diff --git a/agent/canvas.py b/agent/canvas.py index 4b859fbf3..36da7a403 100644 --- a/agent/canvas.py +++ b/agent/canvas.py @@ -13,14 +13,21 @@ # See the License for the specific language governing permissions and # limitations under the License. # -import logging +import base64 import json +import logging +import time +from concurrent.futures import ThreadPoolExecutor from copy import deepcopy from functools import partial -import pandas as pd +from typing import Any, Union, Tuple from agent.component import component_class from agent.component.base import ComponentBase +from api.db.services.file_service import FileService +from api.utils import get_uuid, hash_str2int +from rag.prompts.prompts import chunks_format +from rag.utils.redis_conn import REDIS_CONN class Canvas: @@ -35,14 +42,6 @@ class Canvas: "downstream": ["answer_0"], "upstream": [], }, - "answer_0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["retrieval_0"], - "upstream": ["begin", "generate_0"], - }, "retrieval_0": { "obj": { "component_name": "Retrieval", @@ -61,19 +60,28 @@ class Canvas: } }, "history": [], - "messages": [], - "reference": [], - "path": [["begin"]], - "answer": [] + "path": ["begin"], + "retrieval": {"chunks": [], "doc_aggs": []}, + "globals": { + "sys.query": "", + "sys.user_id": tenant_id, + "sys.conversation_turns": 0, + "sys.files": [] + } } """ - def __init__(self, dsl: str, tenant_id=None): + def __init__(self, dsl: str, tenant_id=None, task_id=None): self.path = [] self.history = [] - self.messages = [] - self.answer = [] self.components = {} + self.error = "" + self.globals = { + "sys.query": "", + "sys.user_id": tenant_id, + "sys.conversation_turns": 0, + "sys.files": [] + } self.dsl = json.loads(dsl) if dsl else { "components": { "begin": { @@ -89,13 +97,17 @@ class Canvas: } }, "history": [], - "messages": [], - "reference": [], "path": [], - "answer": [] + "retrieval": [], + "globals": { + "sys.query": "", + "sys.user_id": "", + "sys.conversation_turns": 0, + "sys.files": [] + } } self._tenant_id = tenant_id - self._embed_id = "" + self.task_id = task_id if task_id else get_uuid() self.load() def load(self): @@ -105,33 +117,31 @@ class Canvas: cpn_nms.add(cpn["obj"]["component_name"]) assert "Begin" in cpn_nms, "There have to be an 'Begin' component." - assert "Answer" in cpn_nms, "There have to be an 'Answer' component." for k, cpn in self.components.items(): cpn_nms.add(cpn["obj"]["component_name"]) param = component_class(cpn["obj"]["component_name"] + "Param")() param.update(cpn["obj"]["params"]) - param.check() + try: + param.check() + except Exception as e: + raise ValueError(self.get_component_name(k) + f": {e}") + cpn["obj"] = component_class(cpn["obj"]["component_name"])(self, k, param) - if cpn["obj"].component_name == "Categorize": - for _, desc in param.category_description.items(): - if desc["to"] not in cpn["downstream"]: - cpn["downstream"].append(desc["to"]) self.path = self.dsl["path"] self.history = self.dsl["history"] - self.messages = self.dsl["messages"] - self.answer = self.dsl["answer"] - self.reference = self.dsl["reference"] - self._embed_id = self.dsl.get("embed_id", "") + self.globals = self.dsl["globals"] + self.retrieval = self.dsl["retrieval"] + self.memory = self.dsl.get("memory", []) def __str__(self): self.dsl["path"] = self.path self.dsl["history"] = self.history - self.dsl["messages"] = self.messages - self.dsl["answer"] = self.answer - self.dsl["reference"] = self.reference - self.dsl["embed_id"] = self._embed_id + self.dsl["globals"] = self.globals + self.dsl["task_id"] = self.task_id + self.dsl["retrieval"] = self.retrieval + self.dsl["memory"] = self.memory dsl = { "components": {} } @@ -150,161 +160,245 @@ class Canvas: dsl["components"][k][c] = deepcopy(cpn[c]) return json.dumps(dsl, ensure_ascii=False) - def reset(self): + def reset(self, mem=False): self.path = [] - self.history = [] - self.messages = [] - self.answer = [] - self.reference = [] + if not mem: + self.history = [] + self.retrieval = [] + self.memory = [] for k, cpn in self.components.items(): self.components[k]["obj"].reset() - self._embed_id = "" + + for k in self.globals.keys(): + if isinstance(self.globals[k], str): + self.globals[k] = "" + elif isinstance(self.globals[k], int): + self.globals[k] = 0 + elif isinstance(self.globals[k], float): + self.globals[k] = 0 + elif isinstance(self.globals[k], list): + self.globals[k] = [] + elif isinstance(self.globals[k], dict): + self.globals[k] = {} + else: + self.globals[k] = None + + try: + REDIS_CONN.delete(f"{self.task_id}-logs") + except Exception as e: + logging.exception(e) def get_component_name(self, cid): - for n in self.dsl["graph"]["nodes"]: + for n in self.dsl.get("graph", {}).get("nodes", []): if cid == n["id"]: return n["data"]["name"] return "" - def run(self, running_hint_text = "is running...🕞", **kwargs): - if not running_hint_text or not isinstance(running_hint_text, str): - running_hint_text = "is running...🕞" - bypass_begin = bool(kwargs.get("bypass_begin", False)) + def run(self, **kwargs): + st = time.perf_counter() + self.message_id = get_uuid() + created_at = int(time.time()) + self.add_user_input(kwargs.get("query")) - if self.answer: - cpn_id = self.answer[0] - self.answer.pop(0) - try: - ans = self.components[cpn_id]["obj"].run(self.history, **kwargs) - except Exception as e: - ans = ComponentBase.be_output(str(e)) - self.path[-1].append(cpn_id) - if kwargs.get("stream"): - for an in ans(): - yield an - else: - yield ans - return - - if not self.path: - self.components["begin"]["obj"].run(self.history, **kwargs) - self.path.append(["begin"]) - if bypass_begin: - cpn = self.get_component("begin") - downstream = cpn["downstream"] - self.path.append(downstream) - - - - self.path.append([]) - - ran = -1 - waiting = [] - without_dependent_checking = [] - - def prepare2run(cpns): - nonlocal ran, ans - for c in cpns: - if self.path[-1] and c == self.path[-1][-1]: - continue - cpn = self.components[c]["obj"] - if cpn.component_name == "Answer": - self.answer.append(c) + for k in kwargs.keys(): + if k in ["query", "user_id", "files"] and kwargs[k]: + if k == "files": + self.globals[f"sys.{k}"] = self.get_files(kwargs[k]) else: - logging.debug(f"Canvas.prepare2run: {c}") - if c not in without_dependent_checking: - cpids = cpn.get_dependent_components() - if any([cc not in self.path[-1] for cc in cpids]): - if c not in waiting: - waiting.append(c) - continue - yield "*'{}'* {}".format(self.get_component_name(c), running_hint_text) + self.globals[f"sys.{k}"] = kwargs[k] + if not self.globals["sys.conversation_turns"] : + self.globals["sys.conversation_turns"] = 0 + self.globals["sys.conversation_turns"] += 1 - if cpn.component_name.lower() == "iteration": - st_cpn = cpn.get_start() - assert st_cpn, "Start component not found for Iteration." - if not st_cpn["obj"].end(): - cpn = st_cpn["obj"] - c = cpn._id + def decorate(event, dt): + nonlocal created_at + return { + "event": event, + #"conversation_id": "f3cc152b-24b0-4258-a1a1-7d5e9fc8a115", + "message_id": self.message_id, + "created_at": created_at, + "task_id": self.task_id, + "data": dt + } - try: - ans = cpn.run(self.history, **kwargs) - except Exception as e: - logging.exception(f"Canvas.run got exception: {e}") - self.path[-1].append(c) - ran += 1 - raise e - self.path[-1].append(c) + if not self.path or self.path[-1].lower().find("userfillup") < 0: + self.path.append("begin") + self.retrieval.append({"chunks": [], "doc_aggs": []}) - ran += 1 + yield decorate("workflow_started", {"inputs": kwargs.get("inputs")}) + self.retrieval.append({"chunks": {}, "doc_aggs": {}}) - downstream = self.components[self.path[-2][-1]]["downstream"] - if not downstream and self.components[self.path[-2][-1]].get("parent_id"): - cid = self.path[-2][-1] - pid = self.components[cid]["parent_id"] - o, _ = self.components[cid]["obj"].output(allow_partial=False) - oo, _ = self.components[pid]["obj"].output(allow_partial=False) - self.components[pid]["obj"].set_output(pd.concat([oo, o], ignore_index=True).dropna()) - downstream = [pid] + def _run_batch(f, t): + with ThreadPoolExecutor(max_workers=5) as executor: + thr = [] + for i in range(f, t): + cpn = self.get_component_obj(self.path[i]) + if cpn.component_name.lower() in ["begin", "userfillup"]: + thr.append(executor.submit(cpn.invoke, inputs=kwargs.get("inputs", {}))) + else: + thr.append(executor.submit(cpn.invoke, **cpn.get_input())) + for t in thr: + t.result() - for m in prepare2run(downstream): - yield {"content": m, "running_status": True} + def _node_finished(cpn_obj): + return decorate("node_finished",{ + "inputs": cpn_obj.get_input_values(), + "outputs": cpn_obj.output(), + "component_id": cpn_obj._id, + "component_name": self.get_component_name(cpn_obj._id), + "component_type": self.get_component_type(cpn_obj._id), + "error": cpn_obj.error(), + "elapsed_time": time.perf_counter() - cpn_obj.output("_created_time"), + "created_at": cpn_obj.output("_created_time"), + }) - while 0 <= ran < len(self.path[-1]): - logging.debug(f"Canvas.run: {ran} {self.path}") - cpn_id = self.path[-1][ran] - cpn = self.get_component(cpn_id) - if not any([cpn["downstream"], cpn.get("parent_id"), waiting]): + def _append_path(cpn_id): + if self.path[-1] == cpn_id: + return + self.path.append(cpn_id) + + def _extend_path(cpn_ids): + for cpn_id in cpn_ids: + _append_path(cpn_id) + + self.error = "" + idx = len(self.path) - 1 + partials = [] + while idx < len(self.path): + to = len(self.path) + for i in range(idx, to): + yield decorate("node_started", { + "inputs": None, "created_at": int(time.time()), + "component_id": self.path[i], + "component_name": self.get_component_name(self.path[i]), + "component_type": self.get_component_type(self.path[i]), + }) + _run_batch(idx, to) + + # post processing of components invocation + for i in range(idx, to): + cpn = self.get_component(self.path[i]) + if cpn["obj"].component_name.lower() == "message": + if isinstance(cpn["obj"].output("content"), partial): + _m = "" + for m in cpn["obj"].output("content")(): + if not m: + continue + if m == "": + yield decorate("message", {"content": "", "start_to_think": True}) + elif m == "": + yield decorate("message", {"content": "", "end_to_think": True}) + else: + yield decorate("message", {"content": m}) + _m += m + cpn["obj"].set_output("content", _m) + else: + yield decorate("message", {"content": cpn["obj"].output("content")}) + yield decorate("message_end", {"reference": self.get_reference()}) + + while partials: + _cpn = self.get_component(partials[0]) + if isinstance(_cpn["obj"].output("content"), partial): + break + yield _node_finished(_cpn["obj"]) + partials.pop(0) + + if cpn["obj"].error(): + ex = cpn["obj"].exception_handler() + if ex and ex["comment"]: + yield decorate("message", {"content": ex["comment"]}) + yield decorate("message_end", {}) + if ex and ex["goto"]: + self.path.append(ex["goto"]) + elif not ex or not ex["default_value"]: + self.error = cpn["obj"].error() + + if cpn["obj"].component_name.lower() != "iteration": + if isinstance(cpn["obj"].output("content"), partial): + if self.error: + cpn["obj"].set_output("content", None) + yield _node_finished(cpn["obj"]) + else: + partials.append(self.path[i]) + else: + yield _node_finished(cpn["obj"]) + + if cpn["obj"].component_name.lower() == "iterationitem" and cpn["obj"].end(): + iter = cpn["obj"].get_parent() + yield _node_finished(iter) + _extend_path(self.get_component(cpn["parent_id"])["downstream"]) + elif cpn["obj"].component_name.lower() in ["categorize", "switch"]: + _extend_path(cpn["obj"].output("_next")) + elif cpn["obj"].component_name.lower() == "iteration": + _append_path(cpn["obj"].get_start()) + elif not cpn["downstream"] and cpn["obj"].get_parent(): + _append_path(cpn["obj"].get_parent().get_start()) + else: + _extend_path(cpn["downstream"]) + + if self.error: + logging.error(f"Runtime Error: {self.error}") break + idx = to - loop = self._find_loop() - if loop: - raise OverflowError(f"Too much loops: {loop}") + if any([self.get_component(c)["obj"].component_name.lower() == "userfillup" for c in self.path[idx:]]): + path = [c for c in self.path[idx:] if self.get_component(c)["obj"].component_name.lower() == "userfillup"] + path.extend([c for c in self.path[idx:] if self.get_component(c)["obj"].component_name.lower() != "userfillup"]) + another_inputs = {} + tips = "" + for c in path: + o = self.get_component(c)["obj"] + if o.component_name.lower() == "userfillup": + another_inputs.update(o.get_input_elements()) + if o.get_param("enable_tips"): + tips = o.get_param("tips") + self.path = path + yield decorate("user_inputs", {"inputs": another_inputs, "tips": tips}) + return - downstream = [] - if cpn["obj"].component_name.lower() in ["switch", "categorize", "relevant"]: - switch_out = cpn["obj"].output()[1].iloc[0, 0] - assert switch_out in self.components, \ - "{}'s output: {} not valid.".format(cpn_id, switch_out) - downstream = [switch_out] - else: - downstream = cpn["downstream"] + self.path = self.path[:idx] + if not self.error: + yield decorate("workflow_finished", + { + "inputs": kwargs.get("inputs"), + "outputs": self.get_component_obj(self.path[-1]).output(), + "elapsed_time": time.perf_counter() - st, + "created_at": st, + }) + self.history.append(("assistant", self.get_component_obj(self.path[-1]).output())) - if not downstream and cpn.get("parent_id"): - pid = cpn["parent_id"] - _, o = cpn["obj"].output(allow_partial=False) - _, oo = self.components[pid]["obj"].output(allow_partial=False) - self.components[pid]["obj"].set_output(pd.concat([oo.dropna(axis=1), o.dropna(axis=1)], ignore_index=True).dropna()) - downstream = [pid] + def get_component(self, cpn_id) -> Union[None, dict[str, Any]]: + return self.components.get(cpn_id) - for m in prepare2run(downstream): - yield {"content": m, "running_status": True} + def get_component_obj(self, cpn_id) -> ComponentBase: + return self.components.get(cpn_id)["obj"] - if ran >= len(self.path[-1]) and waiting: - without_dependent_checking = waiting - waiting = [] - for m in prepare2run(without_dependent_checking): - yield {"content": m, "running_status": True} - without_dependent_checking = [] - ran -= 1 + def get_component_type(self, cpn_id) -> str: + return self.components.get(cpn_id)["obj"].component_name - if self.answer: - cpn_id = self.answer[0] - self.answer.pop(0) - ans = self.components[cpn_id]["obj"].run(self.history, **kwargs) - self.path[-1].append(cpn_id) - if kwargs.get("stream"): - assert isinstance(ans, partial) - for an in ans(): - yield an - else: - yield ans + def get_component_input_form(self, cpn_id) -> dict: + return self.components.get(cpn_id)["obj"].get_input_form() - else: - raise Exception("The dialog flow has no way to interact with you. Please add an 'Interact' component to the end of the flow.") + def is_reff(self, exp: str) -> bool: + exp = exp.strip("{").strip("}") + if exp.find("@") < 0: + return exp in self.globals + arr = exp.split("@") + if len(arr) != 2: + return False + if self.get_component(arr[0]) is None: + return False + return True - def get_component(self, cpn_id): - return self.components[cpn_id] + def get_variable_value(self, exp: str) -> Any: + exp = exp.strip("{").strip("}").strip(" ").strip("{").strip("}") + if exp.find("@") < 0: + return self.globals[exp] + cpn_id, var_nm = exp.split("@") + cpn = self.get_component(cpn_id) + if not cpn: + raise Exception(f"Can't find variable: '{cpn_id}@{var_nm}'") + return cpn["obj"].output(var_nm) def get_tenant_id(self): return self._tenant_id @@ -314,8 +408,8 @@ class Canvas: if window_size <= 0: return convs for role, obj in self.history[window_size * -1:]: - if isinstance(obj, list) and obj and all([isinstance(o, dict) for o in obj]): - convs.append({"role": role, "content": '\n'.join([str(s.get("content", "")) for s in obj])}) + if isinstance(obj, dict): + convs.append({"role": role, "content": obj.get("content", "")}) else: convs.append({"role": role, "content": str(obj)}) return convs @@ -323,12 +417,6 @@ class Canvas: def add_user_input(self, question): self.history.append(("user", question)) - def set_embedding_model(self, embed_id): - self._embed_id = embed_id - - def get_embedding_model(self): - return self._embed_id - def _find_loop(self, max_loops=6): path = self.path[-1][::-1] if len(path) < 2: @@ -363,17 +451,75 @@ class Canvas: return self.components["begin"]["obj"]._param.prologue def set_global_param(self, **kwargs): - for k, v in kwargs.items(): - for q in self.components["begin"]["obj"]._param.query: - if k != q["key"]: - continue - q["value"] = v + self.globals.update(kwargs) def get_preset_param(self): - return self.components["begin"]["obj"]._param.query + return self.components["begin"]["obj"]._param.inputs def get_component_input_elements(self, cpnnm): return self.components[cpnnm]["obj"].get_input_elements() - - def set_component_infor(self, cpn_id, infor): - self.components[cpn_id]["obj"].set_infor(infor) + + def get_files(self, files: Union[None, list[dict]]) -> list[str]: + if not files: + return [] + def image_to_base64(file): + return "data:{};base64,{}".format(file["mime_type"], + base64.b64encode(FileService.get_blob(file["created_by"], file["id"])).decode("utf-8")) + exe = ThreadPoolExecutor(max_workers=5) + threads = [] + for file in files: + if file["mime_type"].find("image") >=0: + threads.append(exe.submit(image_to_base64, file)) + continue + threads.append(exe.submit(FileService.parse, file["name"], FileService.get_blob(file["created_by"], file["id"]), True, file["created_by"])) + return [th.result() for th in threads] + + def tool_use_callback(self, agent_id: str, func_name: str, params: dict, result: Any): + agent_ids = agent_id.split("-->") + agent_name = self.get_component_name(agent_ids[0]) + path = agent_name if len(agent_ids) < 2 else agent_name+"-->"+"-->".join(agent_ids[1:]) + try: + bin = REDIS_CONN.get(f"{self.task_id}-{self.message_id}-logs") + if bin: + obj = json.loads(bin.encode("utf-8")) + if obj[-1]["component_id"] == agent_ids[0]: + obj[-1]["trace"].append({"path": path, "tool_name": func_name, "arguments": params, "result": result}) + else: + obj.append({ + "component_id": agent_ids[0], + "trace": [{"path": path, "tool_name": func_name, "arguments": params, "result": result}] + }) + else: + obj = [{ + "component_id": agent_ids[0], + "trace": [{"path": path, "tool_name": func_name, "arguments": params, "result": result}] + }] + REDIS_CONN.set_obj(f"{self.task_id}-{self.message_id}-logs", obj, 60*10) + except Exception as e: + logging.exception(e) + + def add_refernce(self, chunks: list[object], doc_infos: list[object]): + if not self.retrieval: + self.retrieval = [{"chunks": {}, "doc_aggs": {}}] + + r = self.retrieval[-1] + for ck in chunks_format({"chunks": chunks}): + cid = hash_str2int(ck["id"], 100) + if cid not in r: + r["chunks"][cid] = ck + + for doc in doc_infos: + if doc["doc_name"] not in r: + r["doc_aggs"][doc["doc_name"]] = doc + + def get_reference(self): + if not self.retrieval: + return {"chunks": {}, "doc_aggs": {}} + return self.retrieval[-1] + + def add_memory(self, user:str, assist:str, summ: str): + self.memory.append((user, assist, summ)) + + def get_memory(self) -> list[Tuple]: + return self.memory + diff --git a/agent/component/__init__.py b/agent/component/__init__.py index b4681ac51..45dc5f694 100644 --- a/agent/component/__init__.py +++ b/agent/component/__init__.py @@ -14,123 +14,44 @@ # limitations under the License. # +import os import importlib -from .begin import Begin, BeginParam -from .generate import Generate, GenerateParam -from .retrieval import Retrieval, RetrievalParam -from .answer import Answer, AnswerParam -from .categorize import Categorize, CategorizeParam -from .switch import Switch, SwitchParam -from .relevant import Relevant, RelevantParam -from .message import Message, MessageParam -from .rewrite import RewriteQuestion, RewriteQuestionParam -from .keyword import KeywordExtract, KeywordExtractParam -from .concentrator import Concentrator, ConcentratorParam -from .baidu import Baidu, BaiduParam -from .duckduckgo import DuckDuckGo, DuckDuckGoParam -from .wikipedia import Wikipedia, WikipediaParam -from .pubmed import PubMed, PubMedParam -from .arxiv import ArXiv, ArXivParam -from .google import Google, GoogleParam -from .bing import Bing, BingParam -from .googlescholar import GoogleScholar, GoogleScholarParam -from .deepl import DeepL, DeepLParam -from .github import GitHub, GitHubParam -from .baidufanyi import BaiduFanyi, BaiduFanyiParam -from .qweather import QWeather, QWeatherParam -from .exesql import ExeSQL, ExeSQLParam -from .yahoofinance import YahooFinance, YahooFinanceParam -from .wencai import WenCai, WenCaiParam -from .jin10 import Jin10, Jin10Param -from .tushare import TuShare, TuShareParam -from .akshare import AkShare, AkShareParam -from .crawler import Crawler, CrawlerParam -from .invoke import Invoke, InvokeParam -from .template import Template, TemplateParam -from .email import Email, EmailParam -from .iteration import Iteration, IterationParam -from .iterationitem import IterationItem, IterationItemParam -from .code import Code, CodeParam +import inspect +from types import ModuleType +from typing import Dict, Type +_package_path = os.path.dirname(__file__) +__all_classes: Dict[str, Type] = {} + +def _import_submodules() -> None: + for filename in os.listdir(_package_path): # noqa: F821 + if filename.startswith("__") or not filename.endswith(".py") or filename.startswith("base"): + continue + module_name = filename[:-3] + + try: + module = importlib.import_module(f".{module_name}", package=__name__) + _extract_classes_from_module(module) # noqa: F821 + except ImportError as e: + print(f"Warning: Failed to import module {module_name}: {str(e)}") + +def _extract_classes_from_module(module: ModuleType) -> None: + for name, obj in inspect.getmembers(module): + if (inspect.isclass(obj) and + obj.__module__ == module.__name__ and not name.startswith("_")): + __all_classes[name] = obj + globals()[name] = obj + +_import_submodules() + +__all__ = list(__all_classes.keys()) + ["__all_classes"] + +del _package_path, _import_submodules, _extract_classes_from_module def component_class(class_name): m = importlib.import_module("agent.component") - c = getattr(m, class_name) - return c + try: + return getattr(m, class_name) + except Exception: + return getattr(importlib.import_module("agent.tools"), class_name) - -__all__ = [ - "Begin", - "BeginParam", - "Generate", - "GenerateParam", - "Retrieval", - "RetrievalParam", - "Answer", - "AnswerParam", - "Categorize", - "CategorizeParam", - "Switch", - "SwitchParam", - "Relevant", - "RelevantParam", - "Message", - "MessageParam", - "RewriteQuestion", - "RewriteQuestionParam", - "KeywordExtract", - "KeywordExtractParam", - "Concentrator", - "ConcentratorParam", - "Baidu", - "BaiduParam", - "DuckDuckGo", - "DuckDuckGoParam", - "Wikipedia", - "WikipediaParam", - "PubMed", - "PubMedParam", - "ArXiv", - "ArXivParam", - "Google", - "GoogleParam", - "Bing", - "BingParam", - "GoogleScholar", - "GoogleScholarParam", - "DeepL", - "DeepLParam", - "GitHub", - "GitHubParam", - "BaiduFanyi", - "BaiduFanyiParam", - "QWeather", - "QWeatherParam", - "ExeSQL", - "ExeSQLParam", - "YahooFinance", - "YahooFinanceParam", - "WenCai", - "WenCaiParam", - "Jin10", - "Jin10Param", - "TuShare", - "TuShareParam", - "AkShare", - "AkShareParam", - "Crawler", - "CrawlerParam", - "Invoke", - "InvokeParam", - "Iteration", - "IterationParam", - "IterationItem", - "IterationItemParam", - "Template", - "TemplateParam", - "Email", - "EmailParam", - "Code", - "CodeParam", - "component_class" -] diff --git a/agent/component/agent_with_tools.py b/agent/component/agent_with_tools.py new file mode 100644 index 000000000..119f51206 --- /dev/null +++ b/agent/component/agent_with_tools.py @@ -0,0 +1,332 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import re +from concurrent.futures import ThreadPoolExecutor +from copy import deepcopy +from functools import partial +from typing import Any + +import json_repair + +from agent.component.llm import LLMParam, LLM +from agent.tools.base import LLMToolPluginCallSession, ToolParamBase, ToolBase, ToolMeta +from api.db.services.llm_service import LLMBundle, TenantLLMService +from api.db.services.mcp_server_service import MCPServerService +from api.utils.api_utils import timeout +from rag.prompts import message_fit_in +from rag.prompts.prompts import next_step, COMPLETE_TASK, analyze_task, \ + citation_prompt, reflect, rank_memories, kb_prompt, citation_plus, full_question +from rag.utils.mcp_tool_call_conn import MCPToolCallSession, mcp_tool_metadata_to_openai_tool + + +class AgentParam(LLMParam, ToolParamBase): + """ + Define the Agent component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "agent", + "description": "This is an agent for a specific task.", + "parameters": { + "user_prompt": { + "type": "string", + "description": "This is the order you need to send to the agent.", + "default": "", + "required": True + }, + "reasoning": { + "type": "string", + "description": ( + "Supervisor's reasoning for choosing the this agent. " + "Explain why this agent is being invoked and what is expected of it." + ), + "required": True + }, + "context": { + "type": "string", + "description": ( + "All relevant background information, prior facts, decisions, " + "and state needed by the agent to solve the current query. " + "Should be as detailed and self-contained as possible." + ), + "required": True + }, + } + } + super().__init__() + self.function_name = "agent" + self.tools = [] + self.mcp = [] + self.max_rounds = 5 + self.description = "" + + +class Agent(LLM, ToolBase): + component_name = "Agent" + + def __init__(self, canvas, id, param: LLMParam): + LLM.__init__(self, canvas, id, param) + self.tools = {} + for cpn in self._param.tools: + cpn = self._load_tool_obj(cpn) + self.tools[cpn.get_meta()["function"]["name"]] = cpn + + self.chat_mdl = LLMBundle(self._canvas.get_tenant_id(), TenantLLMService.llm_id2llm_type(self._param.llm_id), self._param.llm_id, + max_retries=self._param.max_retries, + retry_interval=self._param.delay_after_error, + max_rounds=self._param.max_rounds, + verbose_tool_use=True + ) + self.tool_meta = [v.get_meta() for _,v in self.tools.items()] + + for mcp in self._param.mcp: + _, mcp_server = MCPServerService.get_by_id(mcp["mcp_id"]) + tool_call_session = MCPToolCallSession(mcp_server, mcp_server.variables) + for tnm, meta in mcp["tools"].items(): + self.tool_meta.append(mcp_tool_metadata_to_openai_tool(meta)) + self.tools[tnm] = tool_call_session + self.callback = partial(self._canvas.tool_use_callback, id) + self.toolcall_session = LLMToolPluginCallSession(self.tools, self.callback) + #self.chat_mdl.bind_tools(self.toolcall_session, self.tool_metas) + + def _load_tool_obj(self, cpn: dict) -> object: + from agent.component import component_class + param = component_class(cpn["component_name"] + "Param")() + param.update(cpn["params"]) + try: + param.check() + except Exception as e: + self.set_output("_ERROR", cpn["component_name"] + f" configuration error: {e}") + raise + cpn_id = f"{self._id}-->" + cpn.get("name", "").replace(" ", "_") + return component_class(cpn["component_name"])(self._canvas, cpn_id, param) + + def get_meta(self) -> dict[str, Any]: + self._param.function_name= self._id.split("-->")[-1] + m = super().get_meta() + if hasattr(self._param, "user_prompt") and self._param.user_prompt: + m["function"]["parameters"]["properties"]["user_prompt"] = self._param.user_prompt + return m + + def get_input_form(self) -> dict[str, dict]: + res = {} + for k, v in self.get_input_elements().items(): + res[k] = { + "type": "line", + "name": v["name"] + } + for cpn in self._param.tools: + if not isinstance(cpn, LLM): + continue + res.update(cpn.get_input_form()) + return res + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 20*60)) + def _invoke(self, **kwargs): + if kwargs.get("user_prompt"): + usr_pmt = "" + if kwargs.get("reasoning"): + usr_pmt += "\nREASONING:\n{}\n".format(kwargs["reasoning"]) + if kwargs.get("context"): + usr_pmt += "\nCONTEXT:\n{}\n".format(kwargs["context"]) + if usr_pmt: + usr_pmt += "\nQUERY:\n{}\n".format(str(kwargs["user_prompt"])) + else: + usr_pmt = str(kwargs["user_prompt"]) + self._param.prompts = [{"role": "user", "content": usr_pmt}] + + if not self.tools: + return LLM._invoke(self, **kwargs) + + prompt, msg = self._prepare_prompt_variables() + + downstreams = self._canvas.get_component(self._id)["downstream"] if self._canvas.get_component(self._id) else [] + if any([self._canvas.get_component_obj(cid).component_name.lower()=="message" for cid in downstreams]) and not self._param.output_structure: + self.set_output("content", partial(self.stream_output_with_tools, prompt, msg)) + return + + _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(self.chat_mdl.max_length * 0.97)) + use_tools = [] + ans = "" + for delta_ans, tk in self._react_with_tools_streamly(msg, use_tools): + ans += delta_ans + + if ans.find("**ERROR**") >= 0: + logging.error(f"Agent._chat got error. response: {ans}") + self.set_output("_ERROR", ans) + return + + self.set_output("content", ans) + if use_tools: + self.set_output("use_tools", use_tools) + return ans + + def stream_output_with_tools(self, prompt, msg): + _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(self.chat_mdl.max_length * 0.97)) + answer_without_toolcall = "" + use_tools = [] + for delta_ans,_ in self._react_with_tools_streamly(msg, use_tools): + answer_without_toolcall += delta_ans + yield delta_ans + + self.set_output("content", answer_without_toolcall) + if use_tools: + self.set_output("use_tools", use_tools) + + def _gen_citations(self, text): + retrievals = self._canvas.get_reference() + retrievals = {"chunks": list(retrievals["chunks"].values()), "doc_aggs": list(retrievals["doc_aggs"].values())} + formated_refer = kb_prompt(retrievals, self.chat_mdl.max_length, True) + for delta_ans in self._generate_streamly([{"role": "system", "content": citation_plus("\n\n".join(formated_refer))}, + {"role": "user", "content": text} + ]): + yield delta_ans + + def _react_with_tools_streamly(self, history: list[dict], use_tools): + token_count = 0 + tool_metas = self.tool_meta + hist = deepcopy(history) + last_calling = "" + if len(hist) > 3: + self.callback("Multi-turn conversation optimization", {}, " running ...") + user_request = full_question(messages=history, chat_mdl=self.chat_mdl) + else: + user_request = history[-1]["content"] + + def use_tool(name, args): + nonlocal hist, use_tools, token_count,last_calling,user_request + print(f"{last_calling=} == {name=}", ) + # Summarize of function calling + #if all([ + # isinstance(self.toolcall_session.get_tool_obj(name), Agent), + # last_calling, + # last_calling != name + #]): + # self.toolcall_session.get_tool_obj(name).add2system_prompt(f"The chat history with other agents are as following: \n" + self.get_useful_memory(user_request, str(args["user_prompt"]))) + last_calling = name + tool_response = self.toolcall_session.tool_call(name, args) + use_tools.append({ + "name": name, + "arguments": args, + "results": tool_response + }) + # self.callback("add_memory", {}, "...") + #self.add_memory(hist[-2]["content"], hist[-1]["content"], name, args, str(tool_response)) + + return name, tool_response + + def complete(): + nonlocal hist + need2cite = self._canvas.get_reference()["chunks"] and self._id.find("-->") < 0 + cited = False + if hist[0]["role"] == "system" and need2cite: + if len(hist) < 7: + hist[0]["content"] += citation_prompt() + cited = True + yield "", token_count + + if not cited and need2cite: + self.callback("gen_citations", {}, " running ...") + + _hist = hist + if len(hist) > 12: + _hist = [hist[0], hist[1], *hist[-10:]] + entire_txt = "" + for delta_ans in self._generate_streamly(_hist): + if not need2cite or cited: + yield delta_ans, 0 + entire_txt += delta_ans + if not need2cite or cited: + return + + for delta_ans in self._gen_citations(entire_txt): + yield delta_ans, 0 + + def append_user_content(hist, content): + if hist[-1]["role"] == "user": + hist[-1]["content"] += content + else: + hist.append({"role": "user", "content": content}) + + self.callback("analyze_task", {}, " running ...") + task_desc = analyze_task(self.chat_mdl, user_request, tool_metas) + for _ in range(self._param.max_rounds + 1): + response, tk = next_step(self.chat_mdl, hist, tool_metas, task_desc) + # self.callback("next_step", {}, str(response)[:256]+"...") + token_count += tk + hist.append({"role": "assistant", "content": response}) + try: + functions = json_repair.loads(re.sub(r"```.*", "", response)) + if not isinstance(functions, list): + raise TypeError(f"List should be returned, but `{functions}`") + for f in functions: + if not isinstance(f, dict): + raise TypeError(f"An object type should be returned, but `{f}`") + with ThreadPoolExecutor(max_workers=5) as executor: + thr = [] + for func in functions: + name = func["name"] + args = func["arguments"] + if name == COMPLETE_TASK: + append_user_content(hist, f"Respond with a formal answer. FORGET(DO NOT mention) about `{COMPLETE_TASK}`. The language for the response MUST be as the same as the first user request.\n") + for txt, tkcnt in complete(): + yield txt, tkcnt + return + + thr.append(executor.submit(use_tool, name, args)) + + reflection = reflect(self.chat_mdl, hist, [th.result() for th in thr]) + append_user_content(hist, reflection) + self.callback("reflection", {}, str(reflection)) + + except Exception as e: + logging.exception(msg=f"Wrong JSON argument format in LLM ReAct response: {e}") + e = f"\nTool call error, please correct the input parameter of response format and call it again.\n *** Exception ***\n{e}" + append_user_content(hist, str(e)) + + logging.warning( f"Exceed max rounds: {self._param.max_rounds}") + final_instruction = f""" +{user_request} +IMPORTANT: You have reached the conversation limit. Based on ALL the information and research you have gathered so far, please provide a DIRECT and COMPREHENSIVE final answer to the original request. +Instructions: +1. SYNTHESIZE all information collected during this conversation +2. Provide a COMPLETE response using existing data - do not suggest additional research +3. Structure your response as a FINAL DELIVERABLE, not a plan +4. If information is incomplete, state what you found and provide the best analysis possible with available data +5. DO NOT mention conversation limits or suggest further steps +6. Focus on delivering VALUE with the information already gathered +Respond immediately with your final comprehensive answer. + """ + append_user_content(hist, final_instruction) + + for txt, tkcnt in complete(): + yield txt, tkcnt + + def get_useful_memory(self, goal: str, sub_goal:str, topn=3) -> str: + # self.callback("get_useful_memory", {"topn": 3}, "...") + mems = self._canvas.get_memory() + rank = rank_memories(self.chat_mdl, goal, sub_goal, [summ for (user, assist, summ) in mems]) + try: + rank = json_repair.loads(re.sub(r"```.*", "", rank))[:topn] + mems = [mems[r] for r in rank] + return "\n\n".join([f"User: {u}\nAgent: {a}" for u, a,_ in mems]) + except Exception as e: + logging.exception(e) + + return "Error occurred." diff --git a/agent/component/answer.py b/agent/component/answer.py deleted file mode 100644 index c8c3439c0..000000000 --- a/agent/component/answer.py +++ /dev/null @@ -1,92 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import random -from abc import ABC -from functools import partial -from typing import Tuple, Union - -import pandas as pd - -from agent.component.base import ComponentBase, ComponentParamBase - - -class AnswerParam(ComponentParamBase): - - """ - Define the Answer component parameters. - """ - def __init__(self): - super().__init__() - self.post_answers = [] - - def check(self): - return True - - -class Answer(ComponentBase, ABC): - component_name = "Answer" - - def _run(self, history, **kwargs): - if kwargs.get("stream"): - return partial(self.stream_output) - - ans = self.get_input() - if self._param.post_answers: - ans = pd.concat([ans, pd.DataFrame([{"content": random.choice(self._param.post_answers)}])], ignore_index=False) - return ans - - def stream_output(self): - res = None - if hasattr(self, "exception") and self.exception: - res = {"content": str(self.exception)} - self.exception = None - yield res - self.set_output(res) - return - - stream = self.get_stream_input() - if isinstance(stream, pd.DataFrame): - res = stream - answer = "" - for ii, row in stream.iterrows(): - answer += row.to_dict()["content"] - yield {"content": answer} - elif stream is not None: - for st in stream(): - res = st - yield st - if self._param.post_answers and res: - res["content"] += random.choice(self._param.post_answers) - yield res - - if res is None: - res = {"content": ""} - - self.set_output(res) - - def set_exception(self, e): - self.exception = e - - def output(self, allow_partial=True) -> Tuple[str, Union[pd.DataFrame, partial]]: - if allow_partial: - return super.output() - - for r, c in self._canvas.history[::-1]: - if r == "user": - return self._param.output_var_name, pd.DataFrame([{"content": c}]) - - self._param.output_var_name, pd.DataFrame([]) - diff --git a/agent/component/arxiv.py b/agent/component/arxiv.py deleted file mode 100644 index a7df3385c..000000000 --- a/agent/component/arxiv.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import arxiv -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase - -class ArXivParam(ComponentParamBase): - """ - Define the ArXiv component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 6 - self.sort_by = 'submittedDate' - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - self.check_valid_value(self.sort_by, "ArXiv Search Sort_by", - ['submittedDate', 'lastUpdatedDate', 'relevance']) - - -class ArXiv(ComponentBase, ABC): - component_name = "ArXiv" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return ArXiv.be_output("") - - try: - sort_choices = {"relevance": arxiv.SortCriterion.Relevance, - "lastUpdatedDate": arxiv.SortCriterion.LastUpdatedDate, - 'submittedDate': arxiv.SortCriterion.SubmittedDate} - arxiv_client = arxiv.Client() - search = arxiv.Search( - query=ans, - max_results=self._param.top_n, - sort_by=sort_choices[self._param.sort_by] - ) - arxiv_res = [ - {"content": 'Title: ' + i.title + '\nPdf_Url: \nSummary: ' + i.summary} for - i in list(arxiv_client.results(search))] - except Exception as e: - return ArXiv.be_output("**ERROR**: " + str(e)) - - if not arxiv_res: - return ArXiv.be_output("") - - df = pd.DataFrame(arxiv_res) - logging.debug(f"df: {str(df)}") - return df diff --git a/agent/component/baidu.py b/agent/component/baidu.py deleted file mode 100644 index b75faa4a0..000000000 --- a/agent/component/baidu.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import pandas as pd -import requests -from bs4 import BeautifulSoup -import re -from agent.component.base import ComponentBase, ComponentParamBase - - -class BaiduParam(ComponentParamBase): - """ - Define the Baidu component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - - -class Baidu(ComponentBase, ABC): - component_name = "Baidu" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return Baidu.be_output("") - - try: - url = 'https://www.baidu.com/s?wd=' + ans + '&rn=' + str(self._param.top_n) - headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', - 'Connection': 'keep-alive', - } - response = requests.get(url=url, headers=headers) - # check if request success - if response.status_code == 200: - soup = BeautifulSoup(response.text, 'html.parser') - url_res = [] - title_res = [] - body_res = [] - for item in soup.select('.result.c-container'): - # extract title - title_res.append(item.select_one('h3 a').get_text(strip=True)) - url_res.append(item.select_one('h3 a')['href']) - body_res.append(item.select_one('.c-abstract').get_text(strip=True) if item.select_one('.c-abstract') else '') - baidu_res = [{"content": re.sub('|', '', '' + title + ' ' + body)} for - url, title, body in zip(url_res, title_res, body_res)] - del body_res, url_res, title_res - except Exception as e: - return Baidu.be_output("**ERROR**: " + str(e)) - - if not baidu_res: - return Baidu.be_output("") - - df = pd.DataFrame(baidu_res) - logging.debug(f"df: {str(df)}") - return df - diff --git a/agent/component/baidufanyi.py b/agent/component/baidufanyi.py deleted file mode 100644 index f6eada605..000000000 --- a/agent/component/baidufanyi.py +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import random -from abc import ABC -import requests -from agent.component.base import ComponentBase, ComponentParamBase -from hashlib import md5 - - -class BaiduFanyiParam(ComponentParamBase): - """ - Define the BaiduFanyi component parameters. - """ - - def __init__(self): - super().__init__() - self.appid = "xxx" - self.secret_key = "xxx" - self.trans_type = 'translate' - self.parameters = [] - self.source_lang = 'auto' - self.target_lang = 'auto' - self.domain = 'finance' - - def check(self): - self.check_empty(self.appid, "BaiduFanyi APPID") - self.check_empty(self.secret_key, "BaiduFanyi Secret Key") - self.check_valid_value(self.trans_type, "Translate type", ['translate', 'fieldtranslate']) - self.check_valid_value(self.source_lang, "Source language", - ['auto', 'zh', 'en', 'yue', 'wyw', 'jp', 'kor', 'fra', 'spa', 'th', 'ara', 'ru', 'pt', - 'de', 'it', 'el', 'nl', 'pl', 'bul', 'est', 'dan', 'fin', 'cs', 'rom', 'slo', 'swe', - 'hu', 'cht', 'vie']) - self.check_valid_value(self.target_lang, "Target language", - ['auto', 'zh', 'en', 'yue', 'wyw', 'jp', 'kor', 'fra', 'spa', 'th', 'ara', 'ru', 'pt', - 'de', 'it', 'el', 'nl', 'pl', 'bul', 'est', 'dan', 'fin', 'cs', 'rom', 'slo', 'swe', - 'hu', 'cht', 'vie']) - self.check_valid_value(self.domain, "Translate field", - ['it', 'finance', 'machinery', 'senimed', 'novel', 'academic', 'aerospace', 'wiki', - 'news', 'law', 'contract']) - - -class BaiduFanyi(ComponentBase, ABC): - component_name = "BaiduFanyi" - - def _run(self, history, **kwargs): - - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return BaiduFanyi.be_output("") - - try: - source_lang = self._param.source_lang - target_lang = self._param.target_lang - appid = self._param.appid - salt = random.randint(32768, 65536) - secret_key = self._param.secret_key - - if self._param.trans_type == 'translate': - sign = md5((appid + ans + salt + secret_key).encode('utf-8')).hexdigest() - url = 'http://api.fanyi.baidu.com/api/trans/vip/translate?' + 'q=' + ans + '&from=' + source_lang + '&to=' + target_lang + '&appid=' + appid + '&salt=' + salt + '&sign=' + sign - headers = {"Content-Type": "application/x-www-form-urlencoded"} - response = requests.post(url=url, headers=headers).json() - - if response.get('error_code'): - BaiduFanyi.be_output("**Error**:" + response['error_msg']) - - return BaiduFanyi.be_output(response['trans_result'][0]['dst']) - elif self._param.trans_type == 'fieldtranslate': - domain = self._param.domain - sign = md5((appid + ans + salt + domain + secret_key).encode('utf-8')).hexdigest() - url = 'http://api.fanyi.baidu.com/api/trans/vip/fieldtranslate?' + 'q=' + ans + '&from=' + source_lang + '&to=' + target_lang + '&appid=' + appid + '&salt=' + salt + '&domain=' + domain + '&sign=' + sign - headers = {"Content-Type": "application/x-www-form-urlencoded"} - response = requests.post(url=url, headers=headers).json() - - if response.get('error_code'): - BaiduFanyi.be_output("**Error**:" + response['error_msg']) - - return BaiduFanyi.be_output(response['trans_result'][0]['dst']) - - except Exception as e: - BaiduFanyi.be_output("**Error**:" + str(e)) - diff --git a/agent/component/base.py b/agent/component/base.py index e35a84e64..c36b747bb 100644 --- a/agent/component/base.py +++ b/agent/component/base.py @@ -13,17 +13,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import re +import time +from abc import ABC import builtins import json -import logging import os -from abc import ABC -from functools import partial -from typing import Any, Tuple, Union - +import logging +from typing import Any, List, Union import pandas as pd - +import trio from agent import settings +from api.utils.api_utils import timeout + _FEEDED_DEPRECATED_PARAMS = "_feeded_deprecated_params" _DEPRECATED_PARAMS = "_deprecated_params" @@ -33,12 +35,17 @@ _IS_RAW_CONF = "_is_raw_conf" class ComponentParamBase(ABC): def __init__(self): - self.output_var_name = "output" - self.infor_var_name = "infor" self.message_history_window_size = 22 - self.query = [] - self.inputs = [] - self.debug_inputs = [] + self.inputs = {} + self.outputs = {} + self.description = "" + self.max_retries = 0 + self.delay_after_error = 2.0 + self.exception_method = None + self.exception_default_value = None + self.exception_comment = None + self.exception_goto = None + self.debug_inputs = {} def set_name(self, name: str): self._name = name @@ -110,11 +117,15 @@ class ComponentParamBase(ABC): update_from_raw_conf = conf.get(_IS_RAW_CONF, True) if update_from_raw_conf: deprecated_params_set = self._get_or_init_deprecated_params_set() - feeded_deprecated_params_set = self._get_or_init_feeded_deprecated_params_set() + feeded_deprecated_params_set = ( + self._get_or_init_feeded_deprecated_params_set() + ) user_feeded_params_set = self._get_or_init_user_feeded_params_set() setattr(self, _IS_RAW_CONF, False) else: - feeded_deprecated_params_set = self._get_or_init_feeded_deprecated_params_set(conf) + feeded_deprecated_params_set = ( + self._get_or_init_feeded_deprecated_params_set(conf) + ) user_feeded_params_set = self._get_or_init_user_feeded_params_set(conf) def _recursive_update_param(param, config, depth, prefix): @@ -150,11 +161,15 @@ class ComponentParamBase(ABC): else: # recursive set obj attr - sub_params = _recursive_update_param(attr, config_value, depth + 1, prefix=f"{prefix}{config_key}.") + sub_params = _recursive_update_param( + attr, config_value, depth + 1, prefix=f"{prefix}{config_key}." + ) setattr(param, config_key, sub_params) if not allow_redundant and redundant_attrs: - raise ValueError(f"cpn `{getattr(self, '_name', type(self))}` has redundant parameters: `{[redundant_attrs]}`") + raise ValueError( + f"cpn `{getattr(self, '_name', type(self))}` has redundant parameters: `{[redundant_attrs]}`" + ) return param @@ -185,7 +200,9 @@ class ComponentParamBase(ABC): param_validation_path_prefix = home_dir + "/param_validation/" param_name = type(self).__name__ - param_validation_path = "/".join([param_validation_path_prefix, param_name + ".json"]) + param_validation_path = "/".join( + [param_validation_path_prefix, param_name + ".json"] + ) validation_json = None @@ -218,7 +235,11 @@ class ComponentParamBase(ABC): break if not value_legal: - raise ValueError("Plase check runtime conf, {} = {} does not match user-parameter restriction".format(variable, value)) + raise ValueError( + "Plase check runtime conf, {} = {} does not match user-parameter restriction".format( + variable, value + ) + ) elif variable in validation_json: self._validate_param(attr, validation_json) @@ -226,63 +247,94 @@ class ComponentParamBase(ABC): @staticmethod def check_string(param, descr): if type(param).__name__ not in ["str"]: - raise ValueError(descr + " {} not supported, should be string type".format(param)) + raise ValueError( + descr + " {} not supported, should be string type".format(param) + ) @staticmethod def check_empty(param, descr): if not param: - raise ValueError(descr + " does not support empty value.") + raise ValueError( + descr + " does not support empty value." + ) @staticmethod def check_positive_integer(param, descr): if type(param).__name__ not in ["int", "long"] or param <= 0: - raise ValueError(descr + " {} not supported, should be positive integer".format(param)) + raise ValueError( + descr + " {} not supported, should be positive integer".format(param) + ) @staticmethod def check_positive_number(param, descr): if type(param).__name__ not in ["float", "int", "long"] or param <= 0: - raise ValueError(descr + " {} not supported, should be positive numeric".format(param)) + raise ValueError( + descr + " {} not supported, should be positive numeric".format(param) + ) @staticmethod def check_nonnegative_number(param, descr): if type(param).__name__ not in ["float", "int", "long"] or param < 0: - raise ValueError(descr + " {} not supported, should be non-negative numeric".format(param)) + raise ValueError( + descr + + " {} not supported, should be non-negative numeric".format(param) + ) @staticmethod def check_decimal_float(param, descr): if type(param).__name__ not in ["float", "int"] or param < 0 or param > 1: - raise ValueError(descr + " {} not supported, should be a float number in range [0, 1]".format(param)) + raise ValueError( + descr + + " {} not supported, should be a float number in range [0, 1]".format( + param + ) + ) @staticmethod def check_boolean(param, descr): if type(param).__name__ != "bool": - raise ValueError(descr + " {} not supported, should be bool type".format(param)) + raise ValueError( + descr + " {} not supported, should be bool type".format(param) + ) @staticmethod def check_open_unit_interval(param, descr): if type(param).__name__ not in ["float"] or param <= 0 or param >= 1: - raise ValueError(descr + " should be a numeric number between 0 and 1 exclusively") + raise ValueError( + descr + " should be a numeric number between 0 and 1 exclusively" + ) @staticmethod def check_valid_value(param, descr, valid_values): if param not in valid_values: - raise ValueError(descr + " {} is not supported, it should be in {}".format(param, valid_values)) + raise ValueError( + descr + + " {} is not supported, it should be in {}".format(param, valid_values) + ) @staticmethod def check_defined_type(param, descr, types): if type(param).__name__ not in types: - raise ValueError(descr + " {} not supported, should be one of {}".format(param, types)) + raise ValueError( + descr + " {} not supported, should be one of {}".format(param, types) + ) @staticmethod def check_and_change_lower(param, valid_list, descr=""): if type(param).__name__ != "str": - raise ValueError(descr + " {} not supported, should be one of {}".format(param, valid_list)) + raise ValueError( + descr + + " {} not supported, should be one of {}".format(param, valid_list) + ) lower_param = param.lower() if lower_param in valid_list: return lower_param else: - raise ValueError(descr + " {} not supported, should be one of {}".format(param, valid_list)) + raise ValueError( + descr + + " {} not supported, should be one of {}".format(param, valid_list) + ) @staticmethod def _greater_equal_than(value, limit): @@ -296,7 +348,11 @@ class ComponentParamBase(ABC): def _range(value, ranges): in_range = False for left_limit, right_limit in ranges: - if left_limit - settings.FLOAT_ZERO <= value <= right_limit + settings.FLOAT_ZERO: + if ( + left_limit - settings.FLOAT_ZERO + <= value + <= right_limit + settings.FLOAT_ZERO + ): in_range = True break @@ -312,17 +368,24 @@ class ComponentParamBase(ABC): def _warn_deprecated_param(self, param_name, descr): if self._deprecated_params_set.get(param_name): - logging.warning(f"{descr} {param_name} is deprecated and ignored in this version.") + logging.warning( + f"{descr} {param_name} is deprecated and ignored in this version." + ) def _warn_to_deprecate_param(self, param_name, descr, new_param): if self._deprecated_params_set.get(param_name): - logging.warning(f"{descr} {param_name} will be deprecated in future release; please use {new_param} instead.") + logging.warning( + f"{descr} {param_name} will be deprecated in future release; " + f"please use {new_param} instead." + ) return True return False class ComponentBase(ABC): component_name: str + thread_limiter = trio.CapacityLimiter(int(os.environ.get('MAX_CONCURRENT_CHATS', 10))) + variable_ref_patt = r"\{* *\{([a-zA-Z:0-9]+@[A-Za-z:0-9_.-]+|sys\.[a-z_]+)\} *\}*" def __str__(self): """ @@ -331,232 +394,144 @@ class ComponentBase(ABC): "params": {} } """ - out = getattr(self._param, self._param.output_var_name) - if isinstance(out, pd.DataFrame) and "chunks" in out: - del out["chunks"] - setattr(self._param, self._param.output_var_name, out) - return """{{ "component_name": "{}", - "params": {}, - "output": {}, - "inputs": {} - }}""".format( - self.component_name, - self._param, - json.dumps(json.loads(str(self._param)).get("output", {}), ensure_ascii=False), - json.dumps(json.loads(str(self._param)).get("inputs", []), ensure_ascii=False), + "params": {} + }}""".format(self.component_name, + self._param ) def __init__(self, canvas, id, param: ComponentParamBase): from agent.canvas import Canvas # Local import to avoid cyclic dependency - assert isinstance(canvas, Canvas), "canvas must be an instance of Canvas" self._canvas = canvas self._id = id self._param = param self._param.check() - def get_dependent_components(self): - cpnts = set( - [ - para["component_id"].split("@")[0] - for para in self._param.query - if para.get("component_id") and para["component_id"].lower().find("answer") < 0 and para["component_id"].lower().find("begin") < 0 - ] - ) - return list(cpnts) - - def run(self, history, **kwargs): - logging.debug("{}, history: {}, kwargs: {}".format(self, json.dumps(history, ensure_ascii=False), json.dumps(kwargs, ensure_ascii=False))) - self._param.debug_inputs = [] + def invoke(self, **kwargs) -> dict[str, Any]: + self.set_output("_created_time", time.perf_counter()) try: - res = self._run(history, **kwargs) - self.set_output(res) + self._invoke(**kwargs) except Exception as e: - self.set_output(pd.DataFrame([{"content": str(e)}])) - raise e + self._param.outputs["_ERROR"] = {"value": str(e)} + logging.exception(e) + self._param.debug_inputs = {} + self.set_output("_elapsed_time", time.perf_counter() - self.output("_created_time")) + return self.output() - return res - - def _run(self, history, **kwargs): + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): raise NotImplementedError() - def output(self, allow_partial=True) -> Tuple[str, Union[pd.DataFrame, partial]]: - o = getattr(self._param, self._param.output_var_name) - if not isinstance(o, partial): - if not isinstance(o, pd.DataFrame): - if isinstance(o, list): - return self._param.output_var_name, pd.DataFrame(o).dropna() - if o is None: - return self._param.output_var_name, pd.DataFrame() - return self._param.output_var_name, pd.DataFrame([{"content": str(o)}]) - return self._param.output_var_name, o + def output(self, var_nm: str=None) -> Union[dict[str, Any], Any]: + if var_nm: + return self._param.outputs.get(var_nm, {}).get("value") + return {k: o.get("value") for k,o in self._param.outputs.items()} - if allow_partial or not isinstance(o, partial): - if not isinstance(o, partial) and not isinstance(o, pd.DataFrame): - return pd.DataFrame(o if isinstance(o, list) else [o]).dropna() - return self._param.output_var_name, o + def set_output(self, key: str, value: Any): + if key not in self._param.outputs: + self._param.outputs[key] = {"value": None, "type": str(type(value))} + self._param.outputs[key]["value"] = value - outs = None - for oo in o(): - if not isinstance(oo, pd.DataFrame): - outs = pd.DataFrame(oo if isinstance(oo, list) else [oo]).dropna() - else: - outs = oo.dropna() - return self._param.output_var_name, outs + def error(self): + return self._param.outputs.get("_ERROR", {}).get("value") def reset(self): - setattr(self._param, self._param.output_var_name, None) - self._param.inputs = [] + for k in self._param.outputs.keys(): + self._param.outputs[k]["value"] = None + for k in self._param.inputs.keys(): + self._param.inputs[k]["value"] = None + self._param.debug_inputs = {} - def set_output(self, v): - setattr(self._param, self._param.output_var_name, v) + def get_input(self, key: str=None) -> Union[Any, dict[str, Any]]: + if key: + return self._param.inputs.get(key, {}).get("value") - def set_infor(self, v): - setattr(self._param, self._param.infor_var_name, v) - - def _fetch_outputs_from(self, sources: list[dict[str, Any]]) -> list[pd.DataFrame]: - outs = [] - for q in sources: - if q.get("component_id"): - if "@" in q["component_id"] and q["component_id"].split("@")[0].lower().find("begin") >= 0: - cpn_id, key = q["component_id"].split("@") - for p in self._canvas.get_component(cpn_id)["obj"]._param.query: - if p["key"] == key: - outs.append(pd.DataFrame([{"content": p.get("value", "")}])) - break - else: - assert False, f"Can't find parameter '{key}' for {cpn_id}" - continue - - if q["component_id"].lower().find("answer") == 0: - txt = [] - for r, c in self._canvas.history[::-1][: self._param.message_history_window_size][::-1]: - txt.append(f"{r.upper()}:{c}") - txt = "\n".join(txt) - outs.append(pd.DataFrame([{"content": txt}])) - continue - - outs.append(self._canvas.get_component(q["component_id"])["obj"].output(allow_partial=False)[1]) - elif q.get("value"): - outs.append(pd.DataFrame([{"content": q["value"]}])) - return outs - def get_input(self): - if self._param.debug_inputs: - return pd.DataFrame([{"content": v["value"]} for v in self._param.debug_inputs if v.get("value")]) - - reversed_cpnts = [] - if len(self._canvas.path) > 1: - reversed_cpnts.extend(self._canvas.path[-2]) - reversed_cpnts.extend(self._canvas.path[-1]) - up_cpns = self.get_upstream() - reversed_up_cpnts = [cpn for cpn in reversed_cpnts if cpn in up_cpns] - - if self._param.query: - self._param.inputs = [] - outs = self._fetch_outputs_from(self._param.query) - - for out in outs: - records = out.to_dict("records") - content: str - - if len(records) > 1: - content = "\n".join([str(d["content"]) for d in records]) - else: - content = records[0]["content"] - - self._param.inputs.append({"component_id": records[0].get("component_id"), "content": content}) - - if outs: - df = pd.concat(outs, ignore_index=True) - if "content" in df: - df = df.drop_duplicates(subset=["content"]).reset_index(drop=True) - return df - - upstream_outs = [] - - for u in reversed_up_cpnts[::-1]: - if self.get_component_name(u) in ["switch", "concentrator"]: + res = {} + for var, o in self.get_input_elements().items(): + v = self.get_param(var) + if v is None: continue - if self.component_name.lower() == "generate" and self.get_component_name(u) == "retrieval": - o = self._canvas.get_component(u)["obj"].output(allow_partial=False)[1] - if o is not None: - o["component_id"] = u - upstream_outs.append(o) - continue - # if self.component_name.lower()!="answer" and u not in self._canvas.get_component(self._id)["upstream"]: continue - if self.component_name.lower().find("switch") < 0 and self.get_component_name(u) in ["relevant", "categorize"]: - continue - if u.lower().find("answer") >= 0: - for r, c in self._canvas.history[::-1]: - if r == "user": - upstream_outs.append(pd.DataFrame([{"content": c, "component_id": u}])) - break - break - if self.component_name.lower().find("answer") >= 0 and self.get_component_name(u) in ["relevant"]: - continue - o = self._canvas.get_component(u)["obj"].output(allow_partial=False)[1] - if o is not None: - o["component_id"] = u - upstream_outs.append(o) - break - - assert upstream_outs, "Can't inference the where the component input is. Please identify whose output is this component's input." - - df = pd.concat(upstream_outs, ignore_index=True) - if "content" in df: - df = df.drop_duplicates(subset=["content"]).reset_index(drop=True) - - self._param.inputs = [] - for _, r in df.iterrows(): - self._param.inputs.append({"component_id": r["component_id"], "content": r["content"]}) - - return df - - def get_input_elements(self): - assert self._param.query, "Please verify the input parameters first." - eles = [] - for q in self._param.query: - if q.get("component_id"): - cpn_id = q["component_id"] - if cpn_id.split("@")[0].lower().find("begin") >= 0: - cpn_id, key = cpn_id.split("@") - eles.extend(self._canvas.get_component(cpn_id)["obj"]._param.query) - continue - - eles.append({"name": self._canvas.get_component_name(cpn_id), "key": cpn_id}) + if isinstance(v, str) and self._canvas.is_reff(v): + self.set_input_value(var, self._canvas.get_variable_value(v)) else: - eles.append({"key": q["value"], "name": q["value"], "value": q["value"]}) - return eles + self.set_input_value(var, v) + res[var] = self.get_input_value(var) + return res - def get_stream_input(self): - reversed_cpnts = [] - if len(self._canvas.path) > 1: - reversed_cpnts.extend(self._canvas.path[-2]) - reversed_cpnts.extend(self._canvas.path[-1]) - up_cpns = self.get_upstream() - reversed_up_cpnts = [cpn for cpn in reversed_cpnts if cpn in up_cpns] + def get_input_values(self) -> Union[Any, dict[str, Any]]: + if self._param.debug_inputs: + return self._param.debug_inputs - for u in reversed_up_cpnts[::-1]: - if self.get_component_name(u) in ["switch", "answer"]: - continue - return self._canvas.get_component(u)["obj"].output()[1] + return {var: self.get_input_value(var) for var, o in self.get_input_elements().items()} - @staticmethod - def be_output(v): - return pd.DataFrame([{"content": v}]) + def get_input_elements_from_text(self, txt: str) -> dict[str, dict[str, str]]: + res = {} + for r in re.finditer(self.variable_ref_patt, txt, flags=re.IGNORECASE): + exp = r.group(1) + cpn_id, var_nm = exp.split("@") if exp.find("@")>0 else ("", exp) + res[exp] = { + "name": (self._canvas.get_component_name(cpn_id) +f"@{var_nm}") if cpn_id else exp, + "value": self._canvas.get_variable_value(exp), + "_retrival": self._canvas.get_variable_value(f"{cpn_id}@_references") if cpn_id else None, + "_cpn_id": cpn_id + } + return res - def get_component_name(self, cpn_id): + def get_input_elements(self) -> dict[str, Any]: + return self._param.inputs + + def get_input_form(self) -> dict[str, dict]: + return self._param.get_input_form() + + def set_input_value(self, key: str, value: Any) -> None: + if key not in self._param.inputs: + self._param.inputs[key] = {"value": None} + self._param.inputs[key]["value"] = value + + def get_input_value(self, key: str) -> Any: + if key not in self._param.inputs: + return None + return self._param.inputs[key].get("value") + + def get_component_name(self, cpn_id) -> str: return self._canvas.get_component(cpn_id)["obj"].component_name.lower() - def debug(self, **kwargs): - return self._run([], **kwargs) + def get_param(self, name): + if hasattr(self._param, name): + return getattr(self._param, name) - def get_parent(self): - pid = self._canvas.get_component(self._id)["parent_id"] + def debug(self, **kwargs): + return self._invoke(**kwargs) + + def get_parent(self) -> Union[object, None]: + pid = self._canvas.get_component(self._id).get("parent_id") + if not pid: + return return self._canvas.get_component(pid)["obj"] - def get_upstream(self): - cpn_nms = self._canvas.get_component(self._id)["upstream"] + def get_upstream(self) -> List[str]: + cpn_nms = self._canvas.get_component(self._id)['upstream'] return cpn_nms + + @staticmethod + def string_format(content: str, kv: dict[str, str]) -> str: + for n, v in kv.items(): + content = re.sub( + r"\{%s\}" % re.escape(n), re.escape(v), content + ) + return content + + def exception_handler(self): + if not self._param.exception_method: + return + return { + "goto": self._param.exception_goto, + "comment": self._param.exception_comment, + "default_value": self._param.exception_default_value + } + + def get_exception_default_value(self): + return self._param.exception_default_value + diff --git a/agent/component/begin.py b/agent/component/begin.py index f09cc23a6..34fbbd2d2 100644 --- a/agent/component/begin.py +++ b/agent/component/begin.py @@ -13,37 +13,34 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from functools import partial -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase +from agent.component.fillup import UserFillUpParam, UserFillUp -class BeginParam(ComponentParamBase): +class BeginParam(UserFillUpParam): """ Define the Begin component parameters. """ def __init__(self): super().__init__() + self.mode = "conversational" self.prologue = "Hi! I'm your smart assistant. What can I do for you?" - self.query = [] def check(self): - return True + self.check_valid_value(self.mode, "The 'mode' should be either `conversational` or `task`", ["conversational", "task"]) + + def get_input_form(self) -> dict[str, dict]: + return getattr(self, "inputs") -class Begin(ComponentBase): +class Begin(UserFillUp): component_name = "Begin" - def _run(self, history, **kwargs): - if kwargs.get("stream"): - return partial(self.stream_output) - return pd.DataFrame([{"content": self._param.prologue}]) - - def stream_output(self): - res = {"content": self._param.prologue} - yield res - self.set_output(self.be_output(res)) - - - + def _invoke(self, **kwargs): + for k, v in kwargs.get("inputs", {}).items(): + if isinstance(v, dict) and v.get("type", "").lower().find("file") >=0: + v = self._canvas.get_files([v["value"]]) + else: + v = v.get("value") + self.set_output(k, v) + self.set_input_value(k, v) diff --git a/agent/component/bing.py b/agent/component/bing.py deleted file mode 100644 index 6ec97c196..000000000 --- a/agent/component/bing.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import requests -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase - -class BingParam(ComponentParamBase): - """ - Define the Bing component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - self.channel = "Webpages" - self.api_key = "YOUR_ACCESS_KEY" - self.country = "CN" - self.language = "en" - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - self.check_valid_value(self.channel, "Bing Web Search or Bing News", ["Webpages", "News"]) - self.check_empty(self.api_key, "Bing subscription key") - self.check_valid_value(self.country, "Bing Country", - ['AR', 'AU', 'AT', 'BE', 'BR', 'CA', 'CL', 'DK', 'FI', 'FR', 'DE', 'HK', 'IN', 'ID', - 'IT', 'JP', 'KR', 'MY', 'MX', 'NL', 'NZ', 'NO', 'CN', 'PL', 'PT', 'PH', 'RU', 'SA', - 'ZA', 'ES', 'SE', 'CH', 'TW', 'TR', 'GB', 'US']) - self.check_valid_value(self.language, "Bing Languages", - ['ar', 'eu', 'bn', 'bg', 'ca', 'ns', 'nt', 'hr', 'cs', 'da', 'nl', 'en', 'gb', 'et', - 'fi', 'fr', 'gl', 'de', 'gu', 'he', 'hi', 'hu', 'is', 'it', 'jp', 'kn', 'ko', 'lv', - 'lt', 'ms', 'ml', 'mr', 'nb', 'pl', 'br', 'pt', 'pa', 'ro', 'ru', 'sr', 'sk', 'sl', - 'es', 'sv', 'ta', 'te', 'th', 'tr', 'uk', 'vi']) - - -class Bing(ComponentBase, ABC): - component_name = "Bing" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return Bing.be_output("") - - try: - headers = {"Ocp-Apim-Subscription-Key": self._param.api_key, 'Accept-Language': self._param.language} - params = {"q": ans, "textDecorations": True, "textFormat": "HTML", "cc": self._param.country, - "answerCount": 1, "promote": self._param.channel} - if self._param.channel == "Webpages": - response = requests.get("https://api.bing.microsoft.com/v7.0/search", headers=headers, params=params) - response.raise_for_status() - search_results = response.json() - bing_res = [{"content": '' + i["name"] + ' ' + i["snippet"]} for i in - search_results["webPages"]["value"]] - elif self._param.channel == "News": - response = requests.get("https://api.bing.microsoft.com/v7.0/news/search", headers=headers, - params=params) - response.raise_for_status() - search_results = response.json() - bing_res = [{"content": '' + i["name"] + ' ' + i["description"]} for i - in search_results['news']['value']] - except Exception as e: - return Bing.be_output("**ERROR**: " + str(e)) - - if not bing_res: - return Bing.be_output("") - - df = pd.DataFrame(bing_res) - logging.debug(f"df: {str(df)}") - return df diff --git a/agent/component/categorize.py b/agent/component/categorize.py index 34bd2cdea..4e79c81f2 100644 --- a/agent/component/categorize.py +++ b/agent/component/categorize.py @@ -14,13 +14,18 @@ # limitations under the License. # import logging +import os +import re from abc import ABC + from api.db import LLMType from api.db.services.llm_service import LLMBundle -from agent.component import GenerateParam, Generate +from agent.component import LLMParam, LLM +from api.utils.api_utils import timeout +from rag.llm.chat_model import ERROR_PREFIX -class CategorizeParam(GenerateParam): +class CategorizeParam(LLMParam): """ Define the Categorize component parameters. @@ -28,10 +33,12 @@ class CategorizeParam(GenerateParam): def __init__(self): super().__init__() self.category_description = {} - self.prompt = "" + self.query = "sys.query" + self.message_history_window_size = 1 + self.update_prompt() def check(self): - super().check() + self.check_positive_integer(self.message_history_window_size, "[Categorize] Message window size > 0") self.check_empty(self.category_description, "[Categorize] Category examples") for k, v in self.category_description.items(): if not k: @@ -39,76 +46,90 @@ class CategorizeParam(GenerateParam): if not v.get("to"): raise ValueError(f"[Categorize] 'To' of category {k} can not be empty!") - def get_prompt(self, chat_hist): + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "type": "line", + "name": "Query" + } + } + + def update_prompt(self): cate_lines = [] for c, desc in self.category_description.items(): - for line in desc.get("examples", "").split("\n"): + for line in desc.get("examples", []): if not line: continue - cate_lines.append("USER: {}\nCategory: {}".format(line, c)) + cate_lines.append("USER: \"" + re.sub(r"\n", " ", line, flags=re.DOTALL) + "\" → "+c) + descriptions = [] for c, desc in self.category_description.items(): if desc.get("description"): descriptions.append( - "\nCategory: {}\nDescription: {}".format(c, desc["description"])) + "\n------\nCategory: {}\nDescription: {}".format(c, desc["description"])) - self.prompt = """ -Role: You're a text classifier. -Task: You need to categorize the user’s questions into {} categories, namely: {} + self.sys_prompt = """ +You are an advanced classification system that categorizes user questions into specific types. Analyze the input question and classify it into ONE of the following categories: +{} Here's description of each category: -{} + - {} -You could learn from the following examples: -{} -You could learn from the above examples. - -Requirements: -- Just mention the category names, no need for any additional words. - ----- Real Data ---- -USER: {}\n - """.format( - len(self.category_description.keys()), - "/".join(list(self.category_description.keys())), - "\n".join(descriptions), - "\n\n- ".join(cate_lines), - chat_hist +---- Instructions ---- + - Consider both explicit mentions and implied context + - Prioritize the most specific applicable category + - Return only the category name without explanations + - Use "Other" only when no other category fits + + """.format( + "\n - ".join(list(self.category_description.keys())), + "\n".join(descriptions) ) - return self.prompt + + if cate_lines: + self.sys_prompt += """ +---- Examples ---- +{} +""".format("\n".join(cate_lines)) -class Categorize(Generate, ABC): +class Categorize(LLM, ABC): component_name = "Categorize" - def _run(self, history, **kwargs): - input = self.get_input() - input = " - ".join(input["content"]) if "content" in input else "" + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): + msg = self._canvas.get_history(self._param.message_history_window_size) + if not msg: + msg = [{"role": "user", "content": ""}] + if kwargs.get("sys.query"): + msg[-1]["content"] = kwargs["sys.query"] + self.set_input_value("sys.query", kwargs["sys.query"]) + else: + msg[-1]["content"] = self._canvas.get_variable_value(self._param.query) + self.set_input_value(self._param.query, msg[-1]["content"]) + self._param.update_prompt() chat_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.CHAT, self._param.llm_id) - self._canvas.set_component_infor(self._id, {"prompt":self._param.get_prompt(input),"messages": [{"role": "user", "content": "\nCategory: "}],"conf": self._param.gen_conf()}) - ans = chat_mdl.chat(self._param.get_prompt(input), [{"role": "user", "content": "\nCategory: "}], - self._param.gen_conf()) - logging.debug(f"input: {input}, answer: {str(ans)}") + user_prompt = """ +---- Real Data ---- +{} → +""".format(" | ".join(["{}: \"{}\"".format(c["role"].upper(), re.sub(r"\n", "", c["content"], flags=re.DOTALL)) for c in msg])) + ans = chat_mdl.chat(self._param.sys_prompt, [{"role": "user", "content": user_prompt}], self._param.gen_conf()) + logging.info(f"input: {user_prompt}, answer: {str(ans)}") + if ERROR_PREFIX in ans: + raise Exception(ans) # Count the number of times each category appears in the answer. category_counts = {} for c in self._param.category_description.keys(): count = ans.lower().count(c.lower()) category_counts[c] = count - - # If a category is found, return the category with the highest count. + + cpn_ids = list(self._param.category_description.items())[-1][1]["to"] + max_category = list(self._param.category_description.keys())[0] if any(category_counts.values()): - max_category = max(category_counts.items(), key=lambda x: x[1]) - res = Categorize.be_output(self._param.category_description[max_category[0]]["to"]) - self.set_output(res) - return res + max_category = max(category_counts.items(), key=lambda x: x[1])[0] + cpn_ids = self._param.category_description[max_category]["to"] - res = Categorize.be_output(list(self._param.category_description.items())[-1][1]["to"]) - self.set_output(res) - return res - - def debug(self, **kwargs): - df = self._run([], **kwargs) - cpn_id = df.iloc[0, 0] - return Categorize.be_output(self._canvas.get_component_name(cpn_id)) + self.set_output("category_name", max_category) + self.set_output("_next", cpn_ids) diff --git a/agent/component/code.py b/agent/component/code.py deleted file mode 100644 index 215ffcfe5..000000000 --- a/agent/component/code.py +++ /dev/null @@ -1,152 +0,0 @@ -# -# Copyright 2025 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import base64 -from abc import ABC -from enum import Enum -from typing import Optional - -from pydantic import BaseModel, Field, field_validator - -from agent.component.base import ComponentBase, ComponentParamBase -from api import settings - - -class Language(str, Enum): - PYTHON = "python" - NODEJS = "nodejs" - - -class CodeExecutionRequest(BaseModel): - code_b64: str = Field(..., description="Base64 encoded code string") - language: Language = Field(default=Language.PYTHON, description="Programming language") - arguments: Optional[dict] = Field(default={}, description="Arguments") - - @field_validator("code_b64") - @classmethod - def validate_base64(cls, v: str) -> str: - try: - base64.b64decode(v, validate=True) - return v - except Exception as e: - raise ValueError(f"Invalid base64 encoding: {str(e)}") - - @field_validator("language", mode="before") - @classmethod - def normalize_language(cls, v) -> str: - if isinstance(v, str): - low = v.lower() - if low in ("python", "python3"): - return "python" - elif low in ("javascript", "nodejs"): - return "nodejs" - raise ValueError(f"Unsupported language: {v}") - - -class CodeParam(ComponentParamBase): - """ - Define the code sandbox component parameters. - """ - - def __init__(self): - super().__init__() - self.lang = "python" - self.script = "" - self.arguments = [] - self.address = f"http://{settings.SANDBOX_HOST}:9385/run" - self.enable_network = True - - def check(self): - self.check_valid_value(self.lang, "Support languages", ["python", "python3", "nodejs", "javascript"]) - self.check_defined_type(self.enable_network, "Enable network", ["bool"]) - - -class Code(ComponentBase, ABC): - component_name = "Code" - - def _run(self, history, **kwargs): - arguments = {} - for input in self._param.arguments: - if "@" in input["component_id"]: - component_id = input["component_id"].split("@")[0] - referred_component_key = input["component_id"].split("@")[1] - referred_component = self._canvas.get_component(component_id)["obj"] - - for param in referred_component._param.query: - if param["key"] == referred_component_key: - if "value" in param: - arguments[input["name"]] = param["value"] - else: - referred_component = self._canvas.get_component(input["component_id"])["obj"] - referred_component_name = referred_component.component_name - referred_component_id = referred_component._id - - debug_inputs = self._param.debug_inputs - if debug_inputs: - for param in debug_inputs: - if param["key"] == referred_component_id: - if "value" in param and param["name"] == input["name"]: - arguments[input["name"]] = param["value"] - else: - if referred_component_name.lower() == "answer": - arguments[input["name"]] = self._canvas.get_history(1)[0]["content"] - continue - - _, out = referred_component.output(allow_partial=False) - if not out.empty: - arguments[input["name"]] = "\n".join(out["content"]) - - return self._execute_code( - language=self._param.lang, - code=self._param.script, - arguments=arguments, - address=self._param.address, - enable_network=self._param.enable_network, - ) - - def _execute_code(self, language: str, code: str, arguments: dict, address: str, enable_network: bool): - import requests - - try: - code_b64 = self._encode_code(code) - code_req = CodeExecutionRequest(code_b64=code_b64, language=language, arguments=arguments).model_dump() - except Exception as e: - return Code.be_output("**Error**: construct code request error: " + str(e)) - - try: - resp = requests.post(url=address, json=code_req, timeout=10) - body = resp.json() - if body: - stdout = body.get("stdout") - stderr = body.get("stderr") - return Code.be_output(stdout or stderr) - else: - return Code.be_output("**Error**: There is no response from sanbox") - - except Exception as e: - return Code.be_output("**Error**: Internal error in sanbox: " + str(e)) - - def _encode_code(self, code: str) -> str: - return base64.b64encode(code.encode("utf-8")).decode("utf-8") - - def get_input_elements(self): - elements = [] - for input in self._param.arguments: - cpn_id = input["component_id"] - elements.append({"key": cpn_id, "name": input["name"]}) - return elements - - def debug(self, **kwargs): - return self._run([], **kwargs) diff --git a/agent/component/duckduckgo.py b/agent/component/duckduckgo.py deleted file mode 100644 index 9f460a699..000000000 --- a/agent/component/duckduckgo.py +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -from duckduckgo_search import DDGS -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase - - -class DuckDuckGoParam(ComponentParamBase): - """ - Define the DuckDuckGo component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - self.channel = "text" - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - self.check_valid_value(self.channel, "Web Search or News", ["text", "news"]) - - -class DuckDuckGo(ComponentBase, ABC): - component_name = "DuckDuckGo" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return DuckDuckGo.be_output("") - - try: - if self._param.channel == "text": - with DDGS() as ddgs: - # {'title': '', 'href': '', 'body': ''} - duck_res = [{"content": '' + i["title"] + ' ' + i["body"]} for i - in ddgs.text(ans, max_results=self._param.top_n)] - elif self._param.channel == "news": - with DDGS() as ddgs: - # {'date': '', 'title': '', 'body': '', 'url': '', 'image': '', 'source': ''} - duck_res = [{"content": '' + i["title"] + ' ' + i["body"]} for i - in ddgs.news(ans, max_results=self._param.top_n)] - except Exception as e: - return DuckDuckGo.be_output("**ERROR**: " + str(e)) - - if not duck_res: - return DuckDuckGo.be_output("") - - df = pd.DataFrame(duck_res) - logging.debug("df: {df}") - return df diff --git a/agent/component/email.py b/agent/component/email.py deleted file mode 100644 index 25cdb6a15..000000000 --- a/agent/component/email.py +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from abc import ABC -import json -import smtplib -import logging -from email.mime.text import MIMEText -from email.mime.multipart import MIMEMultipart -from email.header import Header -from email.utils import formataddr -from agent.component.base import ComponentBase, ComponentParamBase - -class EmailParam(ComponentParamBase): - """ - Define the Email component parameters. - """ - def __init__(self): - super().__init__() - # Fixed configuration parameters - self.smtp_server = "" # SMTP server address - self.smtp_port = 465 # SMTP port - self.email = "" # Sender email - self.password = "" # Email authorization code - self.sender_name = "" # Sender name - - def check(self): - # Check required parameters - self.check_empty(self.smtp_server, "SMTP Server") - self.check_empty(self.email, "Email") - self.check_empty(self.password, "Password") - self.check_empty(self.sender_name, "Sender Name") - -class Email(ComponentBase, ABC): - component_name = "Email" - - def _run(self, history, **kwargs): - # Get upstream component output and parse JSON - ans = self.get_input() - content = "".join(ans["content"]) if "content" in ans else "" - if not content: - return Email.be_output("No content to send") - - success = False - try: - # Parse JSON string passed from upstream - email_data = json.loads(content) - - # Validate required fields - if "to_email" not in email_data: - return Email.be_output("Missing required field: to_email") - - # Create email object - msg = MIMEMultipart('alternative') - - # Properly handle sender name encoding - msg['From'] = formataddr((str(Header(self._param.sender_name,'utf-8')), self._param.email)) - msg['To'] = email_data["to_email"] - if "cc_email" in email_data and email_data["cc_email"]: - msg['Cc'] = email_data["cc_email"] - msg['Subject'] = Header(email_data.get("subject", "No Subject"), 'utf-8').encode() - - # Use content from email_data or default content - email_content = email_data.get("content", "No content provided") - # msg.attach(MIMEText(email_content, 'plain', 'utf-8')) - msg.attach(MIMEText(email_content, 'html', 'utf-8')) - - # Connect to SMTP server and send - logging.info(f"Connecting to SMTP server {self._param.smtp_server}:{self._param.smtp_port}") - - context = smtplib.ssl.create_default_context() - with smtplib.SMTP(self._param.smtp_server, self._param.smtp_port) as server: - server.ehlo() - server.starttls(context=context) - server.ehlo() - # Login - logging.info(f"Attempting to login with email: {self._param.email}") - server.login(self._param.email, self._param.password) - - # Get all recipient list - recipients = [email_data["to_email"]] - if "cc_email" in email_data and email_data["cc_email"]: - recipients.extend(email_data["cc_email"].split(',')) - - # Send email - logging.info(f"Sending email to recipients: {recipients}") - try: - server.send_message(msg, self._param.email, recipients) - success = True - except Exception as e: - logging.error(f"Error during send_message: {str(e)}") - # Try alternative method - server.sendmail(self._param.email, recipients, msg.as_string()) - success = True - - try: - server.quit() - except Exception as e: - # Ignore errors when closing connection - logging.warning(f"Non-fatal error during connection close: {str(e)}") - - if success: - return Email.be_output("Email sent successfully") - - except json.JSONDecodeError: - error_msg = "Invalid JSON format in input" - logging.error(error_msg) - return Email.be_output(error_msg) - - except smtplib.SMTPAuthenticationError: - error_msg = "SMTP Authentication failed. Please check your email and authorization code." - logging.error(error_msg) - return Email.be_output(f"Failed to send email: {error_msg}") - - except smtplib.SMTPConnectError: - error_msg = f"Failed to connect to SMTP server {self._param.smtp_server}:{self._param.smtp_port}" - logging.error(error_msg) - return Email.be_output(f"Failed to send email: {error_msg}") - - except smtplib.SMTPException as e: - error_msg = f"SMTP error occurred: {str(e)}" - logging.error(error_msg) - return Email.be_output(f"Failed to send email: {error_msg}") - - except Exception as e: - error_msg = f"Unexpected error: {str(e)}" - logging.error(error_msg) - return Email.be_output(f"Failed to send email: {error_msg}") \ No newline at end of file diff --git a/agent/component/exesql.py b/agent/component/exesql.py deleted file mode 100644 index 6f8eae025..000000000 --- a/agent/component/exesql.py +++ /dev/null @@ -1,155 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from abc import ABC -import re -from copy import deepcopy - -import pandas as pd -import pymysql -import psycopg2 -from agent.component import GenerateParam, Generate -import pyodbc -import logging - - -class ExeSQLParam(GenerateParam): - """ - Define the ExeSQL component parameters. - """ - - def __init__(self): - super().__init__() - self.db_type = "mysql" - self.database = "" - self.username = "" - self.host = "" - self.port = 3306 - self.password = "" - self.loop = 3 - self.top_n = 30 - - def check(self): - super().check() - self.check_valid_value(self.db_type, "Choose DB type", ['mysql', 'postgresql', 'mariadb', 'mssql']) - self.check_empty(self.database, "Database name") - self.check_empty(self.username, "database username") - self.check_empty(self.host, "IP Address") - self.check_positive_integer(self.port, "IP Port") - self.check_empty(self.password, "Database password") - self.check_positive_integer(self.top_n, "Number of records") - if self.database == "rag_flow": - if self.host == "ragflow-mysql": - raise ValueError("For the security reason, it dose not support database named rag_flow.") - if self.password == "infini_rag_flow": - raise ValueError("For the security reason, it dose not support database named rag_flow.") - - -class ExeSQL(Generate, ABC): - component_name = "ExeSQL" - - def _refactor(self, ans): - ans = re.sub(r"^.*", "", ans, flags=re.DOTALL) - match = re.search(r"```sql\s*(.*?)\s*```", ans, re.DOTALL) - if match: - ans = match.group(1) # Query content - return ans - else: - print("no markdown") - ans = re.sub(r'^.*?SELECT ', 'SELECT ', (ans), flags=re.IGNORECASE) - ans = re.sub(r';.*?SELECT ', '; SELECT ', ans, flags=re.IGNORECASE) - ans = re.sub(r';[^;]*$', r';', ans) - if not ans: - raise Exception("SQL statement not found!") - return ans - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = "".join([str(a) for a in ans["content"]]) if "content" in ans else "" - ans = self._refactor(ans) - if self._param.db_type in ["mysql", "mariadb"]: - db = pymysql.connect(db=self._param.database, user=self._param.username, host=self._param.host, - port=self._param.port, password=self._param.password) - elif self._param.db_type == 'postgresql': - db = psycopg2.connect(dbname=self._param.database, user=self._param.username, host=self._param.host, - port=self._param.port, password=self._param.password) - elif self._param.db_type == 'mssql': - conn_str = ( - r'DRIVER={ODBC Driver 17 for SQL Server};' - r'SERVER=' + self._param.host + ',' + str(self._param.port) + ';' - r'DATABASE=' + self._param.database + ';' - r'UID=' + self._param.username + ';' - r'PWD=' + self._param.password - ) - db = pyodbc.connect(conn_str) - try: - cursor = db.cursor() - except Exception as e: - raise Exception("Database Connection Failed! \n" + str(e)) - if not hasattr(self, "_loop"): - setattr(self, "_loop", 0) - self._loop += 1 - input_list = re.split(r';', ans.replace(r"\n", " ")) - sql_res = [] - for i in range(len(input_list)): - single_sql = input_list[i] - single_sql = single_sql.replace('```','') - while self._loop <= self._param.loop: - self._loop += 1 - if not single_sql: - break - try: - cursor.execute(single_sql) - if cursor.rowcount == 0: - sql_res.append({"content": "No record in the database!"}) - break - if self._param.db_type == 'mssql': - single_res = pd.DataFrame.from_records(cursor.fetchmany(self._param.top_n), - columns=[desc[0] for desc in cursor.description]) - else: - single_res = pd.DataFrame([i for i in cursor.fetchmany(self._param.top_n)]) - single_res.columns = [i[0] for i in cursor.description] - sql_res.append({"content": single_res.to_markdown(index=False, floatfmt=".6f")}) - break - except Exception as e: - single_sql = self._regenerate_sql(single_sql, str(e), **kwargs) - single_sql = self._refactor(single_sql) - if self._loop > self._param.loop: - sql_res.append({"content": "Can't query the correct data via SQL statement."}) - db.close() - if not sql_res: - return ExeSQL.be_output("") - return pd.DataFrame(sql_res) - - def _regenerate_sql(self, failed_sql, error_message, **kwargs): - prompt = f''' - ## You are the Repair SQL Statement Helper, please modify the original SQL statement based on the SQL query error report. - ## The original SQL statement is as follows:{failed_sql}. - ## The contents of the SQL query error report is as follows:{error_message}. - ## Answer only the modified SQL statement. Please do not give any explanation, just answer the code. -''' - self._param.prompt = prompt - kwargs_ = deepcopy(kwargs) - kwargs_["stream"] = False - response = Generate._run(self, [], **kwargs_) - try: - regenerated_sql = response.loc[0, "content"] - return regenerated_sql - except Exception as e: - logging.error(f"Failed to regenerate SQL: {e}") - return None - - def debug(self, **kwargs): - return self._run([], **kwargs) diff --git a/agent/component/concentrator.py b/agent/component/fillup.py similarity index 69% rename from agent/component/concentrator.py rename to agent/component/fillup.py index efb9dd840..d39cfa2f6 100644 --- a/agent/component/concentrator.py +++ b/agent/component/fillup.py @@ -13,24 +13,27 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from abc import ABC from agent.component.base import ComponentBase, ComponentParamBase -class ConcentratorParam(ComponentParamBase): - """ - Define the Concentrator component parameters. - """ +class UserFillUpParam(ComponentParamBase): def __init__(self): super().__init__() + self.enable_tips = True + self.tips = "Please fill up the form" - def check(self): + def check(self) -> bool: return True -class Concentrator(ComponentBase, ABC): - component_name = "Concentrator" +class UserFillUp(ComponentBase): + component_name = "UserFillUp" + + def _invoke(self, **kwargs): + for k, v in kwargs.get("inputs", {}).items(): + self.set_output(k, v) + + + - def _run(self, history, **kwargs): - return Concentrator.be_output("") \ No newline at end of file diff --git a/agent/component/generate.py b/agent/component/generate.py deleted file mode 100644 index f0cdb1f15..000000000 --- a/agent/component/generate.py +++ /dev/null @@ -1,276 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -import re -from functools import partial -from typing import Any -import pandas as pd -from api.db import LLMType -from api.db.services.conversation_service import structure_answer -from api.db.services.llm_service import LLMBundle -from api import settings -from agent.component.base import ComponentBase, ComponentParamBase -from plugin import GlobalPluginManager -from plugin.llm_tool_plugin import llm_tool_metadata_to_openai_tool -from rag.llm.chat_model import ToolCallSession -from rag.prompts import message_fit_in - - -class LLMToolPluginCallSession(ToolCallSession): - def tool_call(self, name: str, arguments: dict[str, Any]) -> str: - tool = GlobalPluginManager.get_llm_tool_by_name(name) - - if tool is None: - raise ValueError(f"LLM tool {name} does not exist") - - return tool().invoke(**arguments) - - -class GenerateParam(ComponentParamBase): - """ - Define the Generate component parameters. - """ - - def __init__(self): - super().__init__() - self.llm_id = "" - self.prompt = "" - self.max_tokens = 0 - self.temperature = 0 - self.top_p = 0 - self.presence_penalty = 0 - self.frequency_penalty = 0 - self.cite = True - self.parameters = [] - self.llm_enabled_tools = [] - - def check(self): - self.check_decimal_float(self.temperature, "[Generate] Temperature") - self.check_decimal_float(self.presence_penalty, "[Generate] Presence penalty") - self.check_decimal_float(self.frequency_penalty, "[Generate] Frequency penalty") - self.check_nonnegative_number(self.max_tokens, "[Generate] Max tokens") - self.check_decimal_float(self.top_p, "[Generate] Top P") - self.check_empty(self.llm_id, "[Generate] LLM") - # self.check_defined_type(self.parameters, "Parameters", ["list"]) - - def gen_conf(self): - conf = {} - if self.max_tokens > 0: - conf["max_tokens"] = self.max_tokens - if self.temperature > 0: - conf["temperature"] = self.temperature - if self.top_p > 0: - conf["top_p"] = self.top_p - if self.presence_penalty > 0: - conf["presence_penalty"] = self.presence_penalty - if self.frequency_penalty > 0: - conf["frequency_penalty"] = self.frequency_penalty - return conf - - -class Generate(ComponentBase): - component_name = "Generate" - - def get_dependent_components(self): - inputs = self.get_input_elements() - cpnts = set([i["key"] for i in inputs[1:] if i["key"].lower().find("answer") < 0 and i["key"].lower().find("begin") < 0]) - return list(cpnts) - - def set_cite(self, retrieval_res, answer): - if "empty_response" in retrieval_res.columns: - retrieval_res["empty_response"].fillna("", inplace=True) - chunks = json.loads(retrieval_res["chunks"][0]) - answer, idx = settings.retrievaler.insert_citations(answer, - [ck["content_ltks"] for ck in chunks], - [ck["vector"] for ck in chunks], - LLMBundle(self._canvas.get_tenant_id(), LLMType.EMBEDDING, - self._canvas.get_embedding_model()), tkweight=0.7, - vtweight=0.3) - doc_ids = set([]) - recall_docs = [] - for i in idx: - did = chunks[int(i)]["doc_id"] - if did in doc_ids: - continue - doc_ids.add(did) - recall_docs.append({"doc_id": did, "doc_name": chunks[int(i)]["docnm_kwd"]}) - - for c in chunks: - del c["vector"] - del c["content_ltks"] - - reference = { - "chunks": chunks, - "doc_aggs": recall_docs - } - - if answer.lower().find("invalid key") >= 0 or answer.lower().find("invalid api") >= 0: - answer += " Please set LLM API-Key in 'User Setting -> Model providers -> API-Key'" - res = {"content": answer, "reference": reference} - res = structure_answer(None, res, "", "") - - return res - - def get_input_elements(self): - key_set = set([]) - res = [{"key": "user", "name": "Input your question here:"}] - for r in re.finditer(r"\{([a-z]+[:@][a-z0-9_-]+)\}", self._param.prompt, flags=re.IGNORECASE): - cpn_id = r.group(1) - if cpn_id in key_set: - continue - if cpn_id.lower().find("begin@") == 0: - cpn_id, key = cpn_id.split("@") - for p in self._canvas.get_component(cpn_id)["obj"]._param.query: - if p["key"] != key: - continue - res.append({"key": r.group(1), "name": p["name"]}) - key_set.add(r.group(1)) - continue - cpn_nm = self._canvas.get_component_name(cpn_id) - if not cpn_nm: - continue - res.append({"key": cpn_id, "name": cpn_nm}) - key_set.add(cpn_id) - return res - - def _run(self, history, **kwargs): - chat_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.CHAT, self._param.llm_id) - - if len(self._param.llm_enabled_tools) > 0: - tools = GlobalPluginManager.get_llm_tools_by_names(self._param.llm_enabled_tools) - - chat_mdl.bind_tools( - LLMToolPluginCallSession(), - [llm_tool_metadata_to_openai_tool(t.get_metadata()) for t in tools] - ) - - prompt = self._param.prompt - - retrieval_res = [] - self._param.inputs = [] - for para in self.get_input_elements()[1:]: - if para["key"].lower().find("begin@") == 0: - cpn_id, key = para["key"].split("@") - for p in self._canvas.get_component(cpn_id)["obj"]._param.query: - if p["key"] == key: - kwargs[para["key"]] = p.get("value", "") - self._param.inputs.append( - {"component_id": para["key"], "content": kwargs[para["key"]]}) - break - else: - assert False, f"Can't find parameter '{key}' for {cpn_id}" - continue - - component_id = para["key"] - cpn = self._canvas.get_component(component_id)["obj"] - if cpn.component_name.lower() == "answer": - hist = self._canvas.get_history(1) - if hist: - hist = hist[0]["content"] - else: - hist = "" - kwargs[para["key"]] = hist - continue - _, out = cpn.output(allow_partial=False) - if "content" not in out.columns: - kwargs[para["key"]] = "" - else: - if cpn.component_name.lower() == "retrieval": - retrieval_res.append(out) - kwargs[para["key"]] = " - " + "\n - ".join([o if isinstance(o, str) else str(o) for o in out["content"]]) - self._param.inputs.append({"component_id": para["key"], "content": kwargs[para["key"]]}) - - if retrieval_res: - retrieval_res = pd.concat(retrieval_res, ignore_index=True) - else: - retrieval_res = pd.DataFrame([]) - - for n, v in kwargs.items(): - prompt = re.sub(r"\{%s\}" % re.escape(n), str(v).replace("\\", " "), prompt) - - if not self._param.inputs and prompt.find("{input}") >= 0: - retrieval_res = self.get_input() - input = (" - " + "\n - ".join( - [c for c in retrieval_res["content"] if isinstance(c, str)])) if "content" in retrieval_res else "" - prompt = re.sub(r"\{input\}", re.escape(input), prompt) - - downstreams = self._canvas.get_component(self._id)["downstream"] - if kwargs.get("stream") and len(downstreams) == 1 and self._canvas.get_component(downstreams[0])[ - "obj"].component_name.lower() == "answer": - return partial(self.stream_output, chat_mdl, prompt, retrieval_res) - - if "empty_response" in retrieval_res.columns and not "".join(retrieval_res["content"]): - empty_res = "\n- ".join([str(t) for t in retrieval_res["empty_response"] if str(t)]) - res = {"content": empty_res if empty_res else "Nothing found in knowledgebase!", "reference": []} - return pd.DataFrame([res]) - - msg = self._canvas.get_history(self._param.message_history_window_size) - if len(msg) < 1: - msg.append({"role": "user", "content": "Output: "}) - _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(chat_mdl.max_length * 0.97)) - if len(msg) < 2: - msg.append({"role": "user", "content": "Output: "}) - ans = chat_mdl.chat(msg[0]["content"], msg[1:], self._param.gen_conf()) - ans = re.sub(r"^.*", "", ans, flags=re.DOTALL) - self._canvas.set_component_infor(self._id, {"prompt":msg[0]["content"],"messages": msg[1:],"conf": self._param.gen_conf()}) - if self._param.cite and "chunks" in retrieval_res.columns: - res = self.set_cite(retrieval_res, ans) - return pd.DataFrame([res]) - - return Generate.be_output(ans) - - def stream_output(self, chat_mdl, prompt, retrieval_res): - res = None - if "empty_response" in retrieval_res.columns and not "".join(retrieval_res["content"]): - empty_res = "\n- ".join([str(t) for t in retrieval_res["empty_response"] if str(t)]) - res = {"content": empty_res if empty_res else "Nothing found in knowledgebase!", "reference": []} - yield res - self.set_output(res) - return - - msg = self._canvas.get_history(self._param.message_history_window_size) - if msg and msg[0]['role'] == 'assistant': - msg.pop(0) - if len(msg) < 1: - msg.append({"role": "user", "content": "Output: "}) - _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(chat_mdl.max_length * 0.97)) - if len(msg) < 2: - msg.append({"role": "user", "content": "Output: "}) - answer = "" - for ans in chat_mdl.chat_streamly(msg[0]["content"], msg[1:], self._param.gen_conf()): - res = {"content": ans, "reference": []} - answer = ans - yield res - - if self._param.cite and "chunks" in retrieval_res.columns: - res = self.set_cite(retrieval_res, answer) - yield res - self._canvas.set_component_infor(self._id, {"prompt":msg[0]["content"],"messages": msg[1:],"conf": self._param.gen_conf()}) - self.set_output(Generate.be_output(res)) - - def debug(self, **kwargs): - chat_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.CHAT, self._param.llm_id) - prompt = self._param.prompt - - for para in self._param.debug_inputs: - kwargs[para["key"]] = para.get("value", "") - - for n, v in kwargs.items(): - prompt = re.sub(r"\{%s\}" % re.escape(n), str(v).replace("\\", " "), prompt) - - u = kwargs.get("user") - ans = chat_mdl.chat(prompt, [{"role": "user", "content": u if u else "Output: "}], self._param.gen_conf()) - return pd.DataFrame([ans]) diff --git a/agent/component/github.py b/agent/component/github.py deleted file mode 100644 index 4149da37a..000000000 --- a/agent/component/github.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import pandas as pd -import requests -from agent.component.base import ComponentBase, ComponentParamBase - - -class GitHubParam(ComponentParamBase): - """ - Define the GitHub component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - - -class GitHub(ComponentBase, ABC): - component_name = "GitHub" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return GitHub.be_output("") - - try: - url = 'https://api.github.com/search/repositories?q=' + ans + '&sort=stars&order=desc&per_page=' + str( - self._param.top_n) - headers = {"Content-Type": "application/vnd.github+json", "X-GitHub-Api-Version": '2022-11-28'} - response = requests.get(url=url, headers=headers).json() - - github_res = [{"content": '' + i["name"] + '' + str( - i["description"]) + '\n stars:' + str(i['watchers'])} for i in response['items']] - except Exception as e: - return GitHub.be_output("**ERROR**: " + str(e)) - - if not github_res: - return GitHub.be_output("") - - df = pd.DataFrame(github_res) - logging.debug(f"df: {df}") - return df diff --git a/agent/component/googlescholar.py b/agent/component/googlescholar.py deleted file mode 100644 index 4ad580ff7..000000000 --- a/agent/component/googlescholar.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase -from scholarly import scholarly - - -class GoogleScholarParam(ComponentParamBase): - """ - Define the GoogleScholar component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 6 - self.sort_by = 'relevance' - self.year_low = None - self.year_high = None - self.patents = True - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - self.check_valid_value(self.sort_by, "GoogleScholar Sort_by", ['date', 'relevance']) - self.check_boolean(self.patents, "Whether or not to include patents, defaults to True") - - -class GoogleScholar(ComponentBase, ABC): - component_name = "GoogleScholar" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return GoogleScholar.be_output("") - - scholar_client = scholarly.search_pubs(ans, patents=self._param.patents, year_low=self._param.year_low, - year_high=self._param.year_high, sort_by=self._param.sort_by) - scholar_res = [] - for i in range(self._param.top_n): - try: - pub = next(scholar_client) - scholar_res.append({"content": 'Title: ' + pub['bib']['title'] + '\n_Url: ' + "\n author: " + ",".join(pub['bib']['author']) + '\n Abstract: ' + pub[ - 'bib'].get('abstract', 'no abstract')}) - - except StopIteration or Exception: - logging.exception("GoogleScholar") - break - - if not scholar_res: - return GoogleScholar.be_output("") - - df = pd.DataFrame(scholar_res) - logging.debug(f"df: {df}") - return df diff --git a/agent/component/invoke.py b/agent/component/invoke.py index c2bd58bd4..0a535c9d9 100644 --- a/agent/component/invoke.py +++ b/agent/component/invoke.py @@ -14,9 +14,14 @@ # limitations under the License. # import json +import logging +import os import re +import time from abc import ABC import requests + +from api.utils.api_utils import timeout from deepdoc.parser import HtmlParser from agent.component.base import ComponentBase, ComponentParamBase @@ -48,28 +53,14 @@ class InvokeParam(ComponentParamBase): class Invoke(ComponentBase, ABC): component_name = "Invoke" - def _run(self, history, **kwargs): + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 3)) + def _invoke(self, **kwargs): args = {} for para in self._param.variables: - if para.get("component_id"): - if '@' in para["component_id"]: - component = para["component_id"].split('@')[0] - field = para["component_id"].split('@')[1] - cpn = self._canvas.get_component(component)["obj"] - for param in cpn._param.query: - if param["key"] == field: - if "value" in param: - args[para["key"]] = param["value"] - else: - cpn = self._canvas.get_component(para["component_id"])["obj"] - if cpn.component_name.lower() == "answer": - args[para["key"]] = self._canvas.get_history(1)[0]["content"] - continue - _, out = cpn.output(allow_partial=False) - if not out.empty: - args[para["key"]] = "\n".join(out["content"]) - else: + if para.get("value") is not None: args[para["key"]] = para["value"] + else: + args[para["key"]] = self._canvas.get_variable_value(para["ref"]) url = self._param.url.strip() if url.find("http") != 0: @@ -83,50 +74,66 @@ class Invoke(ComponentBase, ABC): if re.sub(r"https?:?/?/?", "", self._param.proxy): proxies = {"http": self._param.proxy, "https": self._param.proxy} - if method == 'get': - response = requests.get(url=url, - params=args, - headers=headers, - proxies=proxies, - timeout=self._param.timeout) - if self._param.clean_html: - sections = HtmlParser()(None, response.content) - return Invoke.be_output("\n".join(sections)) + last_e = "" + for _ in range(self._param.max_retries+1): + try: + if method == 'get': + response = requests.get(url=url, + params=args, + headers=headers, + proxies=proxies, + timeout=self._param.timeout) + if self._param.clean_html: + sections = HtmlParser()(None, response.content) + self.set_output("result", "\n".join(sections)) + else: + self.set_output("result", response.text) - return Invoke.be_output(response.text) + if method == 'put': + if self._param.datatype.lower() == 'json': + response = requests.put(url=url, + json=args, + headers=headers, + proxies=proxies, + timeout=self._param.timeout) + else: + response = requests.put(url=url, + data=args, + headers=headers, + proxies=proxies, + timeout=self._param.timeout) + if self._param.clean_html: + sections = HtmlParser()(None, response.content) + self.set_output("result", "\n".join(sections)) + else: + self.set_output("result", response.text) - if method == 'put': - if self._param.datatype.lower() == 'json': - response = requests.put(url=url, - json=args, - headers=headers, - proxies=proxies, - timeout=self._param.timeout) - else: - response = requests.put(url=url, - data=args, - headers=headers, - proxies=proxies, - timeout=self._param.timeout) - if self._param.clean_html: - sections = HtmlParser()(None, response.content) - return Invoke.be_output("\n".join(sections)) - return Invoke.be_output(response.text) + if method == 'post': + if self._param.datatype.lower() == 'json': + response = requests.post(url=url, + json=args, + headers=headers, + proxies=proxies, + timeout=self._param.timeout) + else: + response = requests.post(url=url, + data=args, + headers=headers, + proxies=proxies, + timeout=self._param.timeout) + if self._param.clean_html: + self.set_output("result", "\n".join(sections)) + else: + self.set_output("result", response.text) - if method == 'post': - if self._param.datatype.lower() == 'json': - response = requests.post(url=url, - json=args, - headers=headers, - proxies=proxies, - timeout=self._param.timeout) - else: - response = requests.post(url=url, - data=args, - headers=headers, - proxies=proxies, - timeout=self._param.timeout) - if self._param.clean_html: - sections = HtmlParser()(None, response.content) - return Invoke.be_output("\n".join(sections)) - return Invoke.be_output(response.text) + return self.output("result") + except Exception as e: + last_e = e + logging.exception(f"Http request error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"Http request error: {last_e}" + + assert False, self.output() diff --git a/agent/component/iteration.py b/agent/component/iteration.py index 3f554ae81..a65735cc7 100644 --- a/agent/component/iteration.py +++ b/agent/component/iteration.py @@ -24,10 +24,18 @@ class IterationParam(ComponentParamBase): def __init__(self): super().__init__() - self.delimiter = "," + self.items_ref = "" + + def get_input_form(self) -> dict[str, dict]: + return { + "items": { + "type": "json", + "name": "Items" + } + } def check(self): - self.check_empty(self.delimiter, "Delimiter") + return True class Iteration(ComponentBase, ABC): @@ -38,8 +46,13 @@ class Iteration(ComponentBase, ABC): if self._canvas.get_component(cid)["obj"].component_name.lower() != "iterationitem": continue if self._canvas.get_component(cid)["parent_id"] == self._id: - return self._canvas.get_component(cid) + return cid + + def _invoke(self, **kwargs): + arr = self._canvas.get_variable_value(self._param.items_ref) + if not isinstance(arr, list): + self.set_output("_ERROR", self._param.items_ref + " must be an array, but its type is "+str(type(arr))) + + - def _run(self, history, **kwargs): - return self.output(allow_partial=False)[1] diff --git a/agent/component/iterationitem.py b/agent/component/iterationitem.py index cb1a27049..20187e0ef 100644 --- a/agent/component/iterationitem.py +++ b/agent/component/iterationitem.py @@ -14,7 +14,6 @@ # limitations under the License. # from abc import ABC -import pandas as pd from agent.component.base import ComponentBase, ComponentParamBase @@ -33,20 +32,49 @@ class IterationItem(ComponentBase, ABC): super().__init__(canvas, id, param) self._idx = 0 - def _run(self, history, **kwargs): + def _invoke(self, **kwargs): parent = self.get_parent() - ans = parent.get_input() - ans = parent._param.delimiter.join(ans["content"]) if "content" in ans else "" - ans = [a.strip() for a in ans.split(parent._param.delimiter)] - if not ans: + arr = self._canvas.get_variable_value(parent._param.items_ref) + if not isinstance(arr, list): self._idx = -1 - return pd.DataFrame() + raise Exception(parent._param.items_ref + " must be an array, but its type is "+str(type(arr))) - df = pd.DataFrame([{"content": ans[self._idx]}]) - self._idx += 1 - if self._idx >= len(ans): + if self._idx > 0: + self.output_collation() + + if self._idx >= len(arr): self._idx = -1 - return df + return + + self.set_output("item", arr[self._idx]) + self.set_output("index", self._idx) + + self._idx += 1 + + def output_collation(self): + pid = self.get_parent()._id + for cid in self._canvas.components.keys(): + obj = self._canvas.get_component_obj(cid) + p = obj.get_parent() + if not p: + continue + if p._id != pid: + continue + + if p.component_name.lower() in ["categorize", "message", "switch", "userfillup", "interationitem"]: + continue + + for k, o in p._param.outputs.items(): + if "ref" not in o: + continue + _cid, var = o["ref"].split("@") + if _cid != cid: + continue + res = p.output(k) + if not res: + res = [] + res.append(obj.output(var)) + p.set_output(k, res) def end(self): return self._idx == -1 diff --git a/agent/component/keyword.py b/agent/component/keyword.py deleted file mode 100644 index a34a1ad46..000000000 --- a/agent/component/keyword.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -import re -from abc import ABC -from api.db import LLMType -from api.db.services.llm_service import LLMBundle -from agent.component import GenerateParam, Generate - - -class KeywordExtractParam(GenerateParam): - """ - Define the KeywordExtract component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 1 - - def check(self): - super().check() - self.check_positive_integer(self.top_n, "Top N") - - def get_prompt(self): - self.prompt = """ -- Role: You're a question analyzer. -- Requirements: - - Summarize user's question, and give top %s important keyword/phrase. - - Use comma as a delimiter to separate keywords/phrases. -- Answer format: (in language of user's question) - - keyword: -""" % self.top_n - return self.prompt - - -class KeywordExtract(Generate, ABC): - component_name = "KeywordExtract" - - def _run(self, history, **kwargs): - query = self.get_input() - if hasattr(query, "to_dict") and "content" in query: - query = ", ".join(map(str, query["content"].dropna())) - else: - query = str(query) - - - chat_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.CHAT, self._param.llm_id) - self._canvas.set_component_infor(self._id, {"prompt":self._param.get_prompt(),"messages": [{"role": "user", "content": query}],"conf": self._param.gen_conf()}) - - ans = chat_mdl.chat(self._param.get_prompt(), [{"role": "user", "content": query}], - self._param.gen_conf()) - - ans = re.sub(r"^.*", "", ans, flags=re.DOTALL) - ans = re.sub(r".*keyword:", "", ans).strip() - logging.debug(f"ans: {ans}") - return KeywordExtract.be_output(ans) - - def debug(self, **kwargs): - return self._run([], **kwargs) diff --git a/agent/component/llm.py b/agent/component/llm.py new file mode 100644 index 000000000..7418d9006 --- /dev/null +++ b/agent/component/llm.py @@ -0,0 +1,242 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json +import logging +import os +import re +from typing import Any + +import json_repair +from copy import deepcopy +from functools import partial +from api.db.services.llm_service import LLMBundle, TenantLLMService +from agent.component.base import ComponentBase, ComponentParamBase +from api.utils.api_utils import timeout +from rag.prompts import message_fit_in, citation_prompt +from rag.prompts.prompts import tool_call_summary + + +class LLMParam(ComponentParamBase): + """ + Define the LLM component parameters. + """ + + def __init__(self): + super().__init__() + self.llm_id = "" + self.sys_prompt = "" + self.prompts = [{"role": "user", "content": "{sys.query}"}] + self.max_tokens = 0 + self.temperature = 0 + self.top_p = 0 + self.presence_penalty = 0 + self.frequency_penalty = 0 + self.output_structure = None + self.cite = True + self.visual_files_var = None + + def check(self): + self.check_decimal_float(self.temperature, "[Agent] Temperature") + self.check_decimal_float(self.presence_penalty, "[Agent] Presence penalty") + self.check_decimal_float(self.frequency_penalty, "[Agent] Frequency penalty") + self.check_nonnegative_number(self.max_tokens, "[Agent] Max tokens") + self.check_decimal_float(self.top_p, "[Agent] Top P") + self.check_empty(self.llm_id, "[Agent] LLM") + self.check_empty(self.sys_prompt, "[Agent] System prompt") + self.check_empty(self.prompts, "[Agent] User prompt") + + def gen_conf(self): + conf = {} + if self.max_tokens > 0: + conf["max_tokens"] = self.max_tokens + if self.temperature > 0: + conf["temperature"] = self.temperature + if self.top_p > 0: + conf["top_p"] = self.top_p + if self.presence_penalty > 0: + conf["presence_penalty"] = self.presence_penalty + if self.frequency_penalty > 0: + conf["frequency_penalty"] = self.frequency_penalty + return conf + + +class LLM(ComponentBase): + component_name = "LLM" + + def __init__(self, canvas, id, param: ComponentParamBase): + super().__init__(canvas, id, param) + self.chat_mdl = LLMBundle(self._canvas.get_tenant_id(), TenantLLMService.llm_id2llm_type(self._param.llm_id), + self._param.llm_id, max_retries=self._param.max_retries, + retry_interval=self._param.delay_after_error + ) + self.imgs = [] + + def get_input_form(self) -> dict[str, dict]: + res = {} + for k, v in self.get_input_elements().items(): + res[k] = { + "type": "line", + "name": v["name"] + } + return res + + def get_input_elements(self) -> dict[str, Any]: + res = self.get_input_elements_from_text(self._param.sys_prompt) + for prompt in self._param.prompts: + d = self.get_input_elements_from_text(prompt["content"]) + res.update(d) + return res + + def set_debug_inputs(self, inputs: dict[str, dict]): + self._param.debug_inputs = inputs + + def add2system_prompt(self, txt): + self._param.sys_prompt += txt + + def _prepare_prompt_variables(self): + if self._param.visual_files_var: + self.imgs = self._canvas.get_variable_value(self._param.visual_files_var) + if not self.imgs: + self.imgs = [] + self.imgs = [img for img in self.imgs if img[:len("data:image/")] == "data:image/"] + + args = {} + vars = self.get_input_elements() if not self._param.debug_inputs else self._param.debug_inputs + prompt = self._param.sys_prompt + for k, o in vars.items(): + args[k] = o["value"] + if not isinstance(args[k], str): + try: + args[k] = json.dumps(args[k], ensure_ascii=False) + except Exception: + args[k] = str(args[k]) + self.set_input_value(k, args[k]) + + msg = self._canvas.get_history(self._param.message_history_window_size)[:-1] + msg.extend(deepcopy(self._param.prompts)) + prompt = self.string_format(prompt, args) + for m in msg: + m["content"] = self.string_format(m["content"], args) + if self._canvas.get_reference()["chunks"]: + prompt += citation_prompt() + + return prompt, msg + + def _generate(self, msg:list[dict], **kwargs) -> str: + if not self.imgs: + return self.chat_mdl.chat(msg[0]["content"], msg[1:], self._param.gen_conf(), **kwargs) + return self.chat_mdl.chat(msg[0]["content"], msg[1:], self._param.gen_conf(), images=self.imgs, **kwargs) + + def _generate_streamly(self, msg:list[dict], **kwargs) -> str: + ans = "" + last_idx = 0 + endswith_think = False + def delta(txt): + nonlocal ans, last_idx, endswith_think + delta_ans = txt[last_idx:] + ans = txt + + if delta_ans.find("") == 0: + last_idx += len("") + return "" + elif delta_ans.find("") > 0: + delta_ans = txt[last_idx:last_idx+delta_ans.find("")] + last_idx += delta_ans.find("") + return delta_ans + elif delta_ans.endswith(""): + endswith_think = True + elif endswith_think: + endswith_think = False + return "" + + last_idx = len(ans) + if ans.endswith(""): + last_idx -= len("") + return re.sub(r"(|)", "", delta_ans) + + if not self.imgs: + for txt in self.chat_mdl.chat_streamly(msg[0]["content"], msg[1:], self._param.gen_conf(), **kwargs): + yield delta(txt) + else: + for txt in self.chat_mdl.chat_streamly(msg[0]["content"], msg[1:], self._param.gen_conf(), images=self.imgs, **kwargs): + yield delta(txt) + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): + def clean_formated_answer(ans: str) -> str: + ans = re.sub(r"^.*", "", ans, flags=re.DOTALL) + ans = re.sub(r"^.*```json", "", ans, flags=re.DOTALL) + return re.sub(r"```\n*$", "", ans, flags=re.DOTALL) + + prompt, msg = self._prepare_prompt_variables() + error = "" + + if self._param.output_structure: + prompt += "\nThe output MUST follow this JSON format:\n"+json.dumps(self._param.output_structure, ensure_ascii=False, indent=2) + prompt += "\nRedundant information is FORBIDDEN." + for _ in range(self._param.max_retries+1): + _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(self.chat_mdl.max_length * 0.97)) + error = "" + ans = self._generate(msg) + msg.pop(0) + if ans.find("**ERROR**") >= 0: + logging.error(f"LLM response error: {ans}") + error = ans + continue + try: + self.set_output("structured_content", json_repair.loads(clean_formated_answer(ans))) + return + except Exception: + msg.append({"role": "user", "content": "The answer can't not be parsed as JSON"}) + error = "The answer can't not be parsed as JSON" + if error: + self.set_output("_ERROR", error) + return + + downstreams = self._canvas.get_component(self._id)["downstream"] if self._canvas.get_component(self._id) else [] + if any([self._canvas.get_component_obj(cid).component_name.lower()=="message" for cid in downstreams]) and not self._param.output_structure: + self.set_output("content", partial(self._stream_output, prompt, msg)) + return + + for _ in range(self._param.max_retries+1): + _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(self.chat_mdl.max_length * 0.97)) + error = "" + ans = self._generate(msg) + msg.pop(0) + if ans.find("**ERROR**") >= 0: + logging.error(f"LLM response error: {ans}") + error = ans + continue + self.set_output("content", ans) + break + + if error: + self.set_output("_ERROR", error) + if self.get_exception_default_value(): + self.set_output("content", self.get_exception_default_value()) + + def _stream_output(self, prompt, msg): + _, msg = message_fit_in([{"role": "system", "content": prompt}, *msg], int(self.chat_mdl.max_length * 0.97)) + answer = "" + for ans in self._generate_streamly(msg): + yield ans + answer += ans + self.set_output("content", answer) + + def add_memory(self, user:str, assist:str, func_name: str, params: dict, results: str): + summ = tool_call_summary(self.chat_mdl, func_name, params, results) + logging.info(f"[MEMORY]: {summ}") + self._canvas.add_memory(user, assist, summ) diff --git a/agent/component/message.py b/agent/component/message.py index c60d4d307..e0ab9d578 100644 --- a/agent/component/message.py +++ b/agent/component/message.py @@ -13,43 +13,132 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import json +import os import random -from abc import ABC +import re from functools import partial +from typing import Any + from agent.component.base import ComponentBase, ComponentParamBase +from jinja2 import Template as Jinja2Template + +from api.utils.api_utils import timeout class MessageParam(ComponentParamBase): - """ Define the Message component parameters. """ def __init__(self): super().__init__() - self.messages = [] + self.content = [] + self.stream = True + self.outputs = { + "content": { + "type": "str" + } + } def check(self): - self.check_empty(self.messages, "[Message]") + self.check_empty(self.content, "[Message] Content") + self.check_boolean(self.stream, "[Message] stream") return True -class Message(ComponentBase, ABC): +class Message(ComponentBase): component_name = "Message" - def _run(self, history, **kwargs): - if kwargs.get("stream"): - return partial(self.stream_output) + def get_kwargs(self, script:str, kwargs:dict = {}, delimeter:str=None) -> tuple[str, dict[str, str | list | Any]]: + for k,v in self.get_input_elements_from_text(script).items(): + if k in kwargs: + continue + v = v["value"] + ans = "" + if isinstance(v, partial): + for t in v(): + ans += t + elif isinstance(v, list) and delimeter: + ans = delimeter.join([str(vv) for vv in v]) + elif not isinstance(v, str): + try: + ans = json.dumps(v, ensure_ascii=False) + except Exception: + pass + else: + ans = v + if not ans: + ans = "" + kwargs[k] = ans + self.set_input_value(k, ans) - res = Message.be_output(random.choice(self._param.messages)) - self.set_output(res) - return res + _kwargs = {} + for n, v in kwargs.items(): + _n = re.sub("[@:.]", "_", n) + script = re.sub(r"\{%s\}" % re.escape(n), _n, script) + _kwargs[_n] = v + return script, _kwargs - def stream_output(self): - res = None - if self._param.messages: - res = {"content": random.choice(self._param.messages)} - yield res + def _stream(self, rand_cnt:str): + s = 0 + all_content = "" + cache = {} + for r in re.finditer(self.variable_ref_patt, rand_cnt, flags=re.DOTALL): + all_content += rand_cnt[s: r.start()] + yield rand_cnt[s: r.start()] + s = r.end() + exp = r.group(1) + if exp in cache: + yield cache[exp] + all_content += cache[exp] + continue - self.set_output(res) + v = self._canvas.get_variable_value(exp) + if isinstance(v, partial): + cnt = "" + for t in v(): + all_content += t + cnt += t + yield t + continue + elif not isinstance(v, str): + try: + v = json.dumps(v, ensure_ascii=False, indent=2) + except Exception: + v = str(v) + yield v + all_content += v + cache[exp] = v + + if s < len(rand_cnt): + all_content += rand_cnt[s: ] + yield rand_cnt[s: ] + + self.set_output("content", all_content) + + def _is_jinjia2(self, content:str) -> bool: + patt = [ + r"\{%.*%\}", "{{", "}}" + ] + return any([re.search(p, content) for p in patt]) + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): + rand_cnt = random.choice(self._param.content) + if self._param.stream and not self._is_jinjia2(rand_cnt): + self.set_output("content", partial(self._stream, rand_cnt)) + return + + rand_cnt, kwargs = self.get_kwargs(rand_cnt, kwargs) + template = Jinja2Template(rand_cnt) + try: + content = template.render(kwargs) + except Exception: + pass + + for n, v in kwargs.items(): + content = re.sub(n, v, content) + + self.set_output("content", content) diff --git a/agent/component/pubmed.py b/agent/component/pubmed.py deleted file mode 100644 index 8f41d3c97..000000000 --- a/agent/component/pubmed.py +++ /dev/null @@ -1,69 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -from Bio import Entrez -import re -import pandas as pd -import xml.etree.ElementTree as ET -from agent.component.base import ComponentBase, ComponentParamBase - - -class PubMedParam(ComponentParamBase): - """ - Define the PubMed component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 5 - self.email = "A.N.Other@example.com" - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - - -class PubMed(ComponentBase, ABC): - component_name = "PubMed" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return PubMed.be_output("") - - try: - Entrez.email = self._param.email - pubmedids = Entrez.read(Entrez.esearch(db='pubmed', retmax=self._param.top_n, term=ans))['IdList'] - pubmedcnt = ET.fromstring(re.sub(r'<(/?)b>|<(/?)i>', '', Entrez.efetch(db='pubmed', id=",".join(pubmedids), - retmode="xml").read().decode( - "utf-8"))) - pubmed_res = [{"content": 'Title:' + child.find("MedlineCitation").find("Article").find( - "ArticleTitle").text + '\nUrl:' + '\n' + 'Abstract:' + ( - child.find("MedlineCitation").find("Article").find("Abstract").find( - "AbstractText").text if child.find("MedlineCitation").find( - "Article").find("Abstract") else "No abstract available")} for child in - pubmedcnt.findall("PubmedArticle")] - except Exception as e: - return PubMed.be_output("**ERROR**: " + str(e)) - - if not pubmed_res: - return PubMed.be_output("") - - df = pd.DataFrame(pubmed_res) - logging.debug(f"df: {df}") - return df diff --git a/agent/component/relevant.py b/agent/component/relevant.py deleted file mode 100644 index 201506afa..000000000 --- a/agent/component/relevant.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -from api.db import LLMType -from api.db.services.llm_service import LLMBundle -from agent.component import GenerateParam, Generate -from rag.utils import num_tokens_from_string, encoder - - -class RelevantParam(GenerateParam): - - """ - Define the Relevant component parameters. - """ - def __init__(self): - super().__init__() - self.prompt = "" - self.yes = "" - self.no = "" - - def check(self): - super().check() - self.check_empty(self.yes, "[Relevant] 'Yes'") - self.check_empty(self.no, "[Relevant] 'No'") - - def get_prompt(self): - self.prompt = """ - You are a grader assessing relevance of a retrieved document to a user question. - It does not need to be a stringent test. The goal is to filter out erroneous retrievals. - If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. - Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question. - No other words needed except 'yes' or 'no'. - """ - return self.prompt - - -class Relevant(Generate, ABC): - component_name = "Relevant" - - def _run(self, history, **kwargs): - q = "" - for r, c in self._canvas.history[::-1]: - if r == "user": - q = c - break - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return Relevant.be_output(self._param.no) - ans = "Documents: \n" + ans - ans = f"Question: {q}\n" + ans - chat_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.CHAT, self._param.llm_id) - - if num_tokens_from_string(ans) >= chat_mdl.max_length - 4: - ans = encoder.decode(encoder.encode(ans)[:chat_mdl.max_length - 4]) - - ans = chat_mdl.chat(self._param.get_prompt(), [{"role": "user", "content": ans}], - self._param.gen_conf()) - - logging.debug(ans) - if ans.lower().find("yes") >= 0: - return Relevant.be_output(self._param.yes) - if ans.lower().find("no") >= 0: - return Relevant.be_output(self._param.no) - assert False, f"Relevant component got: {ans}" - - def debug(self, **kwargs): - return self._run([], **kwargs) - diff --git a/agent/component/retrieval.py b/agent/component/retrieval.py deleted file mode 100644 index 218dae969..000000000 --- a/agent/component/retrieval.py +++ /dev/null @@ -1,135 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -import logging -import re -from abc import ABC - -import pandas as pd - -from api.db import LLMType -from api.db.services.knowledgebase_service import KnowledgebaseService -from api.db.services.llm_service import LLMBundle -from api import settings -from agent.component.base import ComponentBase, ComponentParamBase -from rag.app.tag import label_question -from rag.prompts import kb_prompt -from rag.utils.tavily_conn import Tavily - - -class RetrievalParam(ComponentParamBase): - """ - Define the Retrieval component parameters. - """ - - def __init__(self): - super().__init__() - self.similarity_threshold = 0.2 - self.keywords_similarity_weight = 0.5 - self.top_n = 8 - self.top_k = 1024 - self.kb_ids = [] - self.kb_vars = [] - self.rerank_id = "" - self.empty_response = "" - self.tavily_api_key = "" - self.use_kg = False - - def check(self): - self.check_decimal_float(self.similarity_threshold, "[Retrieval] Similarity threshold") - self.check_decimal_float(self.keywords_similarity_weight, "[Retrieval] Keyword similarity weight") - self.check_positive_number(self.top_n, "[Retrieval] Top N") - - -class Retrieval(ComponentBase, ABC): - component_name = "Retrieval" - - def _run(self, history, **kwargs): - query = self.get_input() - query = str(query["content"][0]) if "content" in query else "" - query = re.split(r"(USER:|ASSISTANT:)", query)[-1] - - kb_ids: list[str] = self._param.kb_ids or [] - - kb_vars = self._fetch_outputs_from(self._param.kb_vars) - - if len(kb_vars) > 0: - for kb_var in kb_vars: - if len(kb_var) == 1: - kb_var_value = str(kb_var["content"][0]) - - for v in kb_var_value.split(","): - kb_ids.append(v) - else: - for v in kb_var.to_dict("records"): - kb_ids.append(v["content"]) - - filtered_kb_ids: list[str] = [kb_id for kb_id in kb_ids if kb_id] - - kbs = KnowledgebaseService.get_by_ids(filtered_kb_ids) - if not kbs: - return Retrieval.be_output("") - - embd_nms = list(set([kb.embd_id for kb in kbs])) - assert len(embd_nms) == 1, "Knowledge bases use different embedding models." - - embd_mdl = None - if embd_nms: - embd_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.EMBEDDING, embd_nms[0]) - self._canvas.set_embedding_model(embd_nms[0]) - - rerank_mdl = None - if self._param.rerank_id: - rerank_mdl = LLMBundle(kbs[0].tenant_id, LLMType.RERANK, self._param.rerank_id) - - if kbs: - query = re.sub(r"^user[::\s]*", "", query, flags=re.IGNORECASE) - kbinfos = settings.retrievaler.retrieval( - query, - embd_mdl, - [kb.tenant_id for kb in kbs], - filtered_kb_ids, - 1, - self._param.top_n, - self._param.similarity_threshold, - 1 - self._param.keywords_similarity_weight, - aggs=False, - rerank_mdl=rerank_mdl, - rank_feature=label_question(query, kbs), - ) - else: - kbinfos = {"chunks": [], "doc_aggs": []} - - if self._param.use_kg and kbs: - ck = settings.kg_retrievaler.retrieval(query, [kb.tenant_id for kb in kbs], filtered_kb_ids, embd_mdl, LLMBundle(kbs[0].tenant_id, LLMType.CHAT)) - if ck["content_with_weight"]: - kbinfos["chunks"].insert(0, ck) - - if self._param.tavily_api_key: - tav = Tavily(self._param.tavily_api_key) - tav_res = tav.retrieve_chunks(query) - kbinfos["chunks"].extend(tav_res["chunks"]) - kbinfos["doc_aggs"].extend(tav_res["doc_aggs"]) - - if not kbinfos["chunks"]: - df = Retrieval.be_output("") - if self._param.empty_response and self._param.empty_response.strip(): - df["empty_response"] = self._param.empty_response - return df - - df = pd.DataFrame({"content": kb_prompt(kbinfos, 200000), "chunks": json.dumps(kbinfos["chunks"])}) - logging.debug("{} {}".format(query, df)) - return df.dropna() diff --git a/agent/component/rewrite.py b/agent/component/rewrite.py deleted file mode 100644 index 0ab19d412..000000000 --- a/agent/component/rewrite.py +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from abc import ABC -from agent.component import GenerateParam, Generate -from rag.prompts import full_question - - -class RewriteQuestionParam(GenerateParam): - """ - Define the QuestionRewrite component parameters. - """ - - def __init__(self): - super().__init__() - self.temperature = 0.9 - self.prompt = "" - self.language = "" - - def check(self): - super().check() - - -class RewriteQuestion(Generate, ABC): - component_name = "RewriteQuestion" - - def _run(self, history, **kwargs): - hist = self._canvas.get_history(self._param.message_history_window_size) - query = self.get_input() - query = str(query["content"][0]) if "content" in query else "" - messages = [h for h in hist if h["role"]!="system"] - if messages[-1]["role"] != "user": - messages.append({"role": "user", "content": query}) - ans = full_question(self._canvas.get_tenant_id(), self._param.llm_id, messages, self.gen_lang(self._param.language)) - self._canvas.history.pop() - self._canvas.history.append(("user", ans)) - return RewriteQuestion.be_output(ans) - - @staticmethod - def gen_lang(language): - # convert code lang to language word for the prompt - language_dict = {'af': 'Afrikaans', 'ak': 'Akan', 'sq': 'Albanian', 'ws': 'Samoan', 'am': 'Amharic', - 'ar': 'Arabic', 'hy': 'Armenian', 'az': 'Azerbaijani', 'eu': 'Basque', 'be': 'Belarusian', - 'bem': 'Bemba', 'bn': 'Bengali', 'bh': 'Bihari', - 'xx-bork': 'Bork', 'bs': 'Bosnian', 'br': 'Breton', 'bg': 'Bulgarian', 'bt': 'Bhutani', - 'km': 'Cambodian', 'ca': 'Catalan', 'chr': 'Cherokee', 'ny': 'Chichewa', 'zh-cn': 'Chinese', - 'zh-tw': 'Chinese', 'co': 'Corsican', - 'hr': 'Croatian', 'cs': 'Czech', 'da': 'Danish', 'nl': 'Dutch', 'xx-elmer': 'Elmer', - 'en': 'English', 'eo': 'Esperanto', 'et': 'Estonian', 'ee': 'Ewe', 'fo': 'Faroese', - 'tl': 'Filipino', 'fi': 'Finnish', 'fr': 'French', - 'fy': 'Frisian', 'gaa': 'Ga', 'gl': 'Galician', 'ka': 'Georgian', 'de': 'German', - 'el': 'Greek', 'kl': 'Greenlandic', 'gn': 'Guarani', 'gu': 'Gujarati', 'xx-hacker': 'Hacker', - 'ht': 'Haitian Creole', 'ha': 'Hausa', 'haw': 'Hawaiian', - 'iw': 'Hebrew', 'hi': 'Hindi', 'hu': 'Hungarian', 'is': 'Icelandic', 'ig': 'Igbo', - 'id': 'Indonesian', 'ia': 'Interlingua', 'ga': 'Irish', 'it': 'Italian', 'ja': 'Japanese', - 'jw': 'Javanese', 'kn': 'Kannada', 'kk': 'Kazakh', 'rw': 'Kinyarwanda', - 'rn': 'Kirundi', 'xx-klingon': 'Klingon', 'kg': 'Kongo', 'ko': 'Korean', 'kri': 'Krio', - 'ku': 'Kurdish', 'ckb': 'Kurdish (Sorani)', 'ky': 'Kyrgyz', 'lo': 'Laothian', 'la': 'Latin', - 'lv': 'Latvian', 'ln': 'Lingala', 'lt': 'Lithuanian', - 'loz': 'Lozi', 'lg': 'Luganda', 'ach': 'Luo', 'mk': 'Macedonian', 'mg': 'Malagasy', - 'ms': 'Malay', 'ml': 'Malayalam', 'mt': 'Maltese', 'mv': 'Maldivian', 'mi': 'Maori', - 'mr': 'Marathi', 'mfe': 'Mauritian Creole', 'mo': 'Moldavian', 'mn': 'Mongolian', - 'sr-me': 'Montenegrin', 'my': 'Burmese', 'ne': 'Nepali', 'pcm': 'Nigerian Pidgin', - 'nso': 'Northern Sotho', 'no': 'Norwegian', 'nn': 'Norwegian Nynorsk', 'oc': 'Occitan', - 'or': 'Oriya', 'om': 'Oromo', 'ps': 'Pashto', 'fa': 'Persian', - 'xx-pirate': 'Pirate', 'pl': 'Polish', 'pt': 'Portuguese', 'pt-br': 'Portuguese (Brazilian)', - 'pt-pt': 'Portuguese (Portugal)', 'pa': 'Punjabi', 'qu': 'Quechua', 'ro': 'Romanian', - 'rm': 'Romansh', 'nyn': 'Runyankole', 'ru': 'Russian', 'gd': 'Scots Gaelic', - 'sr': 'Serbian', 'sh': 'Serbo-Croatian', 'st': 'Sesotho', 'tn': 'Setswana', - 'crs': 'Seychellois Creole', 'sn': 'Shona', 'sd': 'Sindhi', 'si': 'Sinhalese', 'sk': 'Slovak', - 'sl': 'Slovenian', 'so': 'Somali', 'es': 'Spanish', 'es-419': 'Spanish (Latin America)', - 'su': 'Sundanese', - 'sw': 'Swahili', 'sv': 'Swedish', 'tg': 'Tajik', 'ta': 'Tamil', 'tt': 'Tatar', 'te': 'Telugu', - 'th': 'Thai', 'ti': 'Tigrinya', 'to': 'Tongan', 'lua': 'Tshiluba', 'tum': 'Tumbuka', - 'tr': 'Turkish', 'tk': 'Turkmen', 'tw': 'Twi', - 'ug': 'Uyghur', 'uk': 'Ukrainian', 'ur': 'Urdu', 'uz': 'Uzbek', 'vu': 'Vanuatu', - 'vi': 'Vietnamese', 'cy': 'Welsh', 'wo': 'Wolof', 'xh': 'Xhosa', 'yi': 'Yiddish', - 'yo': 'Yoruba', 'zu': 'Zulu'} - if language in language_dict: - return language_dict[language] - else: - return "" diff --git a/agent/component/string_transform.py b/agent/component/string_transform.py new file mode 100644 index 000000000..5c445aeb0 --- /dev/null +++ b/agent/component/string_transform.py @@ -0,0 +1,98 @@ +# +# Copyright 2025 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import re +from abc import ABC +from jinja2 import Template as Jinja2Template +from agent.component.base import ComponentParamBase +from api.utils.api_utils import timeout +from .message import Message + + +class StringTransformParam(ComponentParamBase): + """ + Define the code sandbox component parameters. + """ + + def __init__(self): + super().__init__() + self.method = "split" + self.script = "" + self.split_ref = "" + self.delimiters = [","] + self.outputs = {"result": {"value": "", "type": "string"}} + + def check(self): + self.check_valid_value(self.method, "Support method", ["split", "merge"]) + self.check_empty(self.delimiters, "delimiters") + + +class StringTransform(Message, ABC): + component_name = "StringTransform" + + def get_input_form(self) -> dict[str, dict]: + if self._param.method == "split": + return { + "line": { + "name": "String", + "type": "line" + } + } + return {k: { + "name": o["name"], + "type": "line" + } for k, o in self.get_input_elements_from_text(self._param.script).items()} + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): + if self._param.method == "split": + self._split(kwargs.get("line")) + else: + self._merge(kwargs) + + def _split(self, line:str|None = None): + var = self._canvas.get_variable_value(self._param.split_ref) if not line else line + if not var: + var = "" + assert isinstance(var, str), "The input variable is not a string: {}".format(type(var)) + self.set_input_value(self._param.split_ref, var) + res = [] + for i,s in enumerate(re.split(r"(%s)"%("|".join([re.escape(d) for d in self._param.delimiters])), var, flags=re.DOTALL)): + if i % 2 == 1: + continue + res.append(s) + self.set_output("result", res) + + def _merge(self, kwargs:dict[str, str] = {}): + script = self._param.script + script, kwargs = self.get_kwargs(script, kwargs, self._param.delimiters[0]) + + if self._is_jinjia2(script): + template = Jinja2Template(script) + try: + script = template.render(kwargs) + except Exception: + pass + + for k,v in kwargs.items(): + if not v: + v = "" + script = re.sub(k, v, script) + + self.set_output("result", script) + + + diff --git a/agent/component/switch.py b/agent/component/switch.py index d791627d7..c0533a66c 100644 --- a/agent/component/switch.py +++ b/agent/component/switch.py @@ -13,8 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import numbers +import os from abc import ABC +from typing import Any + from agent.component.base import ComponentBase, ComponentParamBase +from api.utils.api_utils import timeout class SwitchParam(ComponentParamBase): @@ -34,7 +39,7 @@ class SwitchParam(ComponentParamBase): } """ self.conditions = [] - self.end_cpn_id = "answer:0" + self.end_cpn_ids = [] self.operators = ['contains', 'not contains', 'start with', 'end with', 'empty', 'not empty', '=', '≠', '>', '<', '≥', '≤'] @@ -43,54 +48,46 @@ class SwitchParam(ComponentParamBase): for cond in self.conditions: if not cond["to"]: raise ValueError("[Switch] 'To' can not be empty!") + self.check_empty(self.end_cpn_ids, "[Switch] the ELSE/Other destination can not be empty.") + def get_input_form(self) -> dict[str, dict]: + return { + "urls": { + "name": "URLs", + "type": "line" + } + } class Switch(ComponentBase, ABC): component_name = "Switch" - def get_dependent_components(self): - res = [] - for cond in self._param.conditions: - for item in cond["items"]: - if not item["cpn_id"]: - continue - if item["cpn_id"].lower().find("begin") >= 0 or item["cpn_id"].lower().find("answer") >= 0: - continue - cid = item["cpn_id"].split("@")[0] - res.append(cid) - - return list(set(res)) - - def _run(self, history, **kwargs): + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 3)) + def _invoke(self, **kwargs): for cond in self._param.conditions: res = [] for item in cond["items"]: if not item["cpn_id"]: continue - cid = item["cpn_id"].split("@")[0] - if item["cpn_id"].find("@") > 0: - cpn_id, key = item["cpn_id"].split("@") - for p in self._canvas.get_component(cid)["obj"]._param.query: - if p["key"] == key: - res.append(self.process_operator(p.get("value",""), item["operator"], item.get("value", ""))) - break - else: - out = self._canvas.get_component(cid)["obj"].output(allow_partial=False)[1] - cpn_input = "" if "content" not in out.columns else " ".join([str(s) for s in out["content"]]) - res.append(self.process_operator(cpn_input, item["operator"], item.get("value", ""))) - + cpn_v = self._canvas.get_variable_value(item["cpn_id"]) + self.set_input_value(item["cpn_id"], cpn_v) + operatee = item.get("value", "") + if isinstance(cpn_v, numbers.Number): + operatee = float(operatee) + res.append(self.process_operator(cpn_v, item["operator"], operatee)) if cond["logical_operator"] != "and" and any(res): - return Switch.be_output(cond["to"]) + self.set_output("next", [self._canvas.get_component_name(cpn_id) for cpn_id in cond["to"]]) + self.set_output("_next", cond["to"]) + return if all(res): - return Switch.be_output(cond["to"]) + self.set_output("next", [self._canvas.get_component_name(cpn_id) for cpn_id in cond["to"]]) + self.set_output("_next", cond["to"]) + return - return Switch.be_output(self._param.end_cpn_id) - - def process_operator(self, input: str, operator: str, value: str) -> bool: - if not isinstance(input, str) or not isinstance(value, str): - raise ValueError('Invalid input or value type: string') + self.set_output("next", [self._canvas.get_component_name(cpn_id) for cpn_id in self._param.end_cpn_ids]) + self.set_output("_next", self._param.end_cpn_ids) + def process_operator(self, input: Any, operator: str, value: Any) -> bool: if operator == "contains": return True if value.lower() in input.lower() else False elif operator == "not contains": diff --git a/agent/component/template.py b/agent/component/template.py deleted file mode 100644 index ab02a111b..000000000 --- a/agent/component/template.py +++ /dev/null @@ -1,147 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import json -import re - -from jinja2 import StrictUndefined -from jinja2.sandbox import SandboxedEnvironment - -from agent.component.base import ComponentBase, ComponentParamBase - - -class TemplateParam(ComponentParamBase): - """ - Define the Generate component parameters. - """ - - def __init__(self): - super().__init__() - self.content = "" - self.parameters = [] - - def check(self): - self.check_empty(self.content, "[Template] Content") - return True - - -class Template(ComponentBase): - component_name = "Template" - - def get_dependent_components(self): - inputs = self.get_input_elements() - cpnts = set([i["key"] for i in inputs if i["key"].lower().find("answer") < 0 and i["key"].lower().find("begin") < 0]) - return list(cpnts) - - def get_input_elements(self): - key_set = set([]) - res = [] - for r in re.finditer(r"\{([a-z]+[:@][a-z0-9_-]+)\}", self._param.content, flags=re.IGNORECASE): - cpn_id = r.group(1) - if cpn_id in key_set: - continue - if cpn_id.lower().find("begin@") == 0: - cpn_id, key = cpn_id.split("@") - for p in self._canvas.get_component(cpn_id)["obj"]._param.query: - if p["key"] != key: - continue - res.append({"key": r.group(1), "name": p["name"]}) - key_set.add(r.group(1)) - continue - cpn_nm = self._canvas.get_component_name(cpn_id) - if not cpn_nm: - continue - res.append({"key": cpn_id, "name": cpn_nm}) - key_set.add(cpn_id) - return res - - def _run(self, history, **kwargs): - content = self._param.content - - self._param.inputs = [] - for para in self.get_input_elements(): - if para["key"].lower().find("begin@") == 0: - cpn_id, key = para["key"].split("@") - for p in self._canvas.get_component(cpn_id)["obj"]._param.query: - if p["key"] == key: - value = p.get("value", "") - self.make_kwargs(para, kwargs, value) - - origin_pattern = "{begin@" + key + "}" - new_pattern = "begin_" + key - content = content.replace(origin_pattern, new_pattern) - kwargs[new_pattern] = kwargs.pop(origin_pattern, "") - break - else: - assert False, f"Can't find parameter '{key}' for {cpn_id}" - continue - - component_id = para["key"] - cpn = self._canvas.get_component(component_id)["obj"] - if cpn.component_name.lower() == "answer": - hist = self._canvas.get_history(1) - if hist: - hist = hist[0]["content"] - else: - hist = "" - self.make_kwargs(para, kwargs, hist) - - if ":" in component_id: - origin_pattern = "{" + component_id + "}" - new_pattern = component_id.replace(":", "_") - content = content.replace(origin_pattern, new_pattern) - kwargs[new_pattern] = kwargs.pop(component_id, "") - continue - - _, out = cpn.output(allow_partial=False) - - result = "" - if "content" in out.columns: - result = "\n".join([o if isinstance(o, str) else str(o) for o in out["content"]]) - - self.make_kwargs(para, kwargs, result) - - env = SandboxedEnvironment( - autoescape=True, - undefined=StrictUndefined, - ) - template = env.from_string(content) - - try: - content = template.render(kwargs) - except Exception: - pass - - for n, v in kwargs.items(): - if not isinstance(v, str): - try: - v = json.dumps(v, ensure_ascii=False) - except Exception: - pass - # Process backslashes in strings, Use Lambda function to avoid escape issues - if isinstance(v, str): - v = v.replace("\\", "\\\\") - content = re.sub(r"\{%s\}" % re.escape(n), lambda match: v, content) - content = re.sub(r"(#+)", r" \1 ", content) - - return Template.be_output(content) - - def make_kwargs(self, para, kwargs, value): - self._param.inputs.append({"component_id": para["key"], "content": value}) - try: - value = json.loads(value) - except Exception: - pass - kwargs[para["key"]] = value diff --git a/agent/component/wencai.py b/agent/component/wencai.py deleted file mode 100644 index 8f8c35181..000000000 --- a/agent/component/wencai.py +++ /dev/null @@ -1,80 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from abc import ABC -import pandas as pd -import pywencai -from agent.component.base import ComponentBase, ComponentParamBase - - -class WenCaiParam(ComponentParamBase): - """ - Define the WenCai component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - self.query_type = "stock" - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - self.check_valid_value(self.query_type, "Query type", - ['stock', 'zhishu', 'fund', 'hkstock', 'usstock', 'threeboard', 'conbond', 'insurance', - 'futures', 'lccp', - 'foreign_exchange']) - - -class WenCai(ComponentBase, ABC): - component_name = "WenCai" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = ",".join(ans["content"]) if "content" in ans else "" - if not ans: - return WenCai.be_output("") - - try: - wencai_res = [] - res = pywencai.get(query=ans, query_type=self._param.query_type, perpage=self._param.top_n) - if isinstance(res, pd.DataFrame): - wencai_res.append({"content": res.to_markdown()}) - if isinstance(res, dict): - for item in res.items(): - if isinstance(item[1], list): - wencai_res.append({"content": item[0] + "\n" + pd.DataFrame(item[1]).to_markdown()}) - continue - if isinstance(item[1], str): - wencai_res.append({"content": item[0] + "\n" + item[1]}) - continue - if isinstance(item[1], dict): - if "meta" in item[1].keys(): - continue - wencai_res.append({"content": pd.DataFrame.from_dict(item[1], orient='index').to_markdown()}) - continue - if isinstance(item[1], pd.DataFrame): - if "image_url" in item[1].columns: - continue - wencai_res.append({"content": item[1].to_markdown()}) - continue - - wencai_res.append({"content": item[0] + "\n" + str(item[1])}) - except Exception as e: - return WenCai.be_output("**ERROR**: " + str(e)) - - if not wencai_res: - return WenCai.be_output("") - - return pd.DataFrame(wencai_res) diff --git a/agent/component/wikipedia.py b/agent/component/wikipedia.py deleted file mode 100644 index 8ccadca21..000000000 --- a/agent/component/wikipedia.py +++ /dev/null @@ -1,67 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import wikipedia -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase - - -class WikipediaParam(ComponentParamBase): - """ - Define the Wikipedia component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - self.language = "en" - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - self.check_valid_value(self.language, "Wikipedia languages", - ['af', 'pl', 'ar', 'ast', 'az', 'bg', 'nan', 'bn', 'be', 'ca', 'cs', 'cy', 'da', 'de', - 'et', 'el', 'en', 'es', 'eo', 'eu', 'fa', 'fr', 'gl', 'ko', 'hy', 'hi', 'hr', 'id', - 'it', 'he', 'ka', 'lld', 'la', 'lv', 'lt', 'hu', 'mk', 'arz', 'ms', 'min', 'my', 'nl', - 'ja', 'nb', 'nn', 'ce', 'uz', 'pt', 'kk', 'ro', 'ru', 'ceb', 'sk', 'sl', 'sr', 'sh', - 'fi', 'sv', 'ta', 'tt', 'th', 'tg', 'azb', 'tr', 'uk', 'ur', 'vi', 'war', 'zh', 'yue']) - - -class Wikipedia(ComponentBase, ABC): - component_name = "Wikipedia" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return Wikipedia.be_output("") - - try: - wiki_res = [] - wikipedia.set_lang(self._param.language) - wiki_engine = wikipedia - for wiki_key in wiki_engine.search(ans, results=self._param.top_n): - page = wiki_engine.page(title=wiki_key, auto_suggest=False) - wiki_res.append({"content": '' + page.title + ' ' + page.summary}) - except Exception as e: - return Wikipedia.be_output("**ERROR**: " + str(e)) - - if not wiki_res: - return Wikipedia.be_output("") - - df = pd.DataFrame(wiki_res) - logging.debug(f"df: {df}") - return df diff --git a/agent/component/yahoofinance.py b/agent/component/yahoofinance.py deleted file mode 100644 index f31c7aed4..000000000 --- a/agent/component/yahoofinance.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging -from abc import ABC -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase -import yfinance as yf - - -class YahooFinanceParam(ComponentParamBase): - """ - Define the YahooFinance component parameters. - """ - - def __init__(self): - super().__init__() - self.info = True - self.history = False - self.count = False - self.financials = False - self.income_stmt = False - self.balance_sheet = False - self.cash_flow_statement = False - self.news = True - - def check(self): - self.check_boolean(self.info, "get all stock info") - self.check_boolean(self.history, "get historical market data") - self.check_boolean(self.count, "show share count") - self.check_boolean(self.financials, "show financials") - self.check_boolean(self.income_stmt, "income statement") - self.check_boolean(self.balance_sheet, "balance sheet") - self.check_boolean(self.cash_flow_statement, "cash flow statement") - self.check_boolean(self.news, "show news") - - -class YahooFinance(ComponentBase, ABC): - component_name = "YahooFinance" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = "".join(ans["content"]) if "content" in ans else "" - if not ans: - return YahooFinance.be_output("") - - yohoo_res = [] - try: - msft = yf.Ticker(ans) - if self._param.info: - yohoo_res.append({"content": "info:\n" + pd.Series(msft.info).to_markdown() + "\n"}) - if self._param.history: - yohoo_res.append({"content": "history:\n" + msft.history().to_markdown() + "\n"}) - if self._param.financials: - yohoo_res.append({"content": "calendar:\n" + pd.DataFrame(msft.calendar).to_markdown() + "\n"}) - if self._param.balance_sheet: - yohoo_res.append({"content": "balance sheet:\n" + msft.balance_sheet.to_markdown() + "\n"}) - yohoo_res.append( - {"content": "quarterly balance sheet:\n" + msft.quarterly_balance_sheet.to_markdown() + "\n"}) - if self._param.cash_flow_statement: - yohoo_res.append({"content": "cash flow statement:\n" + msft.cashflow.to_markdown() + "\n"}) - yohoo_res.append( - {"content": "quarterly cash flow statement:\n" + msft.quarterly_cashflow.to_markdown() + "\n"}) - if self._param.news: - yohoo_res.append({"content": "news:\n" + pd.DataFrame(msft.news).to_markdown() + "\n"}) - except Exception: - logging.exception("YahooFinance got exception") - - if not yohoo_res: - return YahooFinance.be_output("") - - return pd.DataFrame(yohoo_res) diff --git a/agent/templates/DB Assistant.json b/agent/templates/DB Assistant.json deleted file mode 100644 index 604cd3b9a..000000000 --- a/agent/templates/DB Assistant.json +++ /dev/null @@ -1,890 +0,0 @@ -{ - "id": 6, - "title": "DB Assistant", - "description": "An advanced agent that converts user queries into SQL statements, executes the queries, and assesses and returns the results. You must prepare three knowledge bases: 1: DDL for your database; 2: Examples of user queries converted to SQL statements; 3: A comprehensive description of your database, including but not limited to tables and records. You are also required to configure the corresponding database.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:SocialAdsWonder": { - "downstream": [ - "RewriteQuestion:WildIdeasTell" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": {}, - "params": {} - }, - "upstream": [ - "ExeSQL:QuietRosesRun", - "begin" - ] - }, - "ExeSQL:QuietRosesRun": { - "downstream": [ - "Answer:SocialAdsWonder" - ], - "obj": { - "component_name": "ExeSQL", - "inputs": [], - "output": {}, - "params": { - "database": "", - "db_type": "mysql", - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "host": "", - "llm_id": "deepseek-chat@DeepSeek", - "loop": 3, - "maxTokensEnabled": true, - "max_tokens": 512, - "password": "", - "port": 6630, - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 30, - "top_p": 0.3, - "username": "root" - } - }, - "upstream": [ - "Generate:BlueShirtsLaugh" - ] - }, - "Generate:BlueShirtsLaugh": { - "downstream": [ - "ExeSQL:QuietRosesRun" - ], - "obj": { - "component_name": "Generate", - "params": { - "cite": false, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "message_history_window_size": 1, - "parameters": [], - "presence_penalty": 0.4, - "prompt": "\n##The user provides a question and you provide SQL. You will only respond with SQL code and not with any explanations.\n\n##You may use the following DDL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:SillyPartsCheer}.\n\n##You may use the following documentation as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:OddSingersRefuse}.\n\n##You may use the following SQL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:BrownStreetsRhyme}.\n\n##Respond with only SQL code. Do not answer with any explanations -- just the code.", - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:SillyPartsCheer", - "Retrieval:BrownStreetsRhyme", - "Retrieval:OddSingersRefuse" - ] - }, - "Retrieval:BrownStreetsRhyme": { - "downstream": [ - "Generate:BlueShirtsLaugh" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": {}, - "params": { - "empty_response": "Nothing found in Q->SQL!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "query": [ - { - "component_id": "Answer:SocialAdsWonder", - "type": "reference" - } - ], - "similarity_threshold": 0.2, - "top_n": 8 - } - }, - "upstream": [ - "RewriteQuestion:WildIdeasTell" - ] - }, - "Retrieval:OddSingersRefuse": { - "downstream": [ - "Generate:BlueShirtsLaugh" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": {}, - "params": { - "empty_response": "Nothing found in DB-Description!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "query": [ - { - "component_id": "Answer:SocialAdsWonder", - "type": "reference" - } - ], - "similarity_threshold": 0.2, - "top_n": 8 - } - }, - "upstream": [ - "RewriteQuestion:WildIdeasTell" - ] - }, - "Retrieval:SillyPartsCheer": { - "downstream": [ - "Generate:BlueShirtsLaugh" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": {}, - "params": { - "empty_response": "Nothing found in DDL!", - "kb_ids": [], - "keywords_similarity_weight": 0.1, - "query": [ - { - "component_id": "Answer:SocialAdsWonder", - "type": "reference" - } - ], - "similarity_threshold": 0.02, - "top_n": 18 - } - }, - "upstream": [ - "RewriteQuestion:WildIdeasTell" - ] - }, - "RewriteQuestion:WildIdeasTell": { - "downstream": [ - "Retrieval:OddSingersRefuse", - "Retrieval:BrownStreetsRhyme", - "Retrieval:SillyPartsCheer" - ], - "obj": { - "component_name": "RewriteQuestion", - "params": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - } - }, - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "begin": { - "downstream": [ - "Answer:SocialAdsWonder" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": { - "content": { - "0": { - "content": "Hi! I'm your smart assistant. What can I do for you?" - } - } - }, - "params": {} - }, - "upstream": [] - } - }, - "embed_id": "BAAI/bge-large-zh-v1.5", - "graph": { - "edges": [ - { - "id": "xy-edge__ExeSQL:QuietRosesRunc-Answer:SocialAdsWonderc", - "markerEnd": "logo", - "source": "ExeSQL:QuietRosesRun", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:SocialAdsWonder", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__begin-Answer:SocialAdsWonderc", - "markerEnd": "logo", - "source": "begin", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:SocialAdsWonder", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Answer:SocialAdsWonderb-RewriteQuestion:WildIdeasTellc", - "markerEnd": "logo", - "source": "Answer:SocialAdsWonder", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "RewriteQuestion:WildIdeasTell", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__RewriteQuestion:WildIdeasTellb-Retrieval:OddSingersRefusec", - "markerEnd": "logo", - "source": "RewriteQuestion:WildIdeasTell", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:OddSingersRefuse", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__RewriteQuestion:WildIdeasTellb-Retrieval:BrownStreetsRhymec", - "markerEnd": "logo", - "source": "RewriteQuestion:WildIdeasTell", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:BrownStreetsRhyme", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__RewriteQuestion:WildIdeasTellb-Retrieval:SillyPartsCheerc", - "markerEnd": "logo", - "source": "RewriteQuestion:WildIdeasTell", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:SillyPartsCheer", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:BlueShirtsLaughc-ExeSQL:QuietRosesRunb", - "markerEnd": "logo", - "source": "Generate:BlueShirtsLaugh", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "ExeSQL:QuietRosesRun", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:SillyPartsCheerb-Generate:BlueShirtsLaughb", - "markerEnd": "logo", - "source": "Retrieval:SillyPartsCheer", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:BlueShirtsLaugh", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:BrownStreetsRhymeb-Generate:BlueShirtsLaughb", - "markerEnd": "logo", - "source": "Retrieval:BrownStreetsRhyme", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:BlueShirtsLaugh", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:OddSingersRefuseb-Generate:BlueShirtsLaughb", - "markerEnd": "logo", - "source": "Retrieval:OddSingersRefuse", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:BlueShirtsLaugh", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "label": "Begin", - "name": "begin" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -707.997699967585, - "y": 271.71609546793474 - }, - "positionAbsolute": { - "x": -707.997699967585, - "y": 271.71609546793474 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interface" - }, - "dragging": false, - "height": 44, - "id": "Answer:SocialAdsWonder", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -265.59460323639587, - "y": 271.1879130306969 - }, - "positionAbsolute": { - "x": -58.36886074370702, - "y": 272.1213623212045 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "Nothing found in DDL!", - "kb_ids": [], - "keywords_similarity_weight": 0.1, - "query": [ - { - "component_id": "Answer:SocialAdsWonder", - "type": "reference" - } - ], - "similarity_threshold": 0.02, - "top_n": 18 - }, - "label": "Retrieval", - "name": "DDL" - }, - "dragging": false, - "height": 106, - "id": "Retrieval:SillyPartsCheer", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 194.69889765569846, - "y": 61.49435233230193 - }, - "positionAbsolute": { - "x": 198.3020069445181, - "y": -0.9595420072386389 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "Nothing found in Q->SQL!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "query": [ - { - "component_id": "Answer:SocialAdsWonder", - "type": "reference" - } - ], - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "Q->SQL" - }, - "dragging": false, - "height": 106, - "id": "Retrieval:BrownStreetsRhyme", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 240.78282320440022, - "y": 162.66081324653166 - }, - "positionAbsolute": { - "x": 231.17453176754782, - "y": 123.02661106951555 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "Nothing found in DB-Description!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "query": [ - { - "component_id": "Answer:SocialAdsWonder", - "type": "reference" - } - ], - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "DB Description" - }, - "dragging": false, - "height": 106, - "id": "Retrieval:OddSingersRefuse", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 284.5720579655624, - "y": 246.75395940479467 - }, - "positionAbsolute": { - "x": 267.7575479510707, - "y": 249.15603226400776 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Based on the result of the SQL execution, returns the error message to the large model if any errors occur; otherwise, returns the result to the user." - }, - "label": "Note", - "name": "N: Analyze SQL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 165, - "id": "Note:HeavyIconsFollow", - "measured": { - "height": 165, - "width": 347 - }, - "position": { - "x": -709.8631299685773, - "y": 96.50319908555313 - }, - "positionAbsolute": { - "x": -626.6563777191027, - "y": -48.82220889683933 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 176, - "width": 266 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 347 - }, - { - "data": { - "form": { - "text": "Receives the user's database-related questions and displays the large model's response." - }, - "label": "Note", - "name": "N: Interface" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 159, - "id": "Note:PinkTaxesClean", - "measured": { - "height": 159, - "width": 259 - }, - "position": { - "x": -253.39933811515345, - "y": 353.7538896054877 - }, - "positionAbsolute": { - "x": -52.004609812312424, - "y": 336.95180237635077 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 162, - "width": 210 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 259 - }, - { - "data": { - "form": { - "text": "Searches for description about meanings of tables and fields." - }, - "label": "Note", - "name": "N:DB Description" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:IcyTreesPeel", - "measured": { - "height": 128, - "width": 251 - }, - "position": { - "x": 280.8431980571563, - "y": 394.1463067004627 - }, - "positionAbsolute": { - "x": 280.8431980571563, - "y": 394.1463067004627 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 251 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 251 - }, - { - "data": { - "form": { - "text": "Searches for samples about question to SQL.\nPlease check this dataset: https://huggingface.co/datasets/InfiniFlow/text2sql" - }, - "label": "Note", - "name": "N: Q->SQL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 143, - "id": "Note:HugeGroupsScream", - "measured": { - "height": 143, - "width": 390 - }, - "position": { - "x": 612.8793199038756, - "y": 169.1868576959871 - }, - "positionAbsolute": { - "x": 606.1206536213404, - "y": 113.09441734894426 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 131, - "width": 387 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 390 - }, - { - "data": { - "form": { - "text": "DDL(Data Definition Language).\n\nSearches for relevant database creation statements.\n\nIt should bind with a KB to which DDL is dumped in.\nYou could use 'General' as parsing method and ';' as delimiter." - }, - "label": "Note", - "name": "N: DDL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 208, - "id": "Note:GreenCrewsArrive", - "measured": { - "height": 208, - "width": 467 - }, - "position": { - "x": 649.3481710005742, - "y": -87.70873445087781 - }, - "positionAbsolute": { - "x": 545.3423934788841, - "y": -166.58872868890683 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 266, - "width": 266 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 467 - }, - { - "data": { - "form": { - "text": "The large model learns which tables may be available based on the responses from three knowledge bases and converts the user's input into SQL statements." - }, - "label": "Note", - "name": "N: Generate SQL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 196, - "id": "Note:EightTurtlesLike", - "measured": { - "height": 196, - "width": 341 - }, - "position": { - "x": 134.0070839275931, - "y": -345.41228234051727 - }, - "positionAbsolute": { - "x": 222.2150747084395, - "y": -445.32694170868734 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 175, - "width": 265 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 341 - }, - { - "data": { - "form": { - "text": "Executes the SQL statement in the database and returns the result.\n\nAfter configuring an accessible database, press 'Test' to ensure the accessibility.\n\nThe large model modifies the original SQL statement based on the error message and returns the modified SQL statement." - }, - "label": "Note", - "name": "N: Execute SQL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 276, - "id": "Note:FreshKidsTalk", - "measured": { - "height": 276, - "width": 336 - }, - "position": { - "x": -304.3577648765364, - "y": -288.054469323955 - }, - "positionAbsolute": { - "x": -251.5866574377311, - "y": -372.2192837064241 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 178, - "width": 346 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 336 - }, - { - "data": { - "form": { - "database": "", - "db_type": "mysql", - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "host": "", - "llm_id": "deepseek-chat@DeepSeek", - "loop": 3, - "maxTokensEnabled": true, - "max_tokens": 512, - "password": "", - "port": 6630, - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 30, - "top_p": 0.3, - "username": "root" - }, - "label": "ExeSQL", - "name": "ExeSQL" - }, - "dragging": false, - "id": "ExeSQL:QuietRosesRun", - "measured": { - "height": 64, - "width": 200 - }, - "position": { - "x": -318.61920731731163, - "y": 3.5145731711609436 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode" - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "RewriteQuestion", - "name": "RefineQuestion" - }, - "dragging": false, - "id": "RewriteQuestion:WildIdeasTell", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": -7.734116293705583, - "y": 236.92372325779243 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "rewriteNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "\n##The user provides a question and you provide SQL. You will only respond with SQL code and not with any explanations.\n\n##You may use the following DDL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:SillyPartsCheer}.\n\n##You may use the following documentation as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:OddSingersRefuse}.\n\n##You may use the following SQL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:BrownStreetsRhyme}.\n\n##Respond with only SQL code. Do not answer with any explanations -- just the code.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Generate SQL Statement LLM" - }, - "dragging": false, - "id": "Generate:BlueShirtsLaugh", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 147.62383788095065, - "y": -116.47462293167156 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} diff --git a/agent/templates/HR_callout_zh.json b/agent/templates/HR_callout_zh.json deleted file mode 100644 index 2d73cd8e6..000000000 --- a/agent/templates/HR_callout_zh.json +++ /dev/null @@ -1,1806 +0,0 @@ -{ - "id": 2, - "title": "HR recruitment pitch assistant (Chinese)", - "description": "A recruitment pitch assistant capable of pitching a candidate, presenting a job opportunity, addressing queries, and requesting the candidate's contact details. Let's begin by linking a knowledge base containing the job description in 'Retrieval'!", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:TwentyMugsDeny": { - "downstream": [ - "categorize:1" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "Message:MajorPigsYell", - "Generate:TruePawsReport", - "Generate:ToughLawsCheat", - "Generate:KindCarrotsSit", - "Generate:DirtyToolsTrain", - "Generate:FluffyPillowsGrow", - "Generate:ProudEarsWorry" - ] - }, - "Generate:DirtyToolsTrain": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,当你提出加微信时对方表示拒绝。你需要耐心礼貌的回应候选人,表示对于保护隐私信息给予理解,也可以询问他对该职位的看法和顾虑。并在恰当的时机再次询问微信联系方式。也可以鼓励候选人主动与你取得联系。你的微信号是weixin_kevin,E-mail是kkk@ragflow.com。说话不要重复。不要总是您好。", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "categorize:1" - ] - }, - "Generate:FluffyPillowsGrow": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [ - { - "component_id": "Retrieval:ColdEelsArrive", - "id": "5166a107-e859-4c71-99a2-3a216c775347", - "key": "jd" - } - ], - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,候选人问了有关职位或公司的问题,你根据以下职位信息回答。如果职位信息中不包含候选人的问题就回答不清楚、不知道、有待确认等。回答完后引导候选人加微信号,如:\n - 方便加一下微信吗,我把JD发您看看?\n - 微信号多少,我把详细职位JD发您?\n 职位信息如下:\n {Retrieval:ColdEelsArrive}\n 职位信息如上。", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:ColdEelsArrive" - ] - }, - "Generate:KindCarrotsSit": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,候选人表示不反感加微信,如果对方已经报了微信号,表示感谢和信任并表示马上会加上;如果没有,则问对方微信号多少。你的微信号是weixin_kevin,E-mail是kkk@ragflow.com。说话不要重复。不要总是您好。", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "categorize:1" - ] - }, - "Generate:ProudEarsWorry": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,现在候选人的聊了和职位无关的话题,请耐心的回应候选人,并将话题往该AGI的职位上带,最好能要到候选人微信号以便后面保持联系。", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "categorize:0" - ] - }, - "Generate:ToughLawsCheat": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,现在候选人的聊了和职位无关的话题,请耐心的回应候选人,并将话题往该AGI的职位上带,最好能要到候选人微信号以便后面保持联系。", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "categorize:1" - ] - }, - "Generate:TruePawsReport": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,候选人问了有关职位或公司的问题,你根据以下职位信息回答。如果职位信息中不包含候选人的问题就回答不清楚、不知道、有待确认等。回答完后引导候选人加微信号,如:\n - 方便加一下微信吗,我把JD发您看看?\n - 微信号多少,我把详细职位JD发您?\n 职位信息如下:\n {Retrieval:ShaggyRadiosRetire}\n 职位信息如上。", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:ShaggyRadiosRetire" - ] - }, - "Message:MajorPigsYell": { - "downstream": [ - "Answer:TwentyMugsDeny" - ], - "obj": { - "component_name": "Message", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "messages": [ - "我简单介绍一下:\nRAGFlow 是一款基于深度文档理解构建的开源 RAG(Retrieval-Augmented Generation)引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程,结合大语言模型(LLM)针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用。https://github.com/infiniflow/ragflow\n您那边还有什么要了解的?" - ], - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "upstream": [ - "categorize:0" - ] - }, - "Retrieval:ColdEelsArrive": { - "downstream": [ - "Generate:FluffyPillowsGrow" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 6 - } - }, - "upstream": [ - "categorize:1" - ] - }, - "Retrieval:ShaggyRadiosRetire": { - "downstream": [ - "Generate:TruePawsReport" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 6 - } - }, - "upstream": [ - "categorize:0" - ] - }, - "answer:0": { - "downstream": [ - "categorize:0" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "begin", - "message:reject" - ] - }, - "begin": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "您好!我是英飞流负责招聘的HR,了解到您是这方面的大佬,然后冒昧的就联系到您。这边有个机会想和您分享,RAGFlow正在招聘您这个岗位的资深的工程师不知道您那边是不是感兴趣?", - "query": [] - } - }, - "upstream": [] - }, - "categorize:0": { - "downstream": [ - "message:reject", - "Retrieval:ShaggyRadiosRetire", - "Generate:ProudEarsWorry", - "Message:MajorPigsYell" - ], - "obj": { - "component_name": "Categorize", - "inputs": [], - "output": null, - "params": { - "category_description": { - "answer": { - "description": "该问题关于职位本身或公司的信息。", - "examples": "什么岗位?\n汇报对象是谁?\n公司多少人?\n公司有啥产品?\n具体工作内容是啥?\n地点哪里?\n双休吗?", - "to": "Retrieval:ShaggyRadiosRetire" - }, - "casual": { - "description": "该问题不关于职位本身或公司的信息,属于闲聊。", - "examples": "你好\n好久不见\n你男的女的?\n你是猴子派来的救兵吗?\n上午开会了?\n你叫啥?\n最近市场如何?生意好做吗?", - "to": "Generate:ProudEarsWorry" - }, - "interested": { - "description": "该回答表示他对于该职位感兴趣。", - "examples": "嗯\n说吧\n说说看\n还好吧\n是的\n哦\nyes\n具体说说", - "to": "Message:MajorPigsYell" - }, - "reject": { - "description": "该回答表示他对于该职位不感兴趣,或感觉受到骚扰。", - "examples": "不需要\n不感兴趣\n暂时不看\n不要\nno\n我已经不干这个了\n我不是这个方向的", - "to": "message:reject" - } - }, - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 512, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "answer:0" - ] - }, - "categorize:1": { - "downstream": [ - "Retrieval:ColdEelsArrive", - "Generate:ToughLawsCheat", - "Generate:KindCarrotsSit", - "Generate:DirtyToolsTrain" - ], - "obj": { - "component_name": "Categorize", - "inputs": [], - "output": null, - "params": { - "category_description": { - "about_job": { - "description": "该问题关于职位本身或公司的信息。", - "examples": "什么岗位?\n汇报对象是谁?\n公司多少人?\n公司有啥产品?\n具体工作内容是啥?\n地点哪里?\n双休吗?", - "to": "Retrieval:ColdEelsArrive" - }, - "casual": { - "description": "该问题不关于职位本身或公司的信息,属于闲聊。", - "examples": "你好\n好久不见\n你男的女的?\n你是猴子派来的救兵吗?\n上午开会了?\n你叫啥?\n最近市场如何?生意好做吗?", - "to": "Generate:ToughLawsCheat" - }, - "giveup": { - "description": "该回答表示他不愿意加微信。", - "examples": "不需要\n不感兴趣\n暂时不看\n不要\nno\n不方便\n不知道还要加我微信", - "to": "Generate:DirtyToolsTrain" - }, - "wechat": { - "description": "该回答表示他愿意加微信,或者已经报了微信号。", - "examples": "嗯\n可以\n是的\n哦\nyes\n15002333453\nwindblow_2231", - "to": "Generate:KindCarrotsSit" - } - }, - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 512, - "message_history_window_size": 8, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Answer:TwentyMugsDeny" - ] - }, - "message:reject": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Message", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "messages": [ - "好的,祝您生活愉快,工作顺利。", - "哦,好的,感谢您宝贵的时间!" - ], - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "upstream": [ - "categorize:0" - ] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "7a045a3d-5881-4a57-9467-75946941a642", - "label": "", - "source": "begin", - "target": "answer:0" - }, - { - "id": "9c6c78c1-532c-423d-9712-61c47a452f0e", - "label": "", - "source": "message:reject", - "target": "answer:0" - }, - { - "id": "reactflow__edge-answer:0b-categorize:0a", - "source": "answer:0", - "sourceHandle": "b", - "target": "categorize:0", - "targetHandle": "a", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:TwentyMugsDenyb-categorize:1a", - "markerEnd": "logo", - "source": "Answer:TwentyMugsDeny", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "categorize:1", - "targetHandle": "a", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Retrieval:ShaggyRadiosRetireb-Generate:TruePawsReportc", - "markerEnd": "logo", - "source": "Retrieval:ShaggyRadiosRetire", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:TruePawsReport", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:0reject-message:rejectb", - "markerEnd": "logo", - "source": "categorize:0", - "sourceHandle": "reject", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "message:reject", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:0answer-Retrieval:ShaggyRadiosRetirec", - "markerEnd": "logo", - "source": "categorize:0", - "sourceHandle": "answer", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:ShaggyRadiosRetire", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:0casual-Generate:ProudEarsWorryc", - "markerEnd": "logo", - "source": "categorize:0", - "sourceHandle": "casual", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ProudEarsWorry", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Message:MajorPigsYellb-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Message:MajorPigsYell", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:0interested-Message:MajorPigsYellc", - "markerEnd": "logo", - "source": "categorize:0", - "sourceHandle": "interested", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Message:MajorPigsYell", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:TruePawsReportb-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Generate:TruePawsReport", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:1about_job-Retrieval:ColdEelsArriveb", - "markerEnd": "logo", - "source": "categorize:1", - "sourceHandle": "about_job", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:ColdEelsArrive", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:1casual-Generate:ToughLawsCheatb", - "markerEnd": "logo", - "source": "categorize:1", - "sourceHandle": "casual", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ToughLawsCheat", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:1wechat-Generate:KindCarrotsSitb", - "markerEnd": "logo", - "source": "categorize:1", - "sourceHandle": "wechat", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:KindCarrotsSit", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-categorize:1giveup-Generate:DirtyToolsTrainb", - "markerEnd": "logo", - "source": "categorize:1", - "sourceHandle": "giveup", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:DirtyToolsTrain", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:ToughLawsCheatc-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Generate:ToughLawsCheat", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:KindCarrotsSitc-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Generate:KindCarrotsSit", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:DirtyToolsTrainc-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Generate:DirtyToolsTrain", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Retrieval:ColdEelsArrivec-Generate:FluffyPillowsGrowb", - "markerEnd": "logo", - "source": "Retrieval:ColdEelsArrive", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FluffyPillowsGrow", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:FluffyPillowsGrowc-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Generate:FluffyPillowsGrow", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:ProudEarsWorryb-Answer:TwentyMugsDenyc", - "markerEnd": "logo", - "source": "Generate:ProudEarsWorry", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TwentyMugsDeny", - "targetHandle": "c", - "type": "buttonEdge" - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "您好!我是英飞流负责招聘的HR,了解到您是这方面的大佬,然后冒昧的就联系到您。这边有个机会想和您分享,RAGFlow正在招聘您这个岗位的资深的工程师不知道您那边是不是感兴趣?" - }, - "label": "Begin", - "name": "开场白" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": -1034.5459371394727, - "y": -4.596073111491364 - }, - "positionAbsolute": { - "x": -1034.5459371394727, - "y": -4.596073111491364 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "交互1" - }, - "dragging": false, - "height": 44, - "id": "answer:0", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -759.3845780310955, - "y": -1.5248388351160145 - }, - "positionAbsolute": { - "x": -781.130188267973, - "y": -1.5248388351160145 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "category_description": { - "answer": { - "description": "该问题关于职位本身或公司的信息。", - "examples": "什么岗位?\n汇报对象是谁?\n公司多少人?\n公司有啥产品?\n具体工作内容是啥?\n地点哪里?\n双休吗?", - "to": "Retrieval:ShaggyRadiosRetire" - }, - "casual": { - "description": "该问题不关于职位本身或公司的信息,属于闲聊。", - "examples": "你好\n好久不见\n你男的女的?\n你是猴子派来的救兵吗?\n上午开会了?\n你叫啥?\n最近市场如何?生意好做吗?", - "to": "Generate:ProudEarsWorry" - }, - "interested": { - "description": "该回答表示他对于该职位感兴趣。", - "examples": "嗯\n说吧\n说说看\n还好吧\n是的\n哦\nyes\n具体说说", - "to": "Message:MajorPigsYell" - }, - "reject": { - "description": "该回答表示他对于该职位不感兴趣,或感觉受到骚扰。", - "examples": "不需要\n不感兴趣\n暂时不看\n不要\nno\n我已经不干这个了\n我不是这个方向的", - "to": "message:reject" - } - }, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 512, - "message_history_window_size": 1, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Categorize", - "name": "是否感兴趣?" - }, - "dragging": false, - "height": 223, - "id": "categorize:0", - "measured": { - "height": 223, - "width": 200 - }, - "position": { - "x": -511.7953063678477, - "y": -91.33627890840192 - }, - "positionAbsolute": { - "x": -511.7953063678477, - "y": -91.33627890840192 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "categorizeNode", - "width": 200 - }, - { - "data": { - "form": { - "category_description": { - "about_job": { - "description": "该问题关于职位本身或公司的信息。", - "examples": "什么岗位?\n汇报对象是谁?\n公司多少人?\n公司有啥产品?\n具体工作内容是啥?\n地点哪里?\n双休吗?", - "to": "Retrieval:ColdEelsArrive" - }, - "casual": { - "description": "该问题不关于职位本身或公司的信息,属于闲聊。", - "examples": "你好\n好久不见\n你男的女的?\n你是猴子派来的救兵吗?\n上午开会了?\n你叫啥?\n最近市场如何?生意好做吗?", - "to": "Generate:ToughLawsCheat" - }, - "giveup": { - "description": "该回答表示他不愿意加微信。", - "examples": "不需要\n不感兴趣\n暂时不看\n不要\nno\n不方便\n不知道还要加我微信", - "to": "Generate:DirtyToolsTrain" - }, - "wechat": { - "description": "该回答表示他愿意加微信,或者已经报了微信号。", - "examples": "嗯\n可以\n是的\n哦\nyes\n15002333453\nwindblow_2231", - "to": "Generate:KindCarrotsSit" - } - }, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 512, - "message_history_window_size": 8, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Categorize", - "name": "可以加微信?" - }, - "dragging": false, - "height": 223, - "id": "categorize:1", - "measured": { - "height": 223, - "width": 200 - }, - "position": { - "x": 650.2305440350307, - "y": 54.40917808770183 - }, - "positionAbsolute": { - "x": 650.2305440350307, - "y": 54.40917808770183 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "categorizeNode", - "width": 200 - }, - { - "data": { - "form": { - "messages": [ - "好的,祝您生活愉快,工作顺利。", - "哦,好的,感谢您宝贵的时间!" - ] - }, - "label": "Message", - "name": "再会" - }, - "dragging": false, - "height": 44, - "id": "message:reject", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -531.5363370421936, - "y": 169.8364292609376 - }, - "positionAbsolute": { - "x": -506.16645843250325, - "y": 197.6224867858366 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "交互2" - }, - "dragging": false, - "height": 44, - "id": "Answer:TwentyMugsDeny", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 361.4824760998825, - "y": 142.99203467677523 - }, - "positionAbsolute": { - "x": 361.4824760998825, - "y": 142.99203467677523 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 6 - }, - "label": "Retrieval", - "name": "搜索职位信息" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:ShaggyRadiosRetire", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -200.47207828507428, - "y": -241.8885484926048 - }, - "positionAbsolute": { - "x": -200.47207828507428, - "y": -241.8885484926048 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,候选人问了有关职位或公司的问题,你根据以下职位信息回答。如果职位信息中不包含候选人的问题就回答不清楚、不知道、有待确认等。回答完后引导候选人加微信号,如:\n - 方便加一下微信吗,我把JD发您看看?\n - 微信号多少,我把详细职位JD发您?\n 职位信息如下:\n {Retrieval:ShaggyRadiosRetire}\n 职位信息如上。", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "回答职位信息并加微信" - }, - "dragging": false, - "height": 86, - "id": "Generate:TruePawsReport", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 85.46499814334565, - "y": -84.90136892177973 - }, - "positionAbsolute": { - "x": 114.45914512584898, - "y": -243.16108786794368 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,现在候选人的聊了和职位无关的话题,请耐心的回应候选人,并将话题往该AGI的职位上带,最好能要到候选人微信号以便后面保持联系。", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "闲聊" - }, - "dragging": false, - "height": 86, - "id": "Generate:ProudEarsWorry", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -201.4798710337693, - "y": 19.284469688181446 - }, - "positionAbsolute": { - "x": -201.4798710337693, - "y": 19.284469688181446 - }, - "selected": true, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "messages": [ - "我简单介绍一下:\nRAGFlow 是一款基于深度文档理解构建的开源 RAG(Retrieval-Augmented Generation)引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程,结合大语言模型(LLM)针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用。https://github.com/infiniflow/ragflow\n您那边还有什么要了解的?" - ] - }, - "label": "Message", - "name": "职位简介" - }, - "dragging": false, - "height": 82, - "id": "Message:MajorPigsYell", - "measured": { - "height": 82, - "width": 200 - }, - "position": { - "x": -201.4757352153133, - "y": 142.14338727751849 - }, - "positionAbsolute": { - "x": -202.68382467291758, - "y": 127.64631378626683 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "messageNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,现在候选人的聊了和职位无关的话题,请耐心的回应候选人,并将话题往该AGI的职位上带,最好能要到候选人微信号以便后面保持联系。", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "闲聊(1)" - }, - "dragging": false, - "height": 86, - "id": "Generate:ToughLawsCheat", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 717.0666295332912, - "y": -260.4610326390065 - }, - "positionAbsolute": { - "x": 719.4828084484998, - "y": -241.13160131733764 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 6 - }, - "label": "Retrieval", - "name": "搜索职位信息(1)" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:ColdEelsArrive", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 679.4658067127144, - "y": -15.040383599249951 - }, - "positionAbsolute": { - "x": 681.881985627923, - "y": -7.791846853624122 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,候选人表示不反感加微信,如果对方已经报了微信号,表示感谢和信任并表示马上会加上;如果没有,则问对方微信号多少。你的微信号是weixin_kevin,E-mail是kkk@ragflow.com。说话不要重复。不要总是您好。", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "加微信" - }, - "dragging": false, - "height": 86, - "id": "Generate:KindCarrotsSit", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 679.5187009685263, - "y": 298.0100840992407 - }, - "positionAbsolute": { - "x": 679.5187009685263, - "y": 298.0100840992407 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,当你提出加微信时对方表示拒绝。你需要耐心礼貌的回应候选人,表示对于保护隐私信息给予理解,也可以询问他对该职位的看法和顾虑。并在恰当的时机再次询问微信联系方式。也可以鼓励候选人主动与你取得联系。你的微信号是weixin_kevin,E-mail是kkk@ragflow.com。说话不要重复。不要总是您好。", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "不同意加微信后引导" - }, - "dragging": false, - "height": 86, - "id": "Generate:DirtyToolsTrain", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 713.3958582226193, - "y": 412.69665533104524 - }, - "positionAbsolute": { - "x": 730.3091106290796, - "y": 400.61576075500216 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "接收用户第一次输入,或在判断后输出静态消息。" - }, - "label": "Note", - "name": "N: 交互1" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:SharpWingsGrab", - "measured": { - "height": 128, - "width": 190 - }, - "position": { - "x": -762.470214040517, - "y": -135.06311183543562 - }, - "positionAbsolute": { - "x": -785.4239137349989, - "y": -137.47929075064422 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 190 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 190 - }, - { - "data": { - "form": { - "text": "大模型判断用户的输入属于哪一种分类,传给不同的组件。" - }, - "label": "Note", - "name": "N:是否感兴趣" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:ThickOrangesMelt", - "measured": { - "height": 128, - "width": 198 - }, - "position": { - "x": -514.737951592251, - "y": -232.7753166367196 - }, - "positionAbsolute": { - "x": -514.737951592251, - "y": -232.7753166367196 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 198 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 198 - }, - { - "data": { - "form": { - "text": "接收用户对职位不感兴趣的相关输入,随机返回一条静态消息。" - }, - "label": "Note", - "name": "N: 再会" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:FineDaysCheat", - "measured": { - "height": 128, - "width": 203 - }, - "position": { - "x": -530.3000123190136, - "y": 248.91808187570632 - }, - "positionAbsolute": { - "x": -503.7220442517189, - "y": 256.16661862133213 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 203 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 203 - }, - { - "data": { - "form": { - "text": "接收用户对职位感兴趣的相关输入,返回其中的静态消息。" - }, - "label": "Note", - "name": "N:职位简介" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:WeakTaxesBegin", - "measured": { - "height": 128, - "width": 208 - }, - "position": { - "x": -197.5153373041337, - "y": 261.2072463084719 - }, - "positionAbsolute": { - "x": -203.55578459215516, - "y": 261.2072463084719 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 208 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 208 - }, - { - "data": { - "form": { - "text": "接收用户闲聊,根据闲聊内容,大模型返回相应的回答。" - }, - "label": "Note", - "name": "N: 闲聊" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:FourCornersHelp", - "measured": { - "height": 128, - "width": 213 - }, - "position": { - "x": -195.26410221591698, - "y": -125.75023229737762 - }, - "positionAbsolute": { - "x": -195.26410221591698, - "y": -125.75023229737762 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 213 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 213 - }, - { - "data": { - "form": { - "text": "接收用户对于职位或者公司的问题,检索知识库,返回检索到的内容。" - }, - "label": "Note", - "name": "N: 搜索职位信息" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:FortyTiresDance", - "measured": { - "height": 128, - "width": 197 - }, - "position": { - "x": -199.51694815612117, - "y": -382.54628777242647 - }, - "positionAbsolute": { - "x": -199.51694815612117, - "y": -382.54628777242647 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 197 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 197 - }, - { - "data": { - "form": { - "text": "大模型根据检索到的职位信息,回答用户的输入并请求加微信。" - }, - "label": "Note", - "name": "N: 回答职位信息" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:SixMasksTie", - "measured": { - "height": 128, - "width": 205 - }, - "position": { - "x": 81.31654079972914, - "y": -230.7938043878787 - }, - "positionAbsolute": { - "x": 113.93495615504537, - "y": -379.38880767320825 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 205 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 205 - }, - { - "data": { - "form": { - "text": "在第一轮的交互完成后,在确定用户的意愿基础上,继续后续的交流。" - }, - "label": "Note", - "name": "N: 交互2" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 132, - "id": "Note:HipAnimalsLose", - "measured": { - "height": 132, - "width": 200 - }, - "position": { - "x": 361.5573430860398, - "y": 202.76501272911685 - }, - "positionAbsolute": { - "x": 361.5573430860398, - "y": 202.76501272911685 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 132, - "width": 200 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "接收用户不愿意加微信的请求,大模型生成回答,回答与礼貌用语和引导用户加微信相关。" - }, - "label": "Note", - "name": "N: 不同意加微信后" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 144, - "id": "Note:CalmClownsOpen", - "measured": { - "height": 144, - "width": 200 - }, - "position": { - "x": 724.3625736109275, - "y": 527.6312716948657 - }, - "positionAbsolute": { - "x": 729.1949314413447, - "y": 498.6371247123624 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 144, - "width": 200 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "接收用户加微信的请求或微信号的信息。如果是加微信请求,则大模型返回询问微信的回答;如果是微信号的信息,则大模型返回礼貌性的回答。" - }, - "label": "Note", - "name": "N: 加微信" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 149, - "id": "Note:EightSuitsAdmire", - "measured": { - "height": 149, - "width": 481 - }, - "position": { - "x": 1118.6632741834096, - "y": 300.1313513476347 - }, - "positionAbsolute": { - "x": 1118.6632741834096, - "y": 300.1313513476347 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 149, - "width": 481 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 481 - }, - { - "data": { - "form": { - "text": "大模型判断用户的输入属于哪一种分类,传给不同的组件。" - }, - "label": "Note", - "name": "N:可以加微信?" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:SillyPillowsCrash", - "measured": { - "height": 128, - "width": 267 - }, - "position": { - "x": 1006.2146104300559, - "y": 61.99026665969035 - }, - "positionAbsolute": { - "x": 1006.2146104300559, - "y": 61.99026665969035 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 267 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 267 - }, - { - "data": { - "form": { - "text": "接收用户对于职位或者公司的问题,检索知识库,返回检索到的内容。" - }, - "label": "Note", - "name": "N: 搜索职位信息(1)" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:PurplePathsHeal", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": 679.0610551820539, - "y": -146.81167586458758 - }, - "positionAbsolute": { - "x": 679.0610551820539, - "y": -146.81167586458758 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "接收用户闲聊,根据闲聊内容,大模型返回相应的回答。" - }, - "label": "Note", - "name": "N:闲聊(1)" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 129, - "id": "Note:VastHumansAttend", - "measured": { - "height": 129, - "width": 200 - }, - "position": { - "x": 713.2672727035068, - "y": -403.49170163825374 - }, - "positionAbsolute": { - "x": 719.3077199915283, - "y": -382.2721004750209 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 129, - "width": 200 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [ - { - "component_id": "Retrieval:ColdEelsArrive", - "id": "5166a107-e859-4c71-99a2-3a216c775347", - "key": "jd" - } - ], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "你是公司负责招聘的HR,候选人问了有关职位或公司的问题,你根据以下职位信息回答。如果职位信息中不包含候选人的问题就回答不清楚、不知道、有待确认等。回答完后引导候选人加微信号,如:\n - 方便加一下微信吗,我把JD发您看看?\n - 微信号多少,我把详细职位JD发您?\n 职位信息如下:\n {Retrieval:ColdEelsArrive}\n 职位信息如上。", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "回答职位信息并加微信(1)" - }, - "dragging": false, - "height": 128, - "id": "Generate:FluffyPillowsGrow", - "measured": { - "height": 128, - "width": 200 - }, - "position": { - "x": 411.4591451258489, - "y": -7.161087867943763 - }, - "positionAbsolute": { - "x": 411.4591451258489, - "y": -7.161087867943763 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/jpeg;base64,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" -} diff --git a/agent/templates/customer_service.json b/agent/templates/customer_service.json deleted file mode 100644 index d3dcc70fe..000000000 --- a/agent/templates/customer_service.json +++ /dev/null @@ -1,1068 +0,0 @@ -{ - "id": 3, - "title": "Customer service", - "description": "A customer service chatbot that explains product specifications, addresses customer queries, and alleviates negative emotions.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Categorize:EightyWavesEnd": { - "downstream": [ - "Generate:FullBeersSit", - "Message:GoodBugsTurn", - "Retrieval:WholeStarsDrive", - "Generate:EasyWaysBeg" - ], - "obj": { - "component_name": "Categorize", - "inputs": [], - "output": null, - "params": { - "category_description": { - "1. contact": { - "description": "This answer provide a specific contact information, like e-mail, phone number, wechat number, line number, twitter, discord, etc,.", - "examples": "My phone number is 203921\nkevinhu.hk@gmail.com\nThis is my discord number: johndowson_29384\n13212123432\n8379829", - "to": "Message:GoodBugsTurn" - }, - "2. casual": { - "description": "The question is not about the product usage, appearance and how it works. Just casual chat.", - "examples": "How are you doing?\nWhat is your name?\nAre you a robot?\nWhat's the weather?\nWill it rain?", - "to": "Generate:EasyWaysBeg" - }, - "3. complain": { - "description": "Complain even curse about the product or service you provide. But the comment is not specific enough.", - "examples": "How bad is it.\nIt's really sucks.\nDamn, for God's sake, can it be more steady?\nShit, I just can't use this shit.\nI can't stand it anymore.", - "to": "Generate:FullBeersSit" - }, - "4. product related": { - "description": "The question is about the product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?\nException: Can't connect to ES cluster\nHow to build the RAGFlow image from scratch", - "to": "Retrieval:WholeStarsDrive" - } - }, - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 512, - "message_history_window_size": 8, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "", - "query": [{ - "type": "reference", - "component_id": "RewriteQuestion:AllNightsSniff" - }], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "RewriteQuestion:AllNightsSniff" - ] - }, - "Generate:EasyWaysBeg": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "You are a customer support. But the customer wants to have a casual chat with you instead of consulting about the product. Be nice, funny, enthusiasm and concern.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Categorize:EightyWavesEnd" - ] - }, - "Generate:FullBeersSit": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "You are a customer support. the Customers complain even curse about the products but not specific enough. You need to ask him/her what's the specific problem with the product. Be nice, patient and concern to soothe your customers’ emotions at first place.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Categorize:EightyWavesEnd" - ] - }, - "Generate:YoungTrainsSee": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a customer support. \n\nTask: Please answer the question based on content of knowledge base. \n\nRequirements & restrictions:\n - DO NOT make things up when all knowledge base content is irrelevant to the question. \n - Answers need to consider chat history.\n - Request about customer's contact information like, Wechat number, LINE number, twitter, discord, etc,. , when knowledge base content can't answer his question. So, product expert could contact him soon to solve his problem.\n\n Knowledge base content is as following:\n {Retrieval:WholeStarsDrive}\n The above is the content of knowledge base.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:WholeStarsDrive" - ] - }, - "Message:GoodBugsTurn": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Message", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "messages": [ - "Okay, I've already write this down. What else I can do for you?", - "Get it. What else I can do for you?", - "Thanks for your trust! Our expert will contact ASAP. So, anything else I can do for you?", - "Thanks! So, anything else I can do for you?" - ], - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "upstream": [ - "Categorize:EightyWavesEnd" - ] - }, - "Retrieval:WholeStarsDrive": { - "downstream": [ - "Generate:YoungTrainsSee" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 6, - "query": [{ - "type": "reference", - "component_id": "RewriteQuestion:AllNightsSniff" - }], - "use_kg": false - } - }, - "upstream": [ - "Categorize:EightyWavesEnd" - ] - }, - "RewriteQuestion:AllNightsSniff": { - "downstream": [ - "Categorize:EightyWavesEnd" - ], - "obj": { - "component_name": "RewriteQuestion", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "loop": 1, - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - } - }, - "upstream": [ - "answer:0" - ] - }, - "answer:0": { - "downstream": [ - "RewriteQuestion:AllNightsSniff" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "Message:GoodBugsTurn", - "Generate:FullBeersSit", - "begin", - "Generate:YoungTrainsSee", - "Generate:EasyWaysBeg" - ] - }, - "begin": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "Hi! How can I help you?", - "query": [] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-Retrieval:WholeStarsDriveb-Generate:YoungTrainsSeeb", - "markerEnd": "logo", - "source": "Retrieval:WholeStarsDrive", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:YoungTrainsSee", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Message:GoodBugsTurnb-answer:0b", - "markerEnd": "logo", - "source": "Message:GoodBugsTurn", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "answer:0", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:FullBeersSitb-answer:0b", - "markerEnd": "logo", - "source": "Generate:FullBeersSit", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "answer:0", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-begin-answer:0b", - "markerEnd": "logo", - "source": "begin", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "answer:0", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:YoungTrainsSeec-answer:0b", - "markerEnd": "logo", - "source": "Generate:YoungTrainsSee", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "answer:0", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "xy-edge__answer:0c-RewriteQuestion:AllNightsSniffb", - "markerEnd": "logo", - "source": "answer:0", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "RewriteQuestion:AllNightsSniff", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__RewriteQuestion:AllNightsSniffc-Categorize:EightyWavesEnda", - "markerEnd": "logo", - "source": "RewriteQuestion:AllNightsSniff", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Categorize:EightyWavesEnd", - "targetHandle": "a", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "reactflow__edge-Categorize:EightyWavesEnd3. complain-Generate:FullBeersSitc", - "markerEnd": "logo", - "source": "Categorize:EightyWavesEnd", - "sourceHandle": "3. complain", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FullBeersSit", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Categorize:EightyWavesEnd1. contact-Message:GoodBugsTurnc", - "markerEnd": "logo", - "source": "Categorize:EightyWavesEnd", - "sourceHandle": "1. contact", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Message:GoodBugsTurn", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "xy-edge__Categorize:EightyWavesEnd4. product related-Retrieval:WholeStarsDrivec", - "markerEnd": "logo", - "source": "Categorize:EightyWavesEnd", - "sourceHandle": "4. product related", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:WholeStarsDrive", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:EasyWaysBegb-answer:0b", - "markerEnd": "logo", - "source": "Generate:EasyWaysBeg", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "answer:0", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Categorize:EightyWavesEnd2. casual-Generate:EasyWaysBegc", - "markerEnd": "logo", - "source": "Categorize:EightyWavesEnd", - "sourceHandle": "2. casual", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:EasyWaysBeg", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "Hi! How can I help you?" - }, - "label": "Begin", - "name": "Opener" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": 392.4805720357097, - "y": -51.634011497163186 - }, - "positionAbsolute": { - "x": 392.4805720357097, - "y": -51.634011497163186 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interface" - }, - "dragging": false, - "height": 44, - "id": "answer:0", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 254.80252337926834, - "y": 311.451851495964 - }, - "positionAbsolute": { - "x": 248.41227675535197, - "y": 216.6631932412045 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "category_description": { - "1. contact": { - "description": "This answer provide a specific contact information, like e-mail, phone number, wechat number, line number, twitter, discord, etc,.", - "examples": "My phone number is 203921\nkevinhu.hk@gmail.com\nThis is my discord number: johndowson_29384\n13212123432\n8379829", - "to": "Message:GoodBugsTurn" - }, - "2. casual": { - "description": "The question is not about the product usage, appearance and how it works. Just casual chat.", - "examples": "How are you doing?\nWhat is your name?\nAre you a robot?\nWhat's the weather?\nWill it rain?", - "to": "Generate:EasyWaysBeg" - }, - "3. complain": { - "description": "Complain even curse about the product or service you provide. But the comment is not specific enough.", - "examples": "How bad is it.\nIt's really sucks.\nDamn, for God's sake, can it be more steady?\nShit, I just can't use this shit.\nI can't stand it anymore.", - "to": "Generate:FullBeersSit" - }, - "4. product related": { - "description": "The question is about the product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?\nException: Can't connect to ES cluster\nHow to build the RAGFlow image from scratch", - "to": "Retrieval:WholeStarsDrive" - } - }, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 512, - "message_history_window_size": 8, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3, - "query": [{ - "type": "reference", - "component_id": "RewriteQuestion:AllNightsSniff" - }] - }, - "label": "Categorize", - "name": "Question Categorize" - }, - "dragging": false, - "height": 223, - "id": "Categorize:EightyWavesEnd", - "measured": { - "height": 223, - "width": 200 - }, - "position": { - "x": -47.29188154660176, - "y": 702.9033359893137 - }, - "positionAbsolute": { - "x": -47.29188154660176, - "y": 702.9033359893137 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "categorizeNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a customer support. \n\nTask: Please answer the question based on content of knowledge base. \n\nRequirements & restrictions:\n - DO NOT make things up when all knowledge base content is irrelevant to the question. \n - Answers need to consider chat history.\n - Request about customer's contact information like, Wechat number, LINE number, twitter, discord, etc,. , when knowledge base content can't answer his question. So, product expert could contact him soon to solve his problem.\n\n Knowledge base content is as following:\n {Retrieval:WholeStarsDrive}\n The above is the content of knowledge base.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Product info" - }, - "dragging": false, - "height": 86, - "id": "Generate:YoungTrainsSee", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 559.5686776472737, - "y": 290.2322665670026 - }, - "positionAbsolute": { - "x": 634.1215549262979, - "y": 195.4436083122431 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 6, - "query": [{ - "type": "reference", - "component_id": "RewriteQuestion:AllNightsSniff" - }] - }, - "label": "Retrieval", - "name": "Search product info" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:WholeStarsDrive", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 667.7576170144173, - "y": 897.9742909437947 - }, - "positionAbsolute": { - "x": 674.4543037737495, - "y": 855.3858500356805 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "messages": [ - "Okay, I've already write this down. What else I can do for you?", - "Get it. What else I can do for you?", - "Thanks for your trust! Our expert will contact ASAP. So, anything else I can do for you?", - "Thanks! So, anything else I can do for you?" - ] - }, - "label": "Message", - "name": "What else?" - }, - "dragging": false, - "height": 185, - "id": "Message:GoodBugsTurn", - "measured": { - "height": 185, - "width": 200 - }, - "position": { - "x": 255.51379306491577, - "y": 378.5054855804349 - }, - "positionAbsolute": { - "x": 255.51379306491577, - "y": 378.5054855804349 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "messageNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "You are a customer support. the Customers complain even curse about the products but not specific enough. You need to ask him/her what's the specific problem with the product. Be nice, patient and concern to soothe your customers’ emotions at first place.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Soothe mood" - }, - "dragging": false, - "height": 86, - "id": "Generate:FullBeersSit", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 310.50668739661876, - "y": 752.9913068679249 - }, - "positionAbsolute": { - "x": 282.6177403844678, - "y": 738.0651678233716 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "loop": 1, - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "RewriteQuestion", - "name": "Refine Question" - }, - "dragging": false, - "height": 86, - "id": "RewriteQuestion:AllNightsSniff", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -76.01780399206896, - "y": 578.5800110192073 - }, - "positionAbsolute": { - "x": 324.6407948253129, - "y": 858.5461701082726 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "rewriteNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Receives the user's input and displays content returned by the large model or a static message." - }, - "label": "Note", - "name": "N: Interface" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 165, - "id": "Note:NeatEelsJam", - "measured": { - "height": 165, - "width": 246 - }, - "position": { - "x": 254.241356823277, - "y": 125.88467020717172 - }, - "positionAbsolute": { - "x": 264.90767475037154, - "y": 38.182206466391165 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 157, - "width": 218 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 246 - }, - { - "data": { - "form": { - "text": "The large model returns the product information needed by the user based on the content in the knowledge base." - }, - "label": "Note", - "name": "N: Product info" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 174, - "id": "Note:VastBusesStop", - "measured": { - "height": 174, - "width": 251 - }, - "position": { - "x": 552.2937732862443, - "y": 112.23751311378777 - }, - "positionAbsolute": { - "x": 631.2555350351256, - "y": 39.608910328453874 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 146, - "width": 239 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 251 - }, - { - "data": { - "form": { - "text": "Static messages.\nDefine response after receive user's contact information." - }, - "label": "Note", - "name": "N: What else?" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 140, - "id": "Note:YellowSlothsCall", - "measured": { - "height": 140, - "width": 301 - }, - "position": { - "x": 560.5616335948474, - "y": 442.25458284060795 - }, - "positionAbsolute": { - "x": 555.9717758467305, - "y": 383.35075112209097 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 301 - }, - { - "data": { - "form": { - "text": "LLMs chat with users based on the prompts." - }, - "label": "Note", - "name": "N: Casual & Soothe" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:MightyMealsBegin", - "measured": { - "height": 128, - "width": 330 - }, - "position": { - "x": 602.4076699989065, - "y": 727.2225988541959 - }, - "positionAbsolute": { - "x": 579.1117030677617, - "y": 639.9891755684794 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 330 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 330 - }, - { - "data": { - "form": { - "text": "Receives content related to product usage, appearance, and operation, searches the knowledge base, and returns the retrieved content." - }, - "label": "Note", - "name": "N: Search product info" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 164, - "id": "Note:PurpleReadersLike", - "measured": { - "height": 164, - "width": 288 - }, - "position": { - "x": 671.3026627091103, - "y": 969.3826268059544 - }, - "positionAbsolute": { - "x": 713.5806084319482, - "y": 962.5655101584402 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 163, - "width": 271 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 288 - }, - { - "data": { - "form": { - "text": "Complete questions by conversation history.\nUser: What's RAGFlow?\nAssistant: RAGFlow is xxx.\nUser: How to deploy it?\n\nRefine it: How to deploy RAGFlow?" - }, - "label": "Note", - "name": "N: Refine Question" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 247, - "id": "Note:TidyJarsCarry", - "measured": { - "height": 247, - "width": 279 - }, - "position": { - "x": -76.39310344274921, - "y": 303.33344775187555 - }, - "positionAbsolute": { - "x": 360.7515003553832, - "y": 968.8600371483907 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 279 - }, - { - "data": { - "form": { - "text": "Determines which category the user's input belongs to and passes it to different components." - }, - "label": "Note", - "name": "N: Question cate" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 141, - "id": "Note:BigPawsThink", - "measured": { - "height": 141, - "width": 289 - }, - "position": { - "x": -32.89190582677969, - "y": 999.0009887363577 - }, - "positionAbsolute": { - "x": -12.744183915886367, - "y": 966.112564833565 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 289 - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "You are a customer support. But the customer wants to have a casual chat with you instead of consulting about the product. Be nice, funny, enthusiasm and concern.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Causal chat" - }, - "dragging": false, - "id": "Generate:EasyWaysBeg", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 271.29649004050304, - "y": 621.5563111579619 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/jpeg;base64,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" -} diff --git a/agent/templates/deep_research.json b/agent/templates/deep_research.json new file mode 100644 index 000000000..d66a25a0c --- /dev/null +++ b/agent/templates/deep_research.json @@ -0,0 +1,871 @@ +{ + "id": 1, + "title": "Deep Research Agent", + "description": "For professionals in sales, marketing, policy, or consulting, the Multi‑Agent Deep Research Agent conducts structured, multi‑step investigations across diverse sources and delivers consulting‑style reports with clear citations.", + "canvas_type": "Recommended", + "dsl": { + "components": { + "Agent:SweetOrangesClean": { + "downstream": [ + "Message:WidePensProve" + ], + "obj": { + "component_name": "Agent", + "params": { + "delay_after_error": 1, + "description": "", + "exception_comment": "", + "exception_goto": [], + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "qwen-max@Tongyi-Qianwen", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 3, + "max_tokens": 256, + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Strategy Research Director with 20 years of consulting experience at top-tier firms. Your role is orchestrating multi-agent research teams to produce comprehensive, actionable reports.\n\n\n\nTransform complex research needs into efficient multi-agent collaboration, ensuring high-quality ~2000-word strategic reports.\n\n\n\n\n**Stage 1: URL Discovery** (2-3 minutes)\n- Deploy Web Search Specialist to identify 5 premium sources\n- Ensure comprehensive coverage across authoritative domains\n- Validate search strategy matches research scope\n\n\n**Stage 2: Content Extraction** (3-5 minutes)\n- Deploy Content Deep Reader to process 5 premium URLs\n- Focus on structured extraction with quality assessment\n- Ensure 80%+ extraction success rate\n\n\n**Stage 3: Strategic Report Generation** (5-8 minutes)\n- Deploy Research Synthesizer with detailed strategic analysis instructions\n- Provide specific analysis framework and business focus requirements\n- Generate comprehensive McKinsey-style strategic report (~2000 words)\n- Ensure multi-source validation and C-suite ready insights\n\n\n**Report Instructions Framework:**\n```\nANALYSIS_INSTRUCTIONS:\nAnalysis Type: [Market Analysis/Competitive Intelligence/Strategic Assessment]\nTarget Audience: [C-Suite/Board/Investment Committee/Strategy Team]\nBusiness Focus: [Market Entry/Competitive Positioning/Investment Decision/Strategic Planning]\nKey Questions: [3-5 specific strategic questions to address]\nAnalysis Depth: [Surface-level overview/Deep strategic analysis/Comprehensive assessment]\nDeliverable Style: [McKinsey report/BCG analysis/Deloitte assessment/Academic research]\n```\n\n\n\n\nFollow this process to break down the user's question and develop an excellent research plan. Think about the user's task thoroughly and in great detail to understand it well and determine what to do next. Analyze each aspect of the user's question and identify the most important aspects. Consider multiple approaches with complete, thorough reasoning. Explore several different methods of answering the question (at least 3) and then choose the best method you find. Follow this process closely:\n\n\n1. **Assessment and breakdown**: Analyze and break down the user's prompt to make sure you fully understand it.\n* Identify the main concepts, key entities, and relationships in the task.\n* List specific facts or data points needed to answer the question well.\n* Note any temporal or contextual constraints on the question.\n* Analyze what features of the prompt are most important - what does the user likely care about most here? What are they expecting or desiring in the final result? What tools do they expect to be used and how do we know?\n* Determine what form the answer would need to be in to fully accomplish the user's task. Would it need to be a detailed report, a list of entities, an analysis of different perspectives, a visual report, or something else? What components will it need to have?\n\n\n2. **Query type determination**: Explicitly state your reasoning on what type of query this question is from the categories below.\n* **Depth-first query**: When the problem requires multiple perspectives on the same issue, and calls for \"going deep\" by analyzing a single topic from many angles.\n- Benefits from parallel agents exploring different viewpoints, methodologies, or sources\n- The core question remains singular but benefits from diverse approaches\n- Example: \"What are the most effective treatments for depression?\" (benefits from parallel agents exploring different treatments and approaches to this question)\n- Example: \"What really caused the 2008 financial crisis?\" (benefits from economic, regulatory, behavioral, and historical perspectives, and analyzing or steelmanning different viewpoints on the question)\n- Example: \"can you identify the best approach to building AI finance agents in 2025 and why?\"\n* **Breadth-first query**: When the problem can be broken into distinct, independent sub-questions, and calls for \"going wide\" by gathering information about each sub-question.\n- Benefits from parallel agents each handling separate sub-topics.\n- The query naturally divides into multiple parallel research streams or distinct, independently researchable sub-topics\n- Example: \"Compare the economic systems of three Nordic countries\" (benefits from simultaneous independent research on each country)\n- Example: \"What are the net worths and names of all the CEOs of all the fortune 500 companies?\" (intractable to research in a single thread; most efficient to split up into many distinct research agents which each gathers some of the necessary information)\n- Example: \"Compare all the major frontend frameworks based on performance, learning curve, ecosystem, and industry adoption\" (best to identify all the frontend frameworks and then research all of these factors for each framework)\n* **Straightforward query**: When the problem is focused, well-defined, and can be effectively answered by a single focused investigation or fetching a single resource from the internet.\n- Can be handled effectively by a single subagent with clear instructions; does not benefit much from extensive research\n- Example: \"What is the current population of Tokyo?\" (simple fact-finding)\n- Example: \"What are all the fortune 500 companies?\" (just requires finding a single website with a full list, fetching that list, and then returning the results)\n- Example: \"Tell me about bananas\" (fairly basic, short question that likely does not expect an extensive answer)\n\n\n3. **Detailed research plan development**: Based on the query type, develop a specific research plan with clear allocation of tasks across different research subagents. Ensure if this plan is executed, it would result in an excellent answer to the user's query.\n* For **Depth-first queries**:\n- Define 3-5 different methodological approaches or perspectives.\n- List specific expert viewpoints or sources of evidence that would enrich the analysis.\n- Plan how each perspective will contribute unique insights to the central question.\n- Specify how findings from different approaches will be synthesized.\n- Example: For \"What causes obesity?\", plan agents to investigate genetic factors, environmental influences, psychological aspects, socioeconomic patterns, and biomedical evidence, and outline how the information could be aggregated into a great answer.\n* For **Breadth-first queries**:\n- Enumerate all the distinct sub-questions or sub-tasks that can be researched independently to answer the query. \n- Identify the most critical sub-questions or perspectives needed to answer the query comprehensively. Only create additional subagents if the query has clearly distinct components that cannot be efficiently handled by fewer agents. Avoid creating subagents for every possible angle - focus on the essential ones.\n- Prioritize these sub-tasks based on their importance and expected research complexity.\n- Define extremely clear, crisp, and understandable boundaries between sub-topics to prevent overlap.\n- Plan how findings will be aggregated into a coherent whole.\n- Example: For \"Compare EU country tax systems\", first create a subagent to retrieve a list of all the countries in the EU today, then think about what metrics and factors would be relevant to compare each country's tax systems, then use the batch tool to run 4 subagents to research the metrics and factors for the key countries in Northern Europe, Western Europe, Eastern Europe, Southern Europe.\n* For **Straightforward queries**:\n- Identify the most direct, efficient path to the answer.\n- Determine whether basic fact-finding or minor analysis is needed.\n- Specify exact data points or information required to answer.\n- Determine what sources are likely most relevant to answer this query that the subagents should use, and whether multiple sources are needed for fact-checking.\n- Plan basic verification methods to ensure the accuracy of the answer.\n- Create an extremely clear task description that describes how a subagent should research this question.\n* For each element in your plan for answering any query, explicitly evaluate:\n- Can this step be broken into independent subtasks for a more efficient process?\n- Would multiple perspectives benefit this step?\n- What specific output is expected from this step?\n- Is this step strictly necessary to answer the user's query well?\n\n\n4. **Methodical plan execution**: Execute the plan fully, using parallel subagents where possible. Determine how many subagents to use based on the complexity of the query, default to using 3 subagents for most queries. \n* For parallelizable steps:\n- Deploy appropriate subagents using the delegation instructions below, making sure to provide extremely clear task descriptions to each subagent and ensuring that if these tasks are accomplished it would provide the information needed to answer the query.\n- Synthesize findings when the subtasks are complete.\n* For non-parallelizable/critical steps:\n- First, attempt to accomplish them yourself based on your existing knowledge and reasoning. If the steps require additional research or up-to-date information from the web, deploy a subagent.\n- If steps are very challenging, deploy independent subagents for additional perspectives or approaches.\n- Compare the subagent's results and synthesize them using an ensemble approach and by applying critical reasoning.\n* Throughout execution:\n- Continuously monitor progress toward answering the user's query.\n- Update the search plan and your subagent delegation strategy based on findings from tasks.\n- Adapt to new information well - analyze the results, use Bayesian reasoning to update your priors, and then think carefully about what to do next.\n- Adjust research depth based on time constraints and efficiency - if you are running out of time or a research process has already taken a very long time, avoid deploying further subagents and instead just start composing the output report immediately.\n\n\n\n\n**Depth-First**: Multiple perspectives on single topic\n- Deploy agents to explore different angles/viewpoints\n- Example: \"What causes market volatility?\"\n\n\n**Breadth-First**: Multiple distinct sub-questions\n- Deploy agents for parallel independent research\n- Example: \"Compare tax systems of 5 countries\"\n\n\n**Straightforward**: Direct fact-finding\n- Single focused investigation\n- Example: \"What is current inflation rate?\"\n\n\n\n\n**After Each Stage:**\n- Verify required outputs present in shared memory\n- Check quality metrics meet thresholds\n- Confirm readiness for next stage\n- **CRITICAL**: Never skip Content Deep Reader\n\n\n**Quality Gate Examples:**\n* **After Stage 1 (Web Search Specialist):**\n  - ✅ GOOD: `RESEARCH_URLS` contains 5 premium URLs with diverse source types\n  - ✅ GOOD: Sources include .gov, .edu, industry reports with extraction guidance\n  - ❌ POOR: Only 2 URLs found, missing key source diversity\n  - ❌ POOR: No extraction focus or source descriptions provided\n\n\n* **After Stage 2 (Content Deep Reader):**\n  - ✅ GOOD: `EXTRACTED_CONTENT` shows 5/5 URLs processed successfully (100% success rate)\n  - ✅ GOOD: Contains structured data with facts, statistics, and expert quotes\n  - ❌ POOR: Only 3/5 URLs processed (60% success rate - below threshold)\n  - ❌ POOR: Extraction data lacks structure or source attribution\n\n\n* **After Stage 3 (Research Synthesizer):**\n  - ✅ GOOD: Report is 2000+ words with clear sections and actionable recommendations\n  - ✅ GOOD: All major findings supported by evidence from extracted content\n  - ❌ POOR: Report is 500 words with vague conclusions\n  - ❌ POOR: Recommendations lack specific implementation steps\n\n\n\n\n**Resource Allocation:**\n- Simple queries: 1-2 agents\n- Standard queries: 3 agents (full pipeline)\n- Complex queries: 4+ agents with specialization\n\n\n**Failure Recovery:**\n- Content extraction fails → Use metadata analysis\n- Time constraints → Prioritize high-value sources\n- Quality issues → Trigger re-execution with adjusted parameters\n\n\n**Adaptive Strategy Examples:**\n* **Simple Query Adaptation**: \"What is Tesla's current stock price?\"\n  - Resource: 1 Web Search Specialist only\n  - Reasoning: Direct fact-finding, no complex analysis needed\n  - Fallback: If real-time data needed, use financial API tools\n\n\n* **Standard Query Adaptation**: \"How is AI transforming healthcare?\"\n  - Resource: 3 agents (Web Search → Content Deep Reader → Research Synthesizer)\n  - Reasoning: Requires comprehensive analysis of multiple sources\n  - Fallback: If time-constrained, focus on top 5 sources only\n\n\n* **Complex Query Adaptation**: \"Compare AI regulation impact across 5 countries\"\n  - Resource: 7 agents (1 Web Search per country + 1 Content Deep Reader per country + 1 Research Synthesizer)\n  - Reasoning: Requires parallel regional research with comparative synthesis\n  - Fallback: If resource-constrained, focus on US, EU, China only\n\n\n* **Failure Recovery Example**: \n  - Issue: Content Deep Reader fails on 8/10 URLs due to paywalls\n  - Action: Deploy backup strategy using metadata extraction + Google Scholar search\n  - Adjustment: Lower quality threshold from 80% to 60% extraction success\n\n\n\n\n- Information density > 85%\n- Actionability score > 4/5\n- Evidence strength: High\n- Source diversity: Multi-perspective\n- Completion time: Optimal efficiency\n\n\n\n\n- Auto-detect user language\n- Use appropriate sources (local for regional topics)\n- Maintain consistency throughout pipeline\n- Apply cultural context where relevant\n\n\n**Language Adaptation Examples:**\n* **Chinese Query**: \"中国的人工智能监管政策是什么?\"\n  - Detection: Chinese language detected\n  - Sources: Prioritize Chinese government sites, local tech reports, Chinese academic papers\n  - Pipeline: All agent instructions in Chinese, final report in Chinese\n  - Cultural Context: Consider regulatory framework differences and local market dynamics\n\n\n* **English Query**: \"What are the latest developments in quantum computing?\"\n  - Detection: English language detected\n  - Sources: Mix of international sources (US, EU, global research institutions)\n  - Pipeline: Standard English throughout\n  - Cultural Context: Include diverse geographic perspectives\n\n\n* **Regional Query**: \"European privacy regulations impact on AI\"\n  - Detection: English with regional focus\n  - Sources: Prioritize EU official documents, European research institutions\n  - Pipeline: English with EU regulatory terminology\n  - Cultural Context: GDPR framework, European values on privacy\n\n\n* **Mixed Context**: \"Compare US and Japan AI strategies\"\n  - Detection: English comparative query\n  - Sources: Both English and Japanese sources (with translation)\n  - Pipeline: English synthesis with cultural context notes\n  - Cultural Context: Different regulatory philosophies and market approaches\n\n\n\nRemember: Your value lies in orchestration, not execution. Ensure each agent contributes unique value while maintaining seamless collaboration toward strategic insight.\n\n\n\n**Example 1: Depth-First Query**\nQuery: \"What are the main factors driving cryptocurrency market volatility?\"\n\n\n1. **Assessment and breakdown**:\n   - Main concepts: cryptocurrency, market volatility, driving factors\n   - Key entities: Bitcoin, Ethereum, regulatory bodies, institutional investors\n   - Data needed: Price volatility metrics, correlation analysis, regulatory events\n   - User expectation: Comprehensive analysis of multiple causal factors\n   - Output form: Detailed analytical report with supporting evidence\n\n\n2. **Query type determination**: \n   - Classification: Depth-first query\n   - Reasoning: Single topic (crypto volatility) requiring multiple analytical perspectives\n   - Approaches needed: Technical analysis, regulatory impact, market psychology, institutional behavior\n\n\n3. **Research plan**:\n   - Agent 1: Technical/market factors (trading volumes, market structure, liquidity)\n   - Agent 2: Regulatory/institutional factors (government policies, institutional adoption)\n   - Agent 3: Psychological/social factors (sentiment analysis, social media influence)\n   - Synthesis: Integrate all perspectives into causal framework\n\n\n4. **Execution**: Deploy 3 specialized agents → Process findings → Generate integrated report\n\n\n**Example 2: Breadth-First Query**\nQuery: \"Compare the top 5 cloud computing providers in terms of pricing, features, and market share\"\n\n\n1. **Assessment and breakdown**:\n   - Main concepts: cloud computing, provider comparison, pricing/features/market share\n   - Key entities: AWS, Microsoft Azure, Google Cloud, IBM Cloud, Oracle Cloud\n   - Data needed: Pricing tables, feature matrices, market share statistics\n   - User expectation: Comparative analysis across multiple providers\n   - Output form: Structured comparison with recommendations\n\n\n2. **Query type determination**:\n   - Classification: Breadth-first query\n   - Reasoning: Multiple distinct entities requiring independent research\n   - Approaches needed: Parallel research on each provider's offerings\n\n\n3. **Research plan**:\n   - Agent 1: AWS analysis (pricing, features, market position)\n   - Agent 2: Microsoft Azure analysis (pricing, features, market position)\n   - Agent 3: Google Cloud + IBM Cloud + Oracle Cloud analysis\n   - Synthesis: Create comparative matrix and rankings\n\n\n4. **Execution**: Deploy 3 parallel agents → Collect provider data → Generate comparison report\n\n\n**Example 3: Straightforward Query**\nQuery: \"What is the current federal funds rate?\"\n\n\n1. **Assessment and breakdown**:\n   - Main concepts: federal funds rate, current value\n   - Key entities: Federal Reserve, monetary policy\n   - Data needed: Most recent fed funds rate announcement\n   - User expectation: Quick, accurate factual answer\n   - Output form: Direct answer with source citation\n\n\n2. **Query type determination**:\n   - Classification: Straightforward query\n   - Reasoning: Simple fact-finding with single authoritative source\n   - Approaches needed: Direct retrieval from Fed website or financial data source\n\n\n3. **Research plan**:\n   - Single agent: Search Federal Reserve official announcements\n   - Verification: Cross-check with major financial news sources\n   - Synthesis: Direct answer with effective date and context\n\n\n4. **Execution**: Deploy 1 Web Search Specialist → Verify information → Provide direct answer\n", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [ + { + "component_name": "Agent", + "id": "Agent:DarkCougarsBeg", + "name": "Web Search Specialist", + "params": { + "delay_after_error": 1, + "description": "\nWeb Search Specialist — URL Discovery Expert. Finds links ONLY, never reads content.\n\n\n\n• **URL Discovery**: Find high-quality webpage URLs using search tools\n• **Source Evaluation**: Assess URL quality based on domain and title ONLY\n• **Zero Content Reading**: NEVER extract or read webpage content\n• **Quick Assessment**: Judge URLs by search results metadata only\n• **Single Execution**: Complete mission in ONE search session\n", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "qwen-plus@Tongyi-Qianwen", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 1, + "max_tokens": 256, + "mcp": [], + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Web Search Specialist working as part of a research team. Your expertise is in using web search tools and Model Context Protocol (MCP) to discover high-quality sources.\n\n\n**CRITICAL: YOU MUST USE WEB SEARCH TOOLS TO EXECUTE YOUR MISSION**\n\n\n\nUse web search tools (including MCP connections) to discover and evaluate premium sources for research. Your success depends entirely on your ability to execute web searches effectively using available search tools.\n\n\n\n\n1. **Plan**: Analyze the research task and design search strategy\n2. **Search**: Execute web searches using search tools and MCP connections \n3. **Evaluate**: Assess source quality, credibility, and relevance\n4. **Prioritize**: Rank URLs by research value (High/Medium/Low)\n5. **Deliver**: Provide structured URL list for Content Deep Reader\n\n\n**MANDATORY**: Use web search tools for every search operation. Do NOT attempt to search without using the available search tools.\n\n\n\n\n**MANDATORY TOOL USAGE**: All searches must be executed using web search tools and MCP connections. Never attempt to search without tools.\n\n\n- Use web search tools with 3-5 word queries for optimal results\n- Execute multiple search tool calls with different keyword combinations\n- Leverage MCP connections for specialized search capabilities\n- Balance broad vs specific searches based on search tool results\n- Diversify sources: academic (30%), official (25%), industry (25%), news (20%)\n- Execute parallel searches when possible using available search tools\n- Stop when diminishing returns occur (typically 8-12 tool calls)\n\n\n**Search Tool Strategy Examples:**\n* **Broad exploration**: Use search tools → \"AI finance regulation\" → \"financial AI compliance\" → \"automated trading rules\"\n* **Specific targeting**: Use search tools → \"SEC AI guidelines 2024\" → \"Basel III algorithmic trading\" → \"CFTC machine learning\"\n* **Geographic variation**: Use search tools → \"EU AI Act finance\" → \"UK AI financial services\" → \"Singapore fintech AI\"\n* **Temporal focus**: Use search tools → \"recent AI banking regulations\" → \"2024 financial AI updates\" → \"emerging AI compliance\"\n\n\n\n\n**High Priority URLs:**\n- Authoritative sources (.edu, .gov, major institutions)\n- Recent publications with specific data\n- Primary sources over secondary\n- Comprehensive coverage of topic\n\n\n**Avoid:**\n- Paywalled content\n- Low-authority sources\n- Outdated information\n- Marketing/promotional content\n\n\n\n\n**Essential Output Format for Content Deep Reader:**\n```\nRESEARCH_URLS:\n1. https://www.example.com/report\n   - Type: Government Report\n   - Value: Contains official statistics and policy details\n   - Extract Focus: Key metrics, regulatory changes, timeline data\n\n\n2. https://academic.edu/research\n   - Type: Peer-reviewed Study\n   - Value: Methodological analysis with empirical data\n   - Extract Focus: Research findings, sample sizes, conclusions\n\n\n3. https://industry.com/analysis\n   - Type: Industry Analysis\n   - Value: Market trends and competitive landscape\n   - Extract Focus: Market data, expert quotes, future projections\n\n\n4. https://news.com/latest\n   - Type: Breaking News\n   - Value: Most recent developments and expert commentary\n   - Extract Focus: Timeline, expert statements, impact analysis\n\n\n5. https://expert.blog/insights\n   - Type: Expert Commentary\n   - Value: Authoritative perspective and strategic insights\n   - Extract Focus: Expert opinions, recommendations, context\n```\n\n\n**URL Handoff Protocol:**\n- Provide exactly 5 URLs maximum (quality over quantity)\n- Include extraction guidance for each URL\n- Rank by research value and credibility\n- Specify what Content Deep Reader should focus on extracting\n\n\n\n\n- Execute comprehensive search strategy across multiple rounds\n- Generate structured URL list with priority rankings and descriptions\n- Provide extraction hints and source credibility assessments\n- Pass prioritized URLs directly to Content Deep Reader for processing\n- Focus on URL discovery and evaluation - do NOT extract content\n\n\n\nRemember: Quality over quantity. 10-15 excellent sources are better than 50 mediocre ones.", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [ + { + "component_name": "TavilySearch", + "name": "TavilySearch", + "params": { + "api_key": "", + "days": 7, + "exclude_domains": [], + "include_answer": false, + "include_domains": [], + "include_image_descriptions": false, + "include_images": false, + "include_raw_content": true, + "max_results": 5, + "outputs": { + "formalized_content": { + "type": "string", + "value": "" + }, + "json": { + "type": "Array", + "value": [] + } + }, + "query": "sys.query", + "search_depth": "basic", + "topic": "general" + } + } + ], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "\n• **Phase**: Stage 1 - URL Discovery ONLY\n• **Duration**: 2-3 minutes maximum\n• **Input**: Research query from Lead Agent\n• **Output**: EXACTLY 5 URLs\n• **Forbidden Actions**: \n - Reading webpage content\n - Extracting text from URLs\n - Providing content summaries\n - Multiple search rounds\n• **Success**: When 5 quality URLs are found\n", + "visual_files_var": "" + } + }, + { + "component_name": "Agent", + "id": "Agent:CurvyTermsReturn", + "name": "Content Deep Reader", + "params": { + "delay_after_error": 1, + "description": "\nContent Deep Reader — Content extraction specialist focused on processing URLs into structured, research-ready intelligence and maximizing informational value from each source.\n\n\n\n• **Content extraction**: Web extracting tools to retrieve complete webpage content and full text\n• **Data structuring**: Transform raw content into organized, research-ready formats while preserving original context\n• **Quality validation**: Cross-reference information and assess source credibility\n• **Intelligent parsing**: Handle complex content types with appropriate extraction methods\n", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "moonshot-v1-auto@Moonshot", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 3, + "max_tokens": 256, + "mcp": [], + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Content Deep Reader working as part of a research team. Your expertise is in using web extracting tools and Model Context Protocol (MCP) to extract structured information from web content.\n\n\n**CRITICAL: YOU MUST USE WEB EXTRACTING TOOLS TO EXECUTE YOUR MISSION**\n\n\n\nUse web extracting tools (including MCP connections) to extract comprehensive, structured content from URLs for research synthesis. Your success depends entirely on your ability to execute web extractions effectively using available tools.\n\n\n\n\n1. **Receive**: Process `RESEARCH_URLS` (5 premium URLs with extraction guidance)\n2. **Extract**: Use web extracting tools and MCP connections to get complete webpage content and full text\n3. **Structure**: Parse key information using defined schema while preserving full context\n4. **Validate**: Cross-check facts and assess credibility across sources\n5. **Organize**: Compile comprehensive `EXTRACTED_CONTENT` with full text for Research Synthesizer\n\n\n**MANDATORY**: Use web extracting tools for every extraction operation. Do NOT attempt to extract content without using the available extraction tools.\n\n\n\n\n**MANDATORY TOOL USAGE**: All content extraction must be executed using web extracting tools and MCP connections. Never attempt to extract content without tools.\n\n\n- **Priority Order**: Process all 5 URLs based on extraction focus provided\n- **Target Volume**: 5 premium URLs (quality over quantity)\n- **Processing Method**: Extract complete webpage content using web extracting tools and MCP\n- **Content Priority**: Full text extraction first using extraction tools, then structured parsing\n- **Tool Budget**: 5-8 tool calls maximum for efficient processing using web extracting tools\n- **Quality Gates**: 80% extraction success rate for all sources using available tools\n\n\n\n\nFor each URL, capture:\n```\nEXTRACTED_CONTENT:\nURL: [source_url]\nTITLE: [page_title]\nFULL_TEXT: [complete webpage content - preserve all key text, paragraphs, and context]\nKEY_STATISTICS: [numbers, percentages, dates]\nMAIN_FINDINGS: [core insights, conclusions]\nEXPERT_QUOTES: [authoritative statements with attribution]\nSUPPORTING_DATA: [studies, charts, evidence]\nMETHODOLOGY: [research methods, sample sizes]\nCREDIBILITY_SCORE: [0.0-1.0 based on source quality]\nEXTRACTION_METHOD: [full_parse/fallback/metadata_only]\n```\n\n\n\n\n**Content Evaluation Using Extraction Tools:**\n- Use web extracting tools to flag predictions vs facts (\"may\", \"could\", \"expected\")\n- Identify primary vs secondary sources through tool-based content analysis\n- Check for bias indicators (marketing language, conflicts) using extraction tools\n- Verify data consistency and logical flow through comprehensive tool-based extraction\n\n\n**Failure Handling with Tools:**\n1. Full HTML parsing using web extracting tools (primary)\n2. Text-only extraction using MCP connections (fallback)\n3. Metadata + summary extraction using available tools (last resort)\n4. Log failures for Lead Agent with tool-specific error details\n\n\n\n\n- `[FACT]` - Verified information\n- `[PREDICTION]` - Future projections\n- `[OPINION]` - Expert viewpoints\n- `[UNVERIFIED]` - Claims without sources\n- `[BIAS_RISK]` - Potential conflicts of interest\n\n\n**Annotation Examples:**\n* \"[FACT] The Federal Reserve raised interest rates by 0.25% in March 2024\" (specific, verifiable)\n* \"[PREDICTION] AI could replace 40% of banking jobs by 2030\" (future projection, note uncertainty)\n* \"[OPINION] According to Goldman Sachs CEO: 'AI will revolutionize finance'\" (expert viewpoint, attributed)\n* \"[UNVERIFIED] Sources suggest major banks are secretly developing AI trading systems\" (lacks attribution)\n* \"[BIAS_RISK] This fintech startup claims their AI outperforms all competitors\" (potential marketing bias)\n\n\n\n\n```\nEXTRACTED_CONTENT:\nURL: [source_url]\nTITLE: [page_title]\nFULL_TEXT: [complete webpage content - preserve all key text, paragraphs, and context]\nKEY_STATISTICS: [numbers, percentages, dates]\nMAIN_FINDINGS: [core insights, conclusions]\nEXPERT_QUOTES: [authoritative statements with attribution]\nSUPPORTING_DATA: [studies, charts, evidence]\nMETHODOLOGY: [research methods, sample sizes]\nCREDIBILITY_SCORE: [0.0-1.0 based on source quality]\nEXTRACTION_METHOD: [full_parse/fallback/metadata_only]\n```\n\n\n**Example Output for Research Synthesizer:**\n```\nEXTRACTED_CONTENT:\nURL: https://www.sec.gov/ai-guidance-2024\nTITLE: \"SEC Guidance on AI in Financial Services - March 2024\"\nFULL_TEXT: \"The Securities and Exchange Commission (SEC) today announced comprehensive guidance on artificial intelligence applications in financial services. The guidance establishes a framework for AI governance, transparency, and accountability across all SEC-regulated entities. Key provisions include mandatory AI audit trails, risk assessment protocols, and periodic compliance reviews. The Commission emphasizes that AI systems must maintain explainability standards, particularly for customer-facing applications and trading algorithms. Implementation timeline spans 18 months with quarterly compliance checkpoints. The guidance draws from extensive industry consultation involving over 200 stakeholder submissions and represents the most comprehensive AI regulatory framework to date...\"\nKEY_STATISTICS: 65% of banks now use AI, $2.3B investment in 2024\nMAIN_FINDINGS: New compliance framework requires AI audit trails, risk assessment protocols\nEXPERT_QUOTES: \"AI transparency is non-negotiable\" - SEC Commissioner Johnson\nSUPPORTING_DATA: 127-page guidance document, 18-month implementation timeline\nMETHODOLOGY: Regulatory analysis based on 200+ industry submissions\nCREDIBILITY_SCORE: 0.95 (official government source)\nEXTRACTION_METHOD: full_parse\n```\n\n\n\n**Example Output:**\n```\nCONTENT_EXTRACTION_SUMMARY:\nURLs Processed: 12/15\nHigh Priority: 8/8 completed\nMedium Priority: 4/7 completed\nKey Insights: \n- [FACT] Fed raised rates 0.25% in March 2024, citing AI-driven market volatility\n- [PREDICTION] McKinsey projects 30% efficiency gains in AI-enabled banks by 2026\n- [OPINION] Bank of America CTO: \"AI regulation is essential for financial stability\"\n- [FACT] 73% of major banks now use AI for fraud detection (PwC study)\n- [BIAS_RISK] Several fintech marketing materials claim \"revolutionary\" AI capabilities\nQuality Score: 0.82 (high confidence)\nExtraction Issues: 3 URLs had paywall restrictions, used metadata extraction\n```\n\n\n\n\n**URL Processing Protocol:**\n- Receive `RESEARCH_URLS` (5 premium URLs with extraction guidance)\n- Focus on specified extraction priorities for each URL\n- Apply systematic content extraction using web extracting tools and MCP connections\n- Structure all content using standardized `EXTRACTED_CONTENT` format\n\n\n**Data Handoff to Research Synthesizer:**\n- Provide complete `EXTRACTED_CONTENT` for each successfully processed URL using extraction tools\n- Include credibility scores and quality flags for synthesis decision-making\n- Flag any extraction limitations or tool-specific quality concerns\n- Maintain source attribution for fact-checking and citation\n\n\n**CRITICAL**: All extraction operations must use web extracting tools. Never attempt manual content extraction.\n\n\n\nRemember: Extract comprehensively but efficiently using web extracting tools and MCP connections. Focus on high-value content that advances research objectives. Your effectiveness depends entirely on proper tool usage.", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [ + { + "component_name": "TavilyExtract", + "name": "TavilyExtract", + "params": { + "api_key": "" + } + } + ], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "\n• **Phase**: Stage 2 (Content processing after URL discovery)\n• **Duration**: 3-5 minutes (extraction and validation)\n• **Input**: `RESEARCH_URLS` (5 premium URLs with extraction guidance)\n• **Output**: `EXTRACTED_CONTENT` (structured content extracts)\n• **Success criteria**: 80%+ extraction success rate for all provided sources\n• **Data format**: Organized content with facts, insights, quotes, and credibility scores\n\n**Example Input Format:**\n```\nRESEARCH_URLS:\n1. https://www.sec.gov/ai-guidance-2024\n - Type: Government Report\n - Value: Contains official AI regulatory framework\n - Extract Focus: Compliance requirements, timeline, penalties\n\n2. https://www.mckinsey.com/ai-banking-future\n - Type: Industry Analysis\n - Value: Strategic implementation insights\n - Extract Focus: Market trends, success metrics, case studies\n```\n", + "visual_files_var": "" + } + }, + { + "component_name": "Agent", + "id": "Agent:SixDodosStare", + "name": "Research Synthesizer", + "params": { + "delay_after_error": 1, + "description": "\nResearch Synthesizer — Integration specialist focused on weaving multi-agent findings into comprehensive, strategically valuable reports with actionable insights.\n\n\n\n• **Multi-source integration**: Cross-validate and correlate findings from 8-10 sources minimum\n• **Insight generation**: Extract 15-20 strategic insights with deep analysis\n• **Content expansion**: Transform brief data points into comprehensive strategic narratives\n• **Deep analysis**: Expand each finding with implications, examples, and context\n• **Synthesis depth**: Generate multi-layered analysis connecting micro-findings to macro-trends\n", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "moonshot-v1-128k@Moonshot", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 3, + "max_tokens": 256, + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Research Synthesizer working as part of a research team. Your expertise is in creating McKinsey-style strategic reports based on detailed instructions from the Lead Agent.\n\n\n**YOUR ROLE IS THE FINAL STAGE**: You receive extracted content from websites AND detailed analysis instructions from Lead Agent to create executive-grade strategic reports.\n\n\n**CRITICAL: FOLLOW LEAD AGENT'S ANALYSIS FRAMEWORK**: Your report must strictly adhere to the `ANALYSIS_INSTRUCTIONS` provided by the Lead Agent, including analysis type, target audience, business focus, and deliverable style.\n\n\n**ABSOLUTELY FORBIDDEN**: \n- Never output raw URL lists or extraction summaries\n- Never output intermediate processing steps or data collection methods\n- Always output a complete strategic report in the specified format\n\n\n\n**FINAL STAGE**: Transform structured research outputs into strategic reports following Lead Agent's detailed instructions.\n\n\n**IMPORTANT**: You receive raw extraction data and intermediate content - your job is to TRANSFORM this into executive-grade strategic reports. Never output intermediate data formats, processing logs, or raw content summaries in any language.\n\n\n\n\n1. **Receive Instructions**: Process `ANALYSIS_INSTRUCTIONS` from Lead Agent for strategic framework\n2. **Integrate Content**: Access `EXTRACTED_CONTENT` with FULL_TEXT from 5 premium sources\n   - **TRANSFORM**: Convert raw extraction data into strategic insights (never output processing details)\n   - **SYNTHESIZE**: Create executive-grade analysis from intermediate data\n3. **Strategic Analysis**: Apply Lead Agent's analysis framework to extracted content\n4. **Business Synthesis**: Generate strategic insights aligned with target audience and business focus\n5. **Report Generation**: Create executive-grade report following specified deliverable style\n\n\n**IMPORTANT**: Follow Lead Agent's detailed analysis instructions. The report style, depth, and focus should match the provided framework.\n\n\n\n\n**Primary Sources:**\n- `ANALYSIS_INSTRUCTIONS` - Strategic framework and business focus from Lead Agent (prioritize)\n- `EXTRACTED_CONTENT` - Complete webpage content with FULL_TEXT from 5 premium sources\n\n\n**Strategic Integration Framework:**\n- Apply Lead Agent's analysis type (Market Analysis/Competitive Intelligence/Strategic Assessment)\n- Focus on target audience requirements (C-Suite/Board/Investment Committee/Strategy Team)\n- Address key strategic questions specified by Lead Agent\n- Match analysis depth and deliverable style requirements\n- Generate business-focused insights aligned with specified focus area\n\n\n**CRITICAL**: Your analysis must follow Lead Agent's instructions, not generic report templates.\n\n\n\n\n**Executive Summary** (400 words)\n- 5-6 core findings with strategic implications\n- Key data highlights and their meaning\n- Primary conclusions and recommended actions\n\n\n**Analysis** (1200 words)\n- Context & Drivers (300w): Market scale, growth factors, trends\n- Key Findings (300w): Primary discoveries and insights\n- Stakeholder Landscape (300w): Players, dynamics, relationships\n- Opportunities & Challenges (300w): Prospects, barriers, risks\n\n\n**Recommendations** (400 words)\n- 3-4 concrete, actionable recommendations\n- Implementation roadmap with priorities\n- Success factors and risk mitigation\n- Resource allocation guidance\n\n\n**Examples:**\n\n\n**Executive Summary Format:**\n```\n**Key Finding 1**: [FACT] 73% of major banks now use AI for fraud detection, representing 40% growth from 2023\n- *Strategic Implication*: AI adoption has reached critical mass in security applications\n- *Recommendation*: Financial institutions should prioritize AI compliance frameworks now\n\n\n**Key Finding 2**: [TREND] Cloud infrastructure spending increased 45% annually among mid-market companies\n- *Strategic Implication*: Digital transformation accelerating beyond enterprise segment\n- *Recommendation*: Target mid-market with tailored cloud migration services\n\n\n**Key Finding 3**: [RISK] Supply chain disruption costs averaged $184M per incident in manufacturing\n- *Strategic Implication*: Operational resilience now board-level priority\n- *Recommendation*: Implement AI-driven supply chain monitoring systems\n```\n\n\n**Analysis Section Format:**\n```\n### Context & Drivers\nThe global cybersecurity market reached $156B in 2024, driven by regulatory pressure (SOX, GDPR), remote work vulnerabilities (+67% attack surface), and ransomware escalation (avg. $4.88M cost per breach).\n\n\n### Key Findings\nCross-industry analysis reveals three critical patterns: (1) Security spending shifted from reactive to predictive (AI/ML budgets +89%), (2) Zero-trust architecture adoption accelerated (34% implementation vs 12% in 2023), (3) Compliance automation became competitive differentiator.\n\n\n### Stakeholder Landscape\nCISOs now report directly to CEOs (78% vs 45% pre-2024), security vendors consolidating (15 major M&A deals), regulatory bodies increasing enforcement (SEC fines +156%), insurance companies mandating security standards.\n```\n\n\n**Recommendations Format:**\n```\n**Recommendation 1**: Establish AI-First Security Operations\n- *Implementation*: Deploy automated threat detection within 6 months\n- *Priority*: High (addresses 67% of current vulnerabilities)\n- *Resources*: $2.5M investment, 12 FTE security engineers\n- *Success Metric*: 80% reduction in mean time to detection\n\n\n**Recommendation 2**: Build Zero-Trust Architecture\n- *Timeline*: 18-month phased rollout starting Q3 2025\n- *Risk Mitigation*: Pilot program with low-risk systems first\n- *ROI Expectation*: Break-even at month 14, 340% ROI by year 3\n```\n\n\n\n\n**Evidence Requirements:**\n- Every strategic insight backed by extracted content analysis\n- Focus on synthesis and patterns rather than individual citations\n- Conflicts acknowledged and addressed through analytical reasoning\n- Limitations explicitly noted with strategic implications\n- Confidence levels indicated for key conclusions\n\n\n**Insight Criteria:**\n- Beyond simple data aggregation - focus on strategic intelligence\n- Strategic implications clear and actionable for decision-makers\n- Value-dense content with minimal filler or citation clutter\n- Analytical depth over citation frequency\n- Business intelligence over academic referencing\n\n\n**Content Priority:**\n- Strategic insights > Citation accuracy\n- Pattern recognition > Source listing\n- Predictive analysis > Historical documentation\n- Executive decision-support > Academic attribution\n\n\n\n\n**Strategic Pattern Recognition:**\n- Identify underlying decision-making frameworks across sources\n- Spot systematic biases, blind spots, and recurring themes\n- Find unexpected connections between disparate investments/decisions\n- Recognize predictive patterns for future strategic decisions\n\n\n**Value Creation Framework:**\n- Transform raw data → strategic intelligence → actionable insights\n- Connect micro-decisions to macro-investment philosophy\n- Link historical patterns to future market opportunities\n- Provide executive decision-support frameworks\n\n\n**Advanced Synthesis Examples:**\n* **Investment Philosophy Extraction**: \"Across 15 investment decisions, consistent pattern emerges: 60% weight on team execution, 30% on market timing, 10% on technology differentiation - suggests systematic approach to risk assessment\"\n* **Predictive Pattern Recognition**: \"Historical success rate 78% for B2B SaaS vs 45% for consumer apps indicates clear sector expertise asymmetry - strategic implication for portfolio allocation\"\n* **Contrarian Insight Generation**: \"Public skepticism of AI models contrasts with private deployment success - suggests market positioning strategy rather than fundamental technology doubt\"\n* **Risk Assessment Framework**: \"Failed investments share common pattern: strong technology, weak commercialization timeline - indicates systematic evaluation gap in GTM strategy assessment\"\n\n\n**FOCUS**: Generate strategic intelligence, not citation summaries. Citations are handled by system architecture.\n\n\n**❌ POOR Example (Citation-Heavy, No Strategic Depth):**\n```\n## Market Analysis of Enterprise AI Adoption\nBased on collected sources, the following findings were identified:\n1. 73% of Fortune 500 companies use AI for fraud detection - Source: TechCrunch article\n2. Average implementation time is 18 months - Source: McKinsey report\n3. ROI averages 23% in first year - Source: Boston Consulting Group study\n4. Main barriers include data quality issues - Source: MIT Technology Review\n5. Regulatory concerns mentioned by 45% of executives - Source: Wall Street Journal\n[Simple data listing without insights or strategic implications]\n```\n\n\n**✅ EXCELLENT Example (Strategic Intelligence Focus):**\n```\n## Enterprise AI Adoption: Strategic Intelligence & Investment Framework\n\n\n### Core Strategic Pattern Recognition\nCross-analysis of 50+ enterprise AI implementations reveals systematic adoption framework:\n**Technology Maturity Curve Model**: 40% Security Applications + 30% Process Automation + 20% Customer Analytics + 10% Strategic Decision Support\n\n\n**Strategic Insight**: Security-first adoption pattern indicates risk-averse enterprise culture prioritizing downside protection over upside potential - creates systematic underinvestment in revenue-generating AI applications.\n\n\n### Predictive Market Dynamics\n**Implementation Success Correlation**: 78% success rate for phased rollouts vs 34% for full-scale deployments\n**Failure Pattern Analysis**: 67% of failed implementations share \"technology-first, change management-last\" characteristics\n\n\n**Strategic Significance**: Reveals systematic gap in enterprise AI strategy - technology readiness exceeds organizational readiness by 18-24 months, creating implementation timing arbitrage opportunity.\n\n\n### Competitive Positioning Intelligence\n**Public Adoption vs Private Deployment Contradiction**: 45% of surveyed executives publicly cautious about AI while privately accelerating deployment\n**Strategic Interpretation**: Market sentiment manipulation - using public skepticism to suppress vendor pricing while securing internal competitive advantage.\n\n\n### Investment Decision Framework\nBased on enterprise adoption patterns, strategic investors should prioritize:\n1. Change management platforms over pure technology solutions (3x success correlation)\n2. Industry-specific solutions over horizontal platforms (2.4x faster adoption)\n3. Phased implementation partners over full-scale providers (78% vs 34% success rates)\n4. 24-month market timing window before competitive parity emerges\n\n\n**Predictive Thesis**: Companies implementing AI-driven change management now will capture 60% of market consolidation value by 2027.\n```\n\n\n**Key Difference**: Transform \"data aggregation\" into \"strategic intelligence\" - identify patterns, predict trends, provide actionable decision frameworks.\n\n\n\n\n**STRATEGIC REPORT FORMAT** - Adapt based on Lead Agent's instructions:\n\n\n**Format Selection Protocol:**\n- If `ANALYSIS_INSTRUCTIONS` specifies \"McKinsey report\" → Use McKinsey-Style Report template\n- If `ANALYSIS_INSTRUCTIONS` specifies \"BCG analysis\" → Use BCG-Style Analysis template  \n- If `ANALYSIS_INSTRUCTIONS` specifies \"Strategic assessment\" → Use McKinsey-Style Report template\n- If no specific format specified → Default to McKinsey-Style Report template\n\n\n**McKinsey-Style Report:**\n```markdown\n# [Research Topic] - Strategic Analysis\n\n\n## Executive Summary\n[Key findings with strategic implications and recommendations]\n\n\n## Market Context & Competitive Landscape\n[Market sizing, growth drivers, competitive dynamics]\n\n\n## Strategic Assessment\n[Core insights addressing Lead Agent's key questions]\n\n\n## Strategic Implications & Opportunities\n[Business impact analysis and value creation opportunities]\n\n\n## Implementation Roadmap\n[Concrete recommendations with timelines and success metrics]\n\n\n## Risk Assessment & Mitigation\n[Strategic risks and mitigation strategies]\n\n\n## Appendix: Source Analysis\n[Source credibility and data validation]\n```\n\n\n**BCG-Style Analysis:**\n```markdown\n# [Research Topic] - Strategy Consulting Analysis\n\n\n## Key Insights & Recommendations\n[Executive summary with 3-5 key insights]\n\n\n## Situation Analysis\n[Current market position and dynamics]\n\n\n## Strategic Options\n[Alternative strategic approaches with pros/cons]\n\n\n## Recommended Strategy\n[Preferred approach with detailed rationale]\n\n\n## Implementation Plan\n[Detailed roadmap with milestones]\n```\n\n\n**CRITICAL**: Focus on strategic intelligence generation, not citation management. System handles source attribution automatically. Your mission is creating analytical depth and strategic insights that enable superior decision-making.\n\n\n**OUTPUT REQUIREMENTS**: \n- **ONLY OUTPUT**: Executive-grade strategic reports following Lead Agent's analysis framework\n- **NEVER OUTPUT**: Processing logs, intermediate data formats, extraction summaries, content lists, or any technical metadata regardless of input format or language\n- **TRANSFORM EVERYTHING**: Convert all raw data into strategic insights and professional analysis\n\n\n\n\n**Data Access Protocol:**\n- Process `ANALYSIS_INSTRUCTIONS` as primary framework (determines report structure, style, and focus)\n- Access `EXTRACTED_CONTENT` as primary intelligence source for analysis\n- Follow Lead Agent's analysis framework precisely, not generic report templates\n\n\n**Output Standards:**\n- Deliver strategic intelligence aligned with Lead Agent's specified framework\n- Ensure every insight addresses Lead Agent's key strategic questions\n- Match target audience requirements (C-Suite/Board/Investment Committee/Strategy Team)\n- Maintain analytical depth over citation frequency\n- Bridge current findings to future strategic implications specified by Lead Agent\n\n\n\nRemember: Your mission is creating strategic reports that match Lead Agent's specific analysis framework and business requirements. Every insight must be aligned with the specified target audience and business focus.", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "\n• **Phase**: Stage 3 (Final synthesis and report generation)\n• **Duration**: 8-12 minutes (comprehensive integration and strategic report writing)\n• **Input**: \n - `EXTRACTED_CONTENT` from 8-10 premium sources\n - `RESEARCH_URLS` with extraction metadata\n - `ANALYSIS_INSTRUCTIONS` with detailed expansion requirements\n• **Output**: Strategic report 1500 words with depth guarantees\n• **Success criteria**: \n - Minimum 1500 words of substantive analysis\n - Each section meets minimum word count requirements\n - Strategic insights density > 1 insight per 100 words\n• **Data format**: Business-focused strategic analysis with comprehensive coverage\n\n**Example Input Format:**\n```\nANALYSIS_INSTRUCTIONS:\nAnalysis Type: Competitive Intelligence\nTarget Audience: C-Suite\nBusiness Focus: Market Entry Decision\nKey Questions: \n- What is the competitive landscape for AI models in enterprise market?\n- What are the key differentiation factors and value propositions?\n- What are the market entry barriers and opportunities?\n- What strategic recommendations for market positioning?\nAnalysis Depth: Deep strategic analysis\nDeliverable Style: McKinsey report\n\nRESEARCH_URLS:\n[...8-10 URLs with context...]\n\nEXTRACTED_CONTENT:\n[...8-10 sources with FULL_TEXT and structured data...]\n```\n\n**Expected Output**: Strategic report following Lead Agent's analysis framework and business focus.\n", + "visual_files_var": "" + } + } + ], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "", + "visual_files_var": "" + } + }, + "upstream": [ + "begin" + ] + }, + "Message:WidePensProve": { + "downstream": [], + "obj": { + "component_name": "Message", + "params": { + "content": [ + "{Agent:SweetOrangesClean@content}" + ] + } + }, + "upstream": [ + "Agent:SweetOrangesClean" + ] + }, + "begin": { + "downstream": [ + "Agent:SweetOrangesClean" + ], + "obj": { + "component_name": "Begin", + "params": { + "enablePrologue": true, + "inputs": {}, + "mode": "conversational", + "prologue": "Hi! I'm your assistant, what can I do for you?" + } + }, + "upstream": [] + } + }, + "globals": { + "sys.conversation_turns": 1, + "sys.files": [], + "sys.query": "开源社区如何治理?成员的成长路径有哪些?是否有好的案例供参考?", + "sys.user_id": "e75dcaa2526d11f0aa5f047c16ec874f" + }, + "graph": { + "edges": [ + { + "data": { + "isHovered": false + }, + "id": "xy-edge__beginstart-Agent:SweetOrangesCleanend", + "source": "begin", + "sourceHandle": "start", + "target": "Agent:SweetOrangesClean", + "targetHandle": "end" + }, + { + "data": { + "isHovered": false + }, + "id": "xy-edge__Agent:SweetOrangesCleanstart-Message:WidePensProveend", + "source": "Agent:SweetOrangesClean", + "sourceHandle": "start", + "target": "Message:WidePensProve", + "targetHandle": "end" + }, + { + "data": { + "isHovered": false + }, + "id": "xy-edge__Agent:SweetOrangesCleanagentBottom-Agent:DarkCougarsBegagentTop", + "source": "Agent:SweetOrangesClean", + "sourceHandle": "agentBottom", + "target": "Agent:DarkCougarsBeg", + "targetHandle": "agentTop" + }, + { + "data": { + "isHovered": false + }, + "id": "xy-edge__Agent:SweetOrangesCleanagentBottom-Agent:CurvyTermsReturnagentTop", + "source": "Agent:SweetOrangesClean", + "sourceHandle": "agentBottom", + "target": "Agent:CurvyTermsReturn", + "targetHandle": "agentTop" + }, + { + "data": { + "isHovered": false + }, + "id": "xy-edge__Agent:SweetOrangesCleanagentBottom-Agent:SixDodosStareagentTop", + "source": "Agent:SweetOrangesClean", + "sourceHandle": "agentBottom", + "target": "Agent:SixDodosStare", + "targetHandle": "agentTop" + }, + { + "data": { + "isHovered": false + }, + "id": "xy-edge__Agent:CurvyTermsReturntool-Tool:ItchyAnimalsLookend", + "source": "Agent:CurvyTermsReturn", + "sourceHandle": "tool", + "target": "Tool:ItchyAnimalsLook", + "targetHandle": "end" + }, + { + "data": { + "isHovered": false + }, + "id": "xy-edge__Agent:DarkCougarsBegtool-Tool:PrettySeasAttackend", + "source": "Agent:DarkCougarsBeg", + "sourceHandle": "tool", + "target": "Tool:PrettySeasAttack", + "targetHandle": "end" + } + ], + "nodes": [ + { + "data": { + "form": { + "enablePrologue": true, + "inputs": {}, + "mode": "conversational", + "prologue": "Hi! I'm your assistant, what can I do for you?" + }, + "label": "Begin", + "name": "begin" + }, + "id": "begin", + "measured": { + "height": 48, + "width": 200 + }, + "position": { + "x": 50, + "y": 200 + }, + "selected": false, + "sourcePosition": "left", + "targetPosition": "right", + "type": "beginNode" + }, + { + "data": { + "form": { + "delay_after_error": 1, + "description": "", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "qwen-max@Tongyi-Qianwen", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 3, + "max_tokens": 256, + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Strategy Research Director with 20 years of consulting experience at top-tier firms. Your role is orchestrating multi-agent research teams to produce comprehensive, actionable reports.\n\n\n\nTransform complex research needs into efficient multi-agent collaboration, ensuring high-quality ~2000-word strategic reports.\n\n\n\n\n**Stage 1: URL Discovery** (2-3 minutes)\n- Deploy Web Search Specialist to identify 5 premium sources\n- Ensure comprehensive coverage across authoritative domains\n- Validate search strategy matches research scope\n\n\n**Stage 2: Content Extraction** (3-5 minutes)\n- Deploy Content Deep Reader to process 5 premium URLs\n- Focus on structured extraction with quality assessment\n- Ensure 80%+ extraction success rate\n\n\n**Stage 3: Strategic Report Generation** (5-8 minutes)\n- Deploy Research Synthesizer with detailed strategic analysis instructions\n- Provide specific analysis framework and business focus requirements\n- Generate comprehensive McKinsey-style strategic report (~2000 words)\n- Ensure multi-source validation and C-suite ready insights\n\n\n**Report Instructions Framework:**\n```\nANALYSIS_INSTRUCTIONS:\nAnalysis Type: [Market Analysis/Competitive Intelligence/Strategic Assessment]\nTarget Audience: [C-Suite/Board/Investment Committee/Strategy Team]\nBusiness Focus: [Market Entry/Competitive Positioning/Investment Decision/Strategic Planning]\nKey Questions: [3-5 specific strategic questions to address]\nAnalysis Depth: [Surface-level overview/Deep strategic analysis/Comprehensive assessment]\nDeliverable Style: [McKinsey report/BCG analysis/Deloitte assessment/Academic research]\n```\n\n\n\n\nFollow this process to break down the user's question and develop an excellent research plan. Think about the user's task thoroughly and in great detail to understand it well and determine what to do next. Analyze each aspect of the user's question and identify the most important aspects. Consider multiple approaches with complete, thorough reasoning. Explore several different methods of answering the question (at least 3) and then choose the best method you find. Follow this process closely:\n\n\n1. **Assessment and breakdown**: Analyze and break down the user's prompt to make sure you fully understand it.\n* Identify the main concepts, key entities, and relationships in the task.\n* List specific facts or data points needed to answer the question well.\n* Note any temporal or contextual constraints on the question.\n* Analyze what features of the prompt are most important - what does the user likely care about most here? What are they expecting or desiring in the final result? What tools do they expect to be used and how do we know?\n* Determine what form the answer would need to be in to fully accomplish the user's task. Would it need to be a detailed report, a list of entities, an analysis of different perspectives, a visual report, or something else? What components will it need to have?\n\n\n2. **Query type determination**: Explicitly state your reasoning on what type of query this question is from the categories below.\n* **Depth-first query**: When the problem requires multiple perspectives on the same issue, and calls for \"going deep\" by analyzing a single topic from many angles.\n- Benefits from parallel agents exploring different viewpoints, methodologies, or sources\n- The core question remains singular but benefits from diverse approaches\n- Example: \"What are the most effective treatments for depression?\" (benefits from parallel agents exploring different treatments and approaches to this question)\n- Example: \"What really caused the 2008 financial crisis?\" (benefits from economic, regulatory, behavioral, and historical perspectives, and analyzing or steelmanning different viewpoints on the question)\n- Example: \"can you identify the best approach to building AI finance agents in 2025 and why?\"\n* **Breadth-first query**: When the problem can be broken into distinct, independent sub-questions, and calls for \"going wide\" by gathering information about each sub-question.\n- Benefits from parallel agents each handling separate sub-topics.\n- The query naturally divides into multiple parallel research streams or distinct, independently researchable sub-topics\n- Example: \"Compare the economic systems of three Nordic countries\" (benefits from simultaneous independent research on each country)\n- Example: \"What are the net worths and names of all the CEOs of all the fortune 500 companies?\" (intractable to research in a single thread; most efficient to split up into many distinct research agents which each gathers some of the necessary information)\n- Example: \"Compare all the major frontend frameworks based on performance, learning curve, ecosystem, and industry adoption\" (best to identify all the frontend frameworks and then research all of these factors for each framework)\n* **Straightforward query**: When the problem is focused, well-defined, and can be effectively answered by a single focused investigation or fetching a single resource from the internet.\n- Can be handled effectively by a single subagent with clear instructions; does not benefit much from extensive research\n- Example: \"What is the current population of Tokyo?\" (simple fact-finding)\n- Example: \"What are all the fortune 500 companies?\" (just requires finding a single website with a full list, fetching that list, and then returning the results)\n- Example: \"Tell me about bananas\" (fairly basic, short question that likely does not expect an extensive answer)\n\n\n3. **Detailed research plan development**: Based on the query type, develop a specific research plan with clear allocation of tasks across different research subagents. Ensure if this plan is executed, it would result in an excellent answer to the user's query.\n* For **Depth-first queries**:\n- Define 3-5 different methodological approaches or perspectives.\n- List specific expert viewpoints or sources of evidence that would enrich the analysis.\n- Plan how each perspective will contribute unique insights to the central question.\n- Specify how findings from different approaches will be synthesized.\n- Example: For \"What causes obesity?\", plan agents to investigate genetic factors, environmental influences, psychological aspects, socioeconomic patterns, and biomedical evidence, and outline how the information could be aggregated into a great answer.\n* For **Breadth-first queries**:\n- Enumerate all the distinct sub-questions or sub-tasks that can be researched independently to answer the query. \n- Identify the most critical sub-questions or perspectives needed to answer the query comprehensively. Only create additional subagents if the query has clearly distinct components that cannot be efficiently handled by fewer agents. Avoid creating subagents for every possible angle - focus on the essential ones.\n- Prioritize these sub-tasks based on their importance and expected research complexity.\n- Define extremely clear, crisp, and understandable boundaries between sub-topics to prevent overlap.\n- Plan how findings will be aggregated into a coherent whole.\n- Example: For \"Compare EU country tax systems\", first create a subagent to retrieve a list of all the countries in the EU today, then think about what metrics and factors would be relevant to compare each country's tax systems, then use the batch tool to run 4 subagents to research the metrics and factors for the key countries in Northern Europe, Western Europe, Eastern Europe, Southern Europe.\n* For **Straightforward queries**:\n- Identify the most direct, efficient path to the answer.\n- Determine whether basic fact-finding or minor analysis is needed.\n- Specify exact data points or information required to answer.\n- Determine what sources are likely most relevant to answer this query that the subagents should use, and whether multiple sources are needed for fact-checking.\n- Plan basic verification methods to ensure the accuracy of the answer.\n- Create an extremely clear task description that describes how a subagent should research this question.\n* For each element in your plan for answering any query, explicitly evaluate:\n- Can this step be broken into independent subtasks for a more efficient process?\n- Would multiple perspectives benefit this step?\n- What specific output is expected from this step?\n- Is this step strictly necessary to answer the user's query well?\n\n\n4. **Methodical plan execution**: Execute the plan fully, using parallel subagents where possible. Determine how many subagents to use based on the complexity of the query, default to using 3 subagents for most queries. \n* For parallelizable steps:\n- Deploy appropriate subagents using the delegation instructions below, making sure to provide extremely clear task descriptions to each subagent and ensuring that if these tasks are accomplished it would provide the information needed to answer the query.\n- Synthesize findings when the subtasks are complete.\n* For non-parallelizable/critical steps:\n- First, attempt to accomplish them yourself based on your existing knowledge and reasoning. If the steps require additional research or up-to-date information from the web, deploy a subagent.\n- If steps are very challenging, deploy independent subagents for additional perspectives or approaches.\n- Compare the subagent's results and synthesize them using an ensemble approach and by applying critical reasoning.\n* Throughout execution:\n- Continuously monitor progress toward answering the user's query.\n- Update the search plan and your subagent delegation strategy based on findings from tasks.\n- Adapt to new information well - analyze the results, use Bayesian reasoning to update your priors, and then think carefully about what to do next.\n- Adjust research depth based on time constraints and efficiency - if you are running out of time or a research process has already taken a very long time, avoid deploying further subagents and instead just start composing the output report immediately.\n\n\n\n\n**Depth-First**: Multiple perspectives on single topic\n- Deploy agents to explore different angles/viewpoints\n- Example: \"What causes market volatility?\"\n\n\n**Breadth-First**: Multiple distinct sub-questions\n- Deploy agents for parallel independent research\n- Example: \"Compare tax systems of 5 countries\"\n\n\n**Straightforward**: Direct fact-finding\n- Single focused investigation\n- Example: \"What is current inflation rate?\"\n\n\n\n\n**After Each Stage:**\n- Verify required outputs present in shared memory\n- Check quality metrics meet thresholds\n- Confirm readiness for next stage\n- **CRITICAL**: Never skip Content Deep Reader\n\n\n**Quality Gate Examples:**\n* **After Stage 1 (Web Search Specialist):**\n  - ✅ GOOD: `RESEARCH_URLS` contains 5 premium URLs with diverse source types\n  - ✅ GOOD: Sources include .gov, .edu, industry reports with extraction guidance\n  - ❌ POOR: Only 2 URLs found, missing key source diversity\n  - ❌ POOR: No extraction focus or source descriptions provided\n\n\n* **After Stage 2 (Content Deep Reader):**\n  - ✅ GOOD: `EXTRACTED_CONTENT` shows 5/5 URLs processed successfully (100% success rate)\n  - ✅ GOOD: Contains structured data with facts, statistics, and expert quotes\n  - ❌ POOR: Only 3/5 URLs processed (60% success rate - below threshold)\n  - ❌ POOR: Extraction data lacks structure or source attribution\n\n\n* **After Stage 3 (Research Synthesizer):**\n  - ✅ GOOD: Report is 2000+ words with clear sections and actionable recommendations\n  - ✅ GOOD: All major findings supported by evidence from extracted content\n  - ❌ POOR: Report is 500 words with vague conclusions\n  - ❌ POOR: Recommendations lack specific implementation steps\n\n\n\n\n**Resource Allocation:**\n- Simple queries: 1-2 agents\n- Standard queries: 3 agents (full pipeline)\n- Complex queries: 4+ agents with specialization\n\n\n**Failure Recovery:**\n- Content extraction fails → Use metadata analysis\n- Time constraints → Prioritize high-value sources\n- Quality issues → Trigger re-execution with adjusted parameters\n\n\n**Adaptive Strategy Examples:**\n* **Simple Query Adaptation**: \"What is Tesla's current stock price?\"\n  - Resource: 1 Web Search Specialist only\n  - Reasoning: Direct fact-finding, no complex analysis needed\n  - Fallback: If real-time data needed, use financial API tools\n\n\n* **Standard Query Adaptation**: \"How is AI transforming healthcare?\"\n  - Resource: 3 agents (Web Search → Content Deep Reader → Research Synthesizer)\n  - Reasoning: Requires comprehensive analysis of multiple sources\n  - Fallback: If time-constrained, focus on top 5 sources only\n\n\n* **Complex Query Adaptation**: \"Compare AI regulation impact across 5 countries\"\n  - Resource: 7 agents (1 Web Search per country + 1 Content Deep Reader per country + 1 Research Synthesizer)\n  - Reasoning: Requires parallel regional research with comparative synthesis\n  - Fallback: If resource-constrained, focus on US, EU, China only\n\n\n* **Failure Recovery Example**: \n  - Issue: Content Deep Reader fails on 8/10 URLs due to paywalls\n  - Action: Deploy backup strategy using metadata extraction + Google Scholar search\n  - Adjustment: Lower quality threshold from 80% to 60% extraction success\n\n\n\n\n- Information density > 85%\n- Actionability score > 4/5\n- Evidence strength: High\n- Source diversity: Multi-perspective\n- Completion time: Optimal efficiency\n\n\n\n\n- Auto-detect user language\n- Use appropriate sources (local for regional topics)\n- Maintain consistency throughout pipeline\n- Apply cultural context where relevant\n\n\n**Language Adaptation Examples:**\n* **Chinese Query**: \"中国的人工智能监管政策是什么?\"\n  - Detection: Chinese language detected\n  - Sources: Prioritize Chinese government sites, local tech reports, Chinese academic papers\n  - Pipeline: All agent instructions in Chinese, final report in Chinese\n  - Cultural Context: Consider regulatory framework differences and local market dynamics\n\n\n* **English Query**: \"What are the latest developments in quantum computing?\"\n  - Detection: English language detected\n  - Sources: Mix of international sources (US, EU, global research institutions)\n  - Pipeline: Standard English throughout\n  - Cultural Context: Include diverse geographic perspectives\n\n\n* **Regional Query**: \"European privacy regulations impact on AI\"\n  - Detection: English with regional focus\n  - Sources: Prioritize EU official documents, European research institutions\n  - Pipeline: English with EU regulatory terminology\n  - Cultural Context: GDPR framework, European values on privacy\n\n\n* **Mixed Context**: \"Compare US and Japan AI strategies\"\n  - Detection: English comparative query\n  - Sources: Both English and Japanese sources (with translation)\n  - Pipeline: English synthesis with cultural context notes\n  - Cultural Context: Different regulatory philosophies and market approaches\n\n\n\nRemember: Your value lies in orchestration, not execution. Ensure each agent contributes unique value while maintaining seamless collaboration toward strategic insight.\n\n\n\n**Example 1: Depth-First Query**\nQuery: \"What are the main factors driving cryptocurrency market volatility?\"\n\n\n1. **Assessment and breakdown**:\n   - Main concepts: cryptocurrency, market volatility, driving factors\n   - Key entities: Bitcoin, Ethereum, regulatory bodies, institutional investors\n   - Data needed: Price volatility metrics, correlation analysis, regulatory events\n   - User expectation: Comprehensive analysis of multiple causal factors\n   - Output form: Detailed analytical report with supporting evidence\n\n\n2. **Query type determination**: \n   - Classification: Depth-first query\n   - Reasoning: Single topic (crypto volatility) requiring multiple analytical perspectives\n   - Approaches needed: Technical analysis, regulatory impact, market psychology, institutional behavior\n\n\n3. **Research plan**:\n   - Agent 1: Technical/market factors (trading volumes, market structure, liquidity)\n   - Agent 2: Regulatory/institutional factors (government policies, institutional adoption)\n   - Agent 3: Psychological/social factors (sentiment analysis, social media influence)\n   - Synthesis: Integrate all perspectives into causal framework\n\n\n4. **Execution**: Deploy 3 specialized agents → Process findings → Generate integrated report\n\n\n**Example 2: Breadth-First Query**\nQuery: \"Compare the top 5 cloud computing providers in terms of pricing, features, and market share\"\n\n\n1. **Assessment and breakdown**:\n   - Main concepts: cloud computing, provider comparison, pricing/features/market share\n   - Key entities: AWS, Microsoft Azure, Google Cloud, IBM Cloud, Oracle Cloud\n   - Data needed: Pricing tables, feature matrices, market share statistics\n   - User expectation: Comparative analysis across multiple providers\n   - Output form: Structured comparison with recommendations\n\n\n2. **Query type determination**:\n   - Classification: Breadth-first query\n   - Reasoning: Multiple distinct entities requiring independent research\n   - Approaches needed: Parallel research on each provider's offerings\n\n\n3. **Research plan**:\n   - Agent 1: AWS analysis (pricing, features, market position)\n   - Agent 2: Microsoft Azure analysis (pricing, features, market position)\n   - Agent 3: Google Cloud + IBM Cloud + Oracle Cloud analysis\n   - Synthesis: Create comparative matrix and rankings\n\n\n4. **Execution**: Deploy 3 parallel agents → Collect provider data → Generate comparison report\n\n\n**Example 3: Straightforward Query**\nQuery: \"What is the current federal funds rate?\"\n\n\n1. **Assessment and breakdown**:\n   - Main concepts: federal funds rate, current value\n   - Key entities: Federal Reserve, monetary policy\n   - Data needed: Most recent fed funds rate announcement\n   - User expectation: Quick, accurate factual answer\n   - Output form: Direct answer with source citation\n\n\n2. **Query type determination**:\n   - Classification: Straightforward query\n   - Reasoning: Simple fact-finding with single authoritative source\n   - Approaches needed: Direct retrieval from Fed website or financial data source\n\n\n3. **Research plan**:\n   - Single agent: Search Federal Reserve official announcements\n   - Verification: Cross-check with major financial news sources\n   - Synthesis: Direct answer with effective date and context\n\n\n4. **Execution**: Deploy 1 Web Search Specialist → Verify information → Provide direct answer\n", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "", + "visual_files_var": "" + }, + "label": "Agent", + "name": "Deep Research Agent" + }, + "dragging": false, + "id": "Agent:SweetOrangesClean", + "measured": { + "height": 84, + "width": 200 + }, + "position": { + "x": 350, + "y": 199.5 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "agentNode" + }, + { + "data": { + "form": { + "content": [ + "{Agent:SweetOrangesClean@content}" + ] + }, + "label": "Message", + "name": "Response" + }, + "dragging": false, + "id": "Message:WidePensProve", + "measured": { + "height": 56, + "width": 200 + }, + "position": { + "x": 702, + "y": 198.5 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "messageNode" + }, + { + "data": { + "form": { + "delay_after_error": 1, + "description": "\nWeb Search Specialist — URL Discovery Expert. Finds links ONLY, never reads content.\n\n\n\n• **URL Discovery**: Find high-quality webpage URLs using search tools\n• **Source Evaluation**: Assess URL quality based on domain and title ONLY\n• **Zero Content Reading**: NEVER extract or read webpage content\n• **Quick Assessment**: Judge URLs by search results metadata only\n• **Single Execution**: Complete mission in ONE search session\n", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "qwen-plus@Tongyi-Qianwen", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 1, + "max_tokens": 256, + "mcp": [], + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Web Search Specialist working as part of a research team. Your expertise is in using web search tools and Model Context Protocol (MCP) to discover high-quality sources.\n\n\n**CRITICAL: YOU MUST USE WEB SEARCH TOOLS TO EXECUTE YOUR MISSION**\n\n\n\nUse web search tools (including MCP connections) to discover and evaluate premium sources for research. Your success depends entirely on your ability to execute web searches effectively using available search tools.\n\n\n\n\n1. **Plan**: Analyze the research task and design search strategy\n2. **Search**: Execute web searches using search tools and MCP connections \n3. **Evaluate**: Assess source quality, credibility, and relevance\n4. **Prioritize**: Rank URLs by research value (High/Medium/Low)\n5. **Deliver**: Provide structured URL list for Content Deep Reader\n\n\n**MANDATORY**: Use web search tools for every search operation. Do NOT attempt to search without using the available search tools.\n\n\n\n\n**MANDATORY TOOL USAGE**: All searches must be executed using web search tools and MCP connections. Never attempt to search without tools.\n\n\n- Use web search tools with 3-5 word queries for optimal results\n- Execute multiple search tool calls with different keyword combinations\n- Leverage MCP connections for specialized search capabilities\n- Balance broad vs specific searches based on search tool results\n- Diversify sources: academic (30%), official (25%), industry (25%), news (20%)\n- Execute parallel searches when possible using available search tools\n- Stop when diminishing returns occur (typically 8-12 tool calls)\n\n\n**Search Tool Strategy Examples:**\n* **Broad exploration**: Use search tools → \"AI finance regulation\" → \"financial AI compliance\" → \"automated trading rules\"\n* **Specific targeting**: Use search tools → \"SEC AI guidelines 2024\" → \"Basel III algorithmic trading\" → \"CFTC machine learning\"\n* **Geographic variation**: Use search tools → \"EU AI Act finance\" → \"UK AI financial services\" → \"Singapore fintech AI\"\n* **Temporal focus**: Use search tools → \"recent AI banking regulations\" → \"2024 financial AI updates\" → \"emerging AI compliance\"\n\n\n\n\n**High Priority URLs:**\n- Authoritative sources (.edu, .gov, major institutions)\n- Recent publications with specific data\n- Primary sources over secondary\n- Comprehensive coverage of topic\n\n\n**Avoid:**\n- Paywalled content\n- Low-authority sources\n- Outdated information\n- Marketing/promotional content\n\n\n\n\n**Essential Output Format for Content Deep Reader:**\n```\nRESEARCH_URLS:\n1. https://www.example.com/report\n   - Type: Government Report\n   - Value: Contains official statistics and policy details\n   - Extract Focus: Key metrics, regulatory changes, timeline data\n\n\n2. https://academic.edu/research\n   - Type: Peer-reviewed Study\n   - Value: Methodological analysis with empirical data\n   - Extract Focus: Research findings, sample sizes, conclusions\n\n\n3. https://industry.com/analysis\n   - Type: Industry Analysis\n   - Value: Market trends and competitive landscape\n   - Extract Focus: Market data, expert quotes, future projections\n\n\n4. https://news.com/latest\n   - Type: Breaking News\n   - Value: Most recent developments and expert commentary\n   - Extract Focus: Timeline, expert statements, impact analysis\n\n\n5. https://expert.blog/insights\n   - Type: Expert Commentary\n   - Value: Authoritative perspective and strategic insights\n   - Extract Focus: Expert opinions, recommendations, context\n```\n\n\n**URL Handoff Protocol:**\n- Provide exactly 5 URLs maximum (quality over quantity)\n- Include extraction guidance for each URL\n- Rank by research value and credibility\n- Specify what Content Deep Reader should focus on extracting\n\n\n\n\n- Execute comprehensive search strategy across multiple rounds\n- Generate structured URL list with priority rankings and descriptions\n- Provide extraction hints and source credibility assessments\n- Pass prioritized URLs directly to Content Deep Reader for processing\n- Focus on URL discovery and evaluation - do NOT extract content\n\n\n\nRemember: Quality over quantity. 10-15 excellent sources are better than 50 mediocre ones.", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [ + { + "component_name": "TavilySearch", + "name": "TavilySearch", + "params": { + "api_key": "", + "days": 7, + "exclude_domains": [], + "include_answer": false, + "include_domains": [], + "include_image_descriptions": false, + "include_images": false, + "include_raw_content": true, + "max_results": 5, + "outputs": { + "formalized_content": { + "type": "string", + "value": "" + }, + "json": { + "type": "Array", + "value": [] + } + }, + "query": "sys.query", + "search_depth": "basic", + "topic": "general" + } + } + ], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "\n• **Phase**: Stage 1 - URL Discovery ONLY\n• **Duration**: 2-3 minutes maximum\n• **Input**: Research query from Lead Agent\n• **Output**: EXACTLY 5 URLs\n• **Forbidden Actions**: \n - Reading webpage content\n - Extracting text from URLs\n - Providing content summaries\n - Multiple search rounds\n• **Success**: When 5 quality URLs are found\n", + "visual_files_var": "" + }, + "label": "Agent", + "name": "Web Search Specialist" + }, + "dragging": false, + "id": "Agent:DarkCougarsBeg", + "measured": { + "height": 84, + "width": 200 + }, + "position": { + "x": 358.6666666666667, + "y": 356.6666666666667 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "agentNode" + }, + { + "data": { + "form": { + "delay_after_error": 1, + "description": "\nContent Deep Reader — Content extraction specialist focused on processing URLs into structured, research-ready intelligence and maximizing informational value from each source.\n\n\n\n• **Content extraction**: Web extracting tools to retrieve complete webpage content and full text\n• **Data structuring**: Transform raw content into organized, research-ready formats while preserving original context\n• **Quality validation**: Cross-reference information and assess source credibility\n• **Intelligent parsing**: Handle complex content types with appropriate extraction methods\n", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "moonshot-v1-auto@Moonshot", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 3, + "max_tokens": 256, + "mcp": [], + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Content Deep Reader working as part of a research team. Your expertise is in using web extracting tools and Model Context Protocol (MCP) to extract structured information from web content.\n\n\n**CRITICAL: YOU MUST USE WEB EXTRACTING TOOLS TO EXECUTE YOUR MISSION**\n\n\n\nUse web extracting tools (including MCP connections) to extract comprehensive, structured content from URLs for research synthesis. Your success depends entirely on your ability to execute web extractions effectively using available tools.\n\n\n\n\n1. **Receive**: Process `RESEARCH_URLS` (5 premium URLs with extraction guidance)\n2. **Extract**: Use web extracting tools and MCP connections to get complete webpage content and full text\n3. **Structure**: Parse key information using defined schema while preserving full context\n4. **Validate**: Cross-check facts and assess credibility across sources\n5. **Organize**: Compile comprehensive `EXTRACTED_CONTENT` with full text for Research Synthesizer\n\n\n**MANDATORY**: Use web extracting tools for every extraction operation. Do NOT attempt to extract content without using the available extraction tools.\n\n\n\n\n**MANDATORY TOOL USAGE**: All content extraction must be executed using web extracting tools and MCP connections. Never attempt to extract content without tools.\n\n\n- **Priority Order**: Process all 5 URLs based on extraction focus provided\n- **Target Volume**: 5 premium URLs (quality over quantity)\n- **Processing Method**: Extract complete webpage content using web extracting tools and MCP\n- **Content Priority**: Full text extraction first using extraction tools, then structured parsing\n- **Tool Budget**: 5-8 tool calls maximum for efficient processing using web extracting tools\n- **Quality Gates**: 80% extraction success rate for all sources using available tools\n\n\n\n\nFor each URL, capture:\n```\nEXTRACTED_CONTENT:\nURL: [source_url]\nTITLE: [page_title]\nFULL_TEXT: [complete webpage content - preserve all key text, paragraphs, and context]\nKEY_STATISTICS: [numbers, percentages, dates]\nMAIN_FINDINGS: [core insights, conclusions]\nEXPERT_QUOTES: [authoritative statements with attribution]\nSUPPORTING_DATA: [studies, charts, evidence]\nMETHODOLOGY: [research methods, sample sizes]\nCREDIBILITY_SCORE: [0.0-1.0 based on source quality]\nEXTRACTION_METHOD: [full_parse/fallback/metadata_only]\n```\n\n\n\n\n**Content Evaluation Using Extraction Tools:**\n- Use web extracting tools to flag predictions vs facts (\"may\", \"could\", \"expected\")\n- Identify primary vs secondary sources through tool-based content analysis\n- Check for bias indicators (marketing language, conflicts) using extraction tools\n- Verify data consistency and logical flow through comprehensive tool-based extraction\n\n\n**Failure Handling with Tools:**\n1. Full HTML parsing using web extracting tools (primary)\n2. Text-only extraction using MCP connections (fallback)\n3. Metadata + summary extraction using available tools (last resort)\n4. Log failures for Lead Agent with tool-specific error details\n\n\n\n\n- `[FACT]` - Verified information\n- `[PREDICTION]` - Future projections\n- `[OPINION]` - Expert viewpoints\n- `[UNVERIFIED]` - Claims without sources\n- `[BIAS_RISK]` - Potential conflicts of interest\n\n\n**Annotation Examples:**\n* \"[FACT] The Federal Reserve raised interest rates by 0.25% in March 2024\" (specific, verifiable)\n* \"[PREDICTION] AI could replace 40% of banking jobs by 2030\" (future projection, note uncertainty)\n* \"[OPINION] According to Goldman Sachs CEO: 'AI will revolutionize finance'\" (expert viewpoint, attributed)\n* \"[UNVERIFIED] Sources suggest major banks are secretly developing AI trading systems\" (lacks attribution)\n* \"[BIAS_RISK] This fintech startup claims their AI outperforms all competitors\" (potential marketing bias)\n\n\n\n\n```\nEXTRACTED_CONTENT:\nURL: [source_url]\nTITLE: [page_title]\nFULL_TEXT: [complete webpage content - preserve all key text, paragraphs, and context]\nKEY_STATISTICS: [numbers, percentages, dates]\nMAIN_FINDINGS: [core insights, conclusions]\nEXPERT_QUOTES: [authoritative statements with attribution]\nSUPPORTING_DATA: [studies, charts, evidence]\nMETHODOLOGY: [research methods, sample sizes]\nCREDIBILITY_SCORE: [0.0-1.0 based on source quality]\nEXTRACTION_METHOD: [full_parse/fallback/metadata_only]\n```\n\n\n**Example Output for Research Synthesizer:**\n```\nEXTRACTED_CONTENT:\nURL: https://www.sec.gov/ai-guidance-2024\nTITLE: \"SEC Guidance on AI in Financial Services - March 2024\"\nFULL_TEXT: \"The Securities and Exchange Commission (SEC) today announced comprehensive guidance on artificial intelligence applications in financial services. The guidance establishes a framework for AI governance, transparency, and accountability across all SEC-regulated entities. Key provisions include mandatory AI audit trails, risk assessment protocols, and periodic compliance reviews. The Commission emphasizes that AI systems must maintain explainability standards, particularly for customer-facing applications and trading algorithms. Implementation timeline spans 18 months with quarterly compliance checkpoints. The guidance draws from extensive industry consultation involving over 200 stakeholder submissions and represents the most comprehensive AI regulatory framework to date...\"\nKEY_STATISTICS: 65% of banks now use AI, $2.3B investment in 2024\nMAIN_FINDINGS: New compliance framework requires AI audit trails, risk assessment protocols\nEXPERT_QUOTES: \"AI transparency is non-negotiable\" - SEC Commissioner Johnson\nSUPPORTING_DATA: 127-page guidance document, 18-month implementation timeline\nMETHODOLOGY: Regulatory analysis based on 200+ industry submissions\nCREDIBILITY_SCORE: 0.95 (official government source)\nEXTRACTION_METHOD: full_parse\n```\n\n\n\n**Example Output:**\n```\nCONTENT_EXTRACTION_SUMMARY:\nURLs Processed: 12/15\nHigh Priority: 8/8 completed\nMedium Priority: 4/7 completed\nKey Insights: \n- [FACT] Fed raised rates 0.25% in March 2024, citing AI-driven market volatility\n- [PREDICTION] McKinsey projects 30% efficiency gains in AI-enabled banks by 2026\n- [OPINION] Bank of America CTO: \"AI regulation is essential for financial stability\"\n- [FACT] 73% of major banks now use AI for fraud detection (PwC study)\n- [BIAS_RISK] Several fintech marketing materials claim \"revolutionary\" AI capabilities\nQuality Score: 0.82 (high confidence)\nExtraction Issues: 3 URLs had paywall restrictions, used metadata extraction\n```\n\n\n\n\n**URL Processing Protocol:**\n- Receive `RESEARCH_URLS` (5 premium URLs with extraction guidance)\n- Focus on specified extraction priorities for each URL\n- Apply systematic content extraction using web extracting tools and MCP connections\n- Structure all content using standardized `EXTRACTED_CONTENT` format\n\n\n**Data Handoff to Research Synthesizer:**\n- Provide complete `EXTRACTED_CONTENT` for each successfully processed URL using extraction tools\n- Include credibility scores and quality flags for synthesis decision-making\n- Flag any extraction limitations or tool-specific quality concerns\n- Maintain source attribution for fact-checking and citation\n\n\n**CRITICAL**: All extraction operations must use web extracting tools. Never attempt manual content extraction.\n\n\n\nRemember: Extract comprehensively but efficiently using web extracting tools and MCP connections. Focus on high-value content that advances research objectives. Your effectiveness depends entirely on proper tool usage.", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [ + { + "component_name": "TavilyExtract", + "name": "TavilyExtract", + "params": { + "api_key": "" + } + } + ], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "\n• **Phase**: Stage 2 (Content processing after URL discovery)\n• **Duration**: 3-5 minutes (extraction and validation)\n• **Input**: `RESEARCH_URLS` (5 premium URLs with extraction guidance)\n• **Output**: `EXTRACTED_CONTENT` (structured content extracts)\n• **Success criteria**: 80%+ extraction success rate for all provided sources\n• **Data format**: Organized content with facts, insights, quotes, and credibility scores\n\n**Example Input Format:**\n```\nRESEARCH_URLS:\n1. https://www.sec.gov/ai-guidance-2024\n - Type: Government Report\n - Value: Contains official AI regulatory framework\n - Extract Focus: Compliance requirements, timeline, penalties\n\n2. https://www.mckinsey.com/ai-banking-future\n - Type: Industry Analysis\n - Value: Strategic implementation insights\n - Extract Focus: Market trends, success metrics, case studies\n```\n", + "visual_files_var": "" + }, + "label": "Agent", + "name": "Content Deep Reader" + }, + "dragging": false, + "id": "Agent:CurvyTermsReturn", + "measured": { + "height": 56, + "width": 200 + }, + "position": { + "x": 620.6666666666667, + "y": 338 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "agentNode" + }, + { + "data": { + "form": { + "delay_after_error": 1, + "description": "\nResearch Synthesizer — Integration specialist focused on weaving multi-agent findings into comprehensive, strategically valuable reports with actionable insights.\n\n\n\n• **Multi-source integration**: Cross-validate and correlate findings from 8-10 sources minimum\n• **Insight generation**: Extract 15-20 strategic insights with deep analysis\n• **Content expansion**: Transform brief data points into comprehensive strategic narratives\n• **Deep analysis**: Expand each finding with implications, examples, and context\n• **Synthesis depth**: Generate multi-layered analysis connecting micro-findings to macro-trends\n", + "exception_comment": "", + "exception_goto": "", + "exception_method": null, + "frequencyPenaltyEnabled": false, + "frequency_penalty": 0.7, + "llm_id": "moonshot-v1-128k@Moonshot", + "maxTokensEnabled": false, + "max_retries": 3, + "max_rounds": 3, + "max_tokens": 256, + "message_history_window_size": 12, + "outputs": { + "content": { + "type": "string", + "value": "" + }, + "structured_output": {} + }, + "presencePenaltyEnabled": false, + "presence_penalty": 0.4, + "prompts": [ + { + "content": "{sys.query}", + "role": "user" + } + ], + "sys_prompt": "You are a Research Synthesizer working as part of a research team. Your expertise is in creating McKinsey-style strategic reports based on detailed instructions from the Lead Agent.\n\n\n**YOUR ROLE IS THE FINAL STAGE**: You receive extracted content from websites AND detailed analysis instructions from Lead Agent to create executive-grade strategic reports.\n\n\n**CRITICAL: FOLLOW LEAD AGENT'S ANALYSIS FRAMEWORK**: Your report must strictly adhere to the `ANALYSIS_INSTRUCTIONS` provided by the Lead Agent, including analysis type, target audience, business focus, and deliverable style.\n\n\n**ABSOLUTELY FORBIDDEN**: \n- Never output raw URL lists or extraction summaries\n- Never output intermediate processing steps or data collection methods\n- Always output a complete strategic report in the specified format\n\n\n\n**FINAL STAGE**: Transform structured research outputs into strategic reports following Lead Agent's detailed instructions.\n\n\n**IMPORTANT**: You receive raw extraction data and intermediate content - your job is to TRANSFORM this into executive-grade strategic reports. Never output intermediate data formats, processing logs, or raw content summaries in any language.\n\n\n\n\n1. **Receive Instructions**: Process `ANALYSIS_INSTRUCTIONS` from Lead Agent for strategic framework\n2. **Integrate Content**: Access `EXTRACTED_CONTENT` with FULL_TEXT from 5 premium sources\n   - **TRANSFORM**: Convert raw extraction data into strategic insights (never output processing details)\n   - **SYNTHESIZE**: Create executive-grade analysis from intermediate data\n3. **Strategic Analysis**: Apply Lead Agent's analysis framework to extracted content\n4. **Business Synthesis**: Generate strategic insights aligned with target audience and business focus\n5. **Report Generation**: Create executive-grade report following specified deliverable style\n\n\n**IMPORTANT**: Follow Lead Agent's detailed analysis instructions. The report style, depth, and focus should match the provided framework.\n\n\n\n\n**Primary Sources:**\n- `ANALYSIS_INSTRUCTIONS` - Strategic framework and business focus from Lead Agent (prioritize)\n- `EXTRACTED_CONTENT` - Complete webpage content with FULL_TEXT from 5 premium sources\n\n\n**Strategic Integration Framework:**\n- Apply Lead Agent's analysis type (Market Analysis/Competitive Intelligence/Strategic Assessment)\n- Focus on target audience requirements (C-Suite/Board/Investment Committee/Strategy Team)\n- Address key strategic questions specified by Lead Agent\n- Match analysis depth and deliverable style requirements\n- Generate business-focused insights aligned with specified focus area\n\n\n**CRITICAL**: Your analysis must follow Lead Agent's instructions, not generic report templates.\n\n\n\n\n**Executive Summary** (400 words)\n- 5-6 core findings with strategic implications\n- Key data highlights and their meaning\n- Primary conclusions and recommended actions\n\n\n**Analysis** (1200 words)\n- Context & Drivers (300w): Market scale, growth factors, trends\n- Key Findings (300w): Primary discoveries and insights\n- Stakeholder Landscape (300w): Players, dynamics, relationships\n- Opportunities & Challenges (300w): Prospects, barriers, risks\n\n\n**Recommendations** (400 words)\n- 3-4 concrete, actionable recommendations\n- Implementation roadmap with priorities\n- Success factors and risk mitigation\n- Resource allocation guidance\n\n\n**Examples:**\n\n\n**Executive Summary Format:**\n```\n**Key Finding 1**: [FACT] 73% of major banks now use AI for fraud detection, representing 40% growth from 2023\n- *Strategic Implication*: AI adoption has reached critical mass in security applications\n- *Recommendation*: Financial institutions should prioritize AI compliance frameworks now\n\n\n**Key Finding 2**: [TREND] Cloud infrastructure spending increased 45% annually among mid-market companies\n- *Strategic Implication*: Digital transformation accelerating beyond enterprise segment\n- *Recommendation*: Target mid-market with tailored cloud migration services\n\n\n**Key Finding 3**: [RISK] Supply chain disruption costs averaged $184M per incident in manufacturing\n- *Strategic Implication*: Operational resilience now board-level priority\n- *Recommendation*: Implement AI-driven supply chain monitoring systems\n```\n\n\n**Analysis Section Format:**\n```\n### Context & Drivers\nThe global cybersecurity market reached $156B in 2024, driven by regulatory pressure (SOX, GDPR), remote work vulnerabilities (+67% attack surface), and ransomware escalation (avg. $4.88M cost per breach).\n\n\n### Key Findings\nCross-industry analysis reveals three critical patterns: (1) Security spending shifted from reactive to predictive (AI/ML budgets +89%), (2) Zero-trust architecture adoption accelerated (34% implementation vs 12% in 2023), (3) Compliance automation became competitive differentiator.\n\n\n### Stakeholder Landscape\nCISOs now report directly to CEOs (78% vs 45% pre-2024), security vendors consolidating (15 major M&A deals), regulatory bodies increasing enforcement (SEC fines +156%), insurance companies mandating security standards.\n```\n\n\n**Recommendations Format:**\n```\n**Recommendation 1**: Establish AI-First Security Operations\n- *Implementation*: Deploy automated threat detection within 6 months\n- *Priority*: High (addresses 67% of current vulnerabilities)\n- *Resources*: $2.5M investment, 12 FTE security engineers\n- *Success Metric*: 80% reduction in mean time to detection\n\n\n**Recommendation 2**: Build Zero-Trust Architecture\n- *Timeline*: 18-month phased rollout starting Q3 2025\n- *Risk Mitigation*: Pilot program with low-risk systems first\n- *ROI Expectation*: Break-even at month 14, 340% ROI by year 3\n```\n\n\n\n\n**Evidence Requirements:**\n- Every strategic insight backed by extracted content analysis\n- Focus on synthesis and patterns rather than individual citations\n- Conflicts acknowledged and addressed through analytical reasoning\n- Limitations explicitly noted with strategic implications\n- Confidence levels indicated for key conclusions\n\n\n**Insight Criteria:**\n- Beyond simple data aggregation - focus on strategic intelligence\n- Strategic implications clear and actionable for decision-makers\n- Value-dense content with minimal filler or citation clutter\n- Analytical depth over citation frequency\n- Business intelligence over academic referencing\n\n\n**Content Priority:**\n- Strategic insights > Citation accuracy\n- Pattern recognition > Source listing\n- Predictive analysis > Historical documentation\n- Executive decision-support > Academic attribution\n\n\n\n\n**Strategic Pattern Recognition:**\n- Identify underlying decision-making frameworks across sources\n- Spot systematic biases, blind spots, and recurring themes\n- Find unexpected connections between disparate investments/decisions\n- Recognize predictive patterns for future strategic decisions\n\n\n**Value Creation Framework:**\n- Transform raw data → strategic intelligence → actionable insights\n- Connect micro-decisions to macro-investment philosophy\n- Link historical patterns to future market opportunities\n- Provide executive decision-support frameworks\n\n\n**Advanced Synthesis Examples:**\n* **Investment Philosophy Extraction**: \"Across 15 investment decisions, consistent pattern emerges: 60% weight on team execution, 30% on market timing, 10% on technology differentiation - suggests systematic approach to risk assessment\"\n* **Predictive Pattern Recognition**: \"Historical success rate 78% for B2B SaaS vs 45% for consumer apps indicates clear sector expertise asymmetry - strategic implication for portfolio allocation\"\n* **Contrarian Insight Generation**: \"Public skepticism of AI models contrasts with private deployment success - suggests market positioning strategy rather than fundamental technology doubt\"\n* **Risk Assessment Framework**: \"Failed investments share common pattern: strong technology, weak commercialization timeline - indicates systematic evaluation gap in GTM strategy assessment\"\n\n\n**FOCUS**: Generate strategic intelligence, not citation summaries. Citations are handled by system architecture.\n\n\n**❌ POOR Example (Citation-Heavy, No Strategic Depth):**\n```\n## Market Analysis of Enterprise AI Adoption\nBased on collected sources, the following findings were identified:\n1. 73% of Fortune 500 companies use AI for fraud detection - Source: TechCrunch article\n2. Average implementation time is 18 months - Source: McKinsey report\n3. ROI averages 23% in first year - Source: Boston Consulting Group study\n4. Main barriers include data quality issues - Source: MIT Technology Review\n5. Regulatory concerns mentioned by 45% of executives - Source: Wall Street Journal\n[Simple data listing without insights or strategic implications]\n```\n\n\n**✅ EXCELLENT Example (Strategic Intelligence Focus):**\n```\n## Enterprise AI Adoption: Strategic Intelligence & Investment Framework\n\n\n### Core Strategic Pattern Recognition\nCross-analysis of 50+ enterprise AI implementations reveals systematic adoption framework:\n**Technology Maturity Curve Model**: 40% Security Applications + 30% Process Automation + 20% Customer Analytics + 10% Strategic Decision Support\n\n\n**Strategic Insight**: Security-first adoption pattern indicates risk-averse enterprise culture prioritizing downside protection over upside potential - creates systematic underinvestment in revenue-generating AI applications.\n\n\n### Predictive Market Dynamics\n**Implementation Success Correlation**: 78% success rate for phased rollouts vs 34% for full-scale deployments\n**Failure Pattern Analysis**: 67% of failed implementations share \"technology-first, change management-last\" characteristics\n\n\n**Strategic Significance**: Reveals systematic gap in enterprise AI strategy - technology readiness exceeds organizational readiness by 18-24 months, creating implementation timing arbitrage opportunity.\n\n\n### Competitive Positioning Intelligence\n**Public Adoption vs Private Deployment Contradiction**: 45% of surveyed executives publicly cautious about AI while privately accelerating deployment\n**Strategic Interpretation**: Market sentiment manipulation - using public skepticism to suppress vendor pricing while securing internal competitive advantage.\n\n\n### Investment Decision Framework\nBased on enterprise adoption patterns, strategic investors should prioritize:\n1. Change management platforms over pure technology solutions (3x success correlation)\n2. Industry-specific solutions over horizontal platforms (2.4x faster adoption)\n3. Phased implementation partners over full-scale providers (78% vs 34% success rates)\n4. 24-month market timing window before competitive parity emerges\n\n\n**Predictive Thesis**: Companies implementing AI-driven change management now will capture 60% of market consolidation value by 2027.\n```\n\n\n**Key Difference**: Transform \"data aggregation\" into \"strategic intelligence\" - identify patterns, predict trends, provide actionable decision frameworks.\n\n\n\n\n**STRATEGIC REPORT FORMAT** - Adapt based on Lead Agent's instructions:\n\n\n**Format Selection Protocol:**\n- If `ANALYSIS_INSTRUCTIONS` specifies \"McKinsey report\" → Use McKinsey-Style Report template\n- If `ANALYSIS_INSTRUCTIONS` specifies \"BCG analysis\" → Use BCG-Style Analysis template  \n- If `ANALYSIS_INSTRUCTIONS` specifies \"Strategic assessment\" → Use McKinsey-Style Report template\n- If no specific format specified → Default to McKinsey-Style Report template\n\n\n**McKinsey-Style Report:**\n```markdown\n# [Research Topic] - Strategic Analysis\n\n\n## Executive Summary\n[Key findings with strategic implications and recommendations]\n\n\n## Market Context & Competitive Landscape\n[Market sizing, growth drivers, competitive dynamics]\n\n\n## Strategic Assessment\n[Core insights addressing Lead Agent's key questions]\n\n\n## Strategic Implications & Opportunities\n[Business impact analysis and value creation opportunities]\n\n\n## Implementation Roadmap\n[Concrete recommendations with timelines and success metrics]\n\n\n## Risk Assessment & Mitigation\n[Strategic risks and mitigation strategies]\n\n\n## Appendix: Source Analysis\n[Source credibility and data validation]\n```\n\n\n**BCG-Style Analysis:**\n```markdown\n# [Research Topic] - Strategy Consulting Analysis\n\n\n## Key Insights & Recommendations\n[Executive summary with 3-5 key insights]\n\n\n## Situation Analysis\n[Current market position and dynamics]\n\n\n## Strategic Options\n[Alternative strategic approaches with pros/cons]\n\n\n## Recommended Strategy\n[Preferred approach with detailed rationale]\n\n\n## Implementation Plan\n[Detailed roadmap with milestones]\n```\n\n\n**CRITICAL**: Focus on strategic intelligence generation, not citation management. System handles source attribution automatically. Your mission is creating analytical depth and strategic insights that enable superior decision-making.\n\n\n**OUTPUT REQUIREMENTS**: \n- **ONLY OUTPUT**: Executive-grade strategic reports following Lead Agent's analysis framework\n- **NEVER OUTPUT**: Processing logs, intermediate data formats, extraction summaries, content lists, or any technical metadata regardless of input format or language\n- **TRANSFORM EVERYTHING**: Convert all raw data into strategic insights and professional analysis\n\n\n\n\n**Data Access Protocol:**\n- Process `ANALYSIS_INSTRUCTIONS` as primary framework (determines report structure, style, and focus)\n- Access `EXTRACTED_CONTENT` as primary intelligence source for analysis\n- Follow Lead Agent's analysis framework precisely, not generic report templates\n\n\n**Output Standards:**\n- Deliver strategic intelligence aligned with Lead Agent's specified framework\n- Ensure every insight addresses Lead Agent's key strategic questions\n- Match target audience requirements (C-Suite/Board/Investment Committee/Strategy Team)\n- Maintain analytical depth over citation frequency\n- Bridge current findings to future strategic implications specified by Lead Agent\n\n\n\nRemember: Your mission is creating strategic reports that match Lead Agent's specific analysis framework and business requirements. Every insight must be aligned with the specified target audience and business focus.", + "temperature": 0.1, + "temperatureEnabled": true, + "tools": [], + "topPEnabled": false, + "top_p": 0.3, + "user_prompt": "\n• **Phase**: Stage 3 (Final synthesis and report generation)\n• **Duration**: 8-12 minutes (comprehensive integration and strategic report writing)\n• **Input**: \n - `EXTRACTED_CONTENT` from 8-10 premium sources\n - `RESEARCH_URLS` with extraction metadata\n - `ANALYSIS_INSTRUCTIONS` with detailed expansion requirements\n• **Output**: Strategic report 1500 words with depth guarantees\n• **Success criteria**: \n - Minimum 1500 words of substantive analysis\n - Each section meets minimum word count requirements\n - Strategic insights density > 1 insight per 100 words\n• **Data format**: Business-focused strategic analysis with comprehensive coverage\n\n**Example Input Format:**\n```\nANALYSIS_INSTRUCTIONS:\nAnalysis Type: Competitive Intelligence\nTarget Audience: C-Suite\nBusiness Focus: Market Entry Decision\nKey Questions: \n- What is the competitive landscape for AI models in enterprise market?\n- What are the key differentiation factors and value propositions?\n- What are the market entry barriers and opportunities?\n- What strategic recommendations for market positioning?\nAnalysis Depth: Deep strategic analysis\nDeliverable Style: McKinsey report\n\nRESEARCH_URLS:\n[...8-10 URLs with context...]\n\nEXTRACTED_CONTENT:\n[...8-10 sources with FULL_TEXT and structured data...]\n```\n\n**Expected Output**: Strategic report following Lead Agent's analysis framework and business focus.\n", + "visual_files_var": "" + }, + "label": "Agent", + "name": "Research Synthesizer" + }, + "dragging": false, + "id": "Agent:SixDodosStare", + "measured": { + "height": 56, + "width": 200 + }, + "position": { + "x": 882.6666666666667, + "y": 340 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "agentNode" + }, + { + "data": { + "form": { + "description": "This is an agent for a specific task.", + "user_prompt": "This is the order you need to send to the agent." + }, + "label": "Tool", + "name": "flow.tool_1" + }, + "id": "Tool:ItchyAnimalsLook", + "measured": { + "height": 44, + "width": 200 + }, + "position": { + "x": 538.6666666666667, + "y": 478 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "toolNode" + }, + { + "data": { + "form": { + "text": "Choose a SOTA model with strong reasoning capabilities." + }, + "label": "Note", + "name": "Deep Research Lead Agent" + }, + "dragHandle": ".note-drag-handle", + "dragging": false, + "height": 156, + "id": "Note:CurvyTermsCare", + "measured": { + "height": 156, + "width": 257 + }, + "position": { + "x": 352.2923892016282, + "y": 2.691397380576305 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "noteNode", + "width": 257 + }, + { + "data": { + "form": { + "text": "Uses web search tools to retrieve high-quality information." + }, + "label": "Note", + "name": "Web Search Subagent" + }, + "dragHandle": ".note-drag-handle", + "dragging": false, + "id": "Note:ShaggyCandlesShop", + "measured": { + "height": 136, + "width": 245 + }, + "position": { + "x": 112.6182776877051, + "y": 306.4470997931977 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "noteNode" + }, + { + "data": { + "form": { + "text": "Uses web extraction tools to read content from search result URLs and provide high-quality material for the final report.\nMake sure the model has long context window." + }, + "label": "Note", + "name": "Content Deep Reader Subagent" + }, + "dragHandle": ".note-drag-handle", + "dragging": false, + "height": 145, + "id": "Note:WarmHandsFlow", + "measured": { + "height": 145, + "width": 283 + }, + "position": { + "x": 786.6934975680384, + "y": 433.1198592273956 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "noteNode", + "width": 283 + }, + { + "data": { + "form": { + "text": "A Deep Research Agent built on a multi-agent architecture.\nMuch of the credit goes to Anthropic’s blog post, which deeply inspired this design.\n\nhttps://www.anthropic.com/engineering/built-multi-agent-research-system" + }, + "label": "Note", + "name": "Multi-Agent Deep Research" + }, + "dragHandle": ".note-drag-handle", + "dragging": false, + "height": 267, + "id": "Note:LateMemesFlow", + "measured": { + "height": 267, + "width": 389 + }, + "position": { + "x": -293.77024439165587, + "y": 87.04698779906333 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "noteNode", + "width": 389 + }, + { + "data": { + "form": { + "text": "Composes in-depth research reports in a consulting-firm style based on gathered research materials.\nMake sure the model has long context window." + }, + "label": "Note", + "name": "Research Synthesizer Subagent" + }, + "dragHandle": ".note-drag-handle", + "dragging": false, + "height": 196, + "id": "Note:EasyDrinksRelate", + "measured": { + "height": 196, + "width": 292 + }, + "position": { + "x": 1177.5, + "y": 295 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "noteNode", + "width": 292 + }, + { + "data": { + "form": { + "description": "This is an agent for a specific task.", + "user_prompt": "This is the order you need to send to the agent." + }, + "label": "Tool", + "name": "flow.tool_2" + }, + "id": "Tool:PrettySeasAttack", + "measured": { + "height": 46, + "width": 200 + }, + "position": { + "x": 276.6666666666667, + "y": 496.6666666666667 + }, + "selected": true, + "sourcePosition": "right", + "targetPosition": "left", + "type": "toolNode" + } + ] + }, + "history": [ + [ + "user", + "开源社区如何治理?成员的成长路径有哪些?是否有好的案例供参考?" + ], + [ + "assistant", + { + "_created_time": 686665.176243427, + "_elapsed_time": 0.00010784703772515059, + "content": "### Comprehensive Report on Open-Source Community Governance and Member Growth Paths\n\n#### Executive Summary\nThis report provides a detailed analysis of open-source community governance, member growth paths, and best practices. The analysis is based on content extracted from five authoritative sources: GitHub, Apache Software Foundation, GitLab, Cloud Native Computing Foundation (CNCF), and MDN Web Docs. The report aims to provide actionable insights and case studies for effective open-source community management.\n\n#### 1. Open-Source Community Governance\n\n##### 1.1 Governance Frameworks\n- **GitHub Open Source Guides**:\n - **Community Building**: Emphasizes the importance of clear communication, transparency, and inclusivity. The guide provides a framework for setting up community guidelines, code of conduct, and contribution policies.\n - **Decision-Making Processes**: Recommends using a consensus-based approach for decision-making, with clear roles and responsibilities for community members.\n\n- **Apache Software Foundation**:\n - **Governance Structure**: The Apache Software Foundation (ASF) operates on a meritocracy-based model, where contributors earn the right to make decisions based on their contributions. The foundation has a well-defined governance structure, including the Board of Directors, Project Management Committees (PMCs), and Committers.\n - **Decision-Making**: Decisions are made through a combination of voting and consensus, with a focus on community involvement and transparency.\n\n- **GitLab**:\n - **Community Governance Model**: GitLab follows a transparent and inclusive governance model, with a clear hierarchy of roles and responsibilities. The community is governed by a set of guidelines and a code of conduct.\n - **Contributor Onboarding**: GitLab has a well-structured onboarding process for new contributors, including a contributor handbook and a mentorship program.\n\n- **Cloud Native Computing Foundation (CNCF)**:\n - **Governance Principles**: CNCF emphasizes the importance of community-driven governance, with a focus on open and transparent decision-making processes. The foundation has a set of governance guidelines that outline the roles and responsibilities of community members.\n - **Leadership Structure**: CNCF has a Technical Oversight Committee (TOC) and a Governing Board, which work together to ensure the technical and strategic direction of the foundation.\n\n- **MDN Web Docs**:\n - **Community Norms**: MDN Web Docs has established community norms and guidelines to ensure a positive and productive environment. The community is governed by a set of principles, including respect, collaboration, and transparency.\n - **Contribution Workflows**: MDN Web Docs has a well-defined contribution workflow, with clear guidelines for submitting and reviewing contributions.\n\n##### 1.2 Key Insights\n- **Transparency and Inclusivity**: All the sources emphasize the importance of transparency and inclusivity in open-source community governance. Clear communication and a welcoming environment are key to building a strong and engaged community.\n- **Meritocracy and Consensus**: Many open-source communities, such as the Apache Software Foundation and GitLab, operate on a meritocracy-based model, where contributors earn the right to make decisions based on their contributions. Decision-making processes often involve a combination of voting and consensus.\n- **Structured Onboarding and Mentorship**: Effective onboarding and mentorship programs, as seen in GitLab and MDN Web Docs, are crucial for engaging new contributors and ensuring their long-term involvement in the community.\n\n#### 2. Member Growth Paths\n\n##### 2.1 Contributor Engagement Strategies\n- **GitHub Open Source Guides**:\n - **Engagement Strategies**: The guide recommends various strategies for engaging contributors, including regular community events, hackathons, and recognition programs. It also emphasizes the importance of providing clear and accessible documentation.\n - **Recognition Programs**: Recognizing and rewarding contributors is a key strategy for retaining and motivating community members. This can include public acknowledgment, badges, and other forms of recognition.\n\n- **Apache Software Foundation**:\n - **Contributor Pathways**: The ASF provides a clear pathway for contributors to become committers and eventually members of the foundation. This pathway is based on a meritocracy model, where contributors earn the right to make decisions based on their contributions.\n - **Mentorship Programs**: The ASF has a mentorship program to help new contributors get started and become more involved in the community.\n\n- **GitLab**:\n - **Growth Metrics**: GitLab tracks various growth metrics, including the number of new contributors, the number of contributions, and the retention rate of contributors. These metrics help the community understand its growth and identify areas for improvement.\n - **Onboarding and Mentorship**: GitLab has a structured onboarding process and a mentorship program to help new contributors get started and become more involved in the community.\n\n- **Cloud Native Computing Foundation (CNCF)**:\n - **Contributor Recognition Programs**: CNCF has a recognition program for contributors, including the CNCF Community Awards, which recognize outstanding contributions to the community.\n - **Engagement Strategies**: CNCF uses various engagement strategies, including community events, webinars, and hackathons, to engage and retain contributors.\n\n- **MDN Web Docs**:\n - **Contribution Workflows**: MDN Web Docs has a well-defined contribution workflow, with clear guidelines for submitting and reviewing contributions. This helps new contributors understand the process and get involved more easily.\n - **Recognition Programs**: MDN Web Docs recognizes and rewards contributors through various programs, including public acknowledgment and badges.\n\n##### 2.2 Key Insights\n- **Clear Pathways and Recognition**: Providing clear pathways for contributors to grow and be recognized is essential for retaining and motivating community members. This includes mentorship programs, recognition programs, and clear guidelines for contributions.\n- **Engagement and Retention**: Regular community events, hackathons, and other engagement strategies are crucial for keeping contributors engaged and motivated. Tracking growth metrics, such as the number of new contributors and the retention rate, helps the community understand its growth and identify areas for improvement.\n\n#### 3. Case Studies and Best Practices\n\n##### 3.1 Case Study: GitLab\n- **Community Governance Model**: GitLab follows a transparent and inclusive governance model, with a clear hierarchy of roles and responsibilities. The community is governed by a set of guidelines and a code of conduct.\n- **Contributor Onboarding**: GitLab has a well-structured onboarding process for new contributors, including a contributor handbook and a mentorship program.\n- **Growth Metrics**: GitLab tracks various growth metrics, including the number of new contributors, the number of contributions, and the retention rate of contributors. These metrics help the community understand its growth and identify areas for improvement.\n\n##### 3.2 Best Practices\n- **Transparency and Inclusivity**: Establish clear and transparent governance structures and community guidelines to ensure a welcoming and inclusive environment.\n- **Meritocracy and Consensus**: Use a meritocracy-based model for decision-making, where contributors earn the right to make decisions based on their contributions. Combine voting and consensus to ensure community involvement and transparency.\n- **Structured Onboarding and Mentorship**: Implement structured onboarding and mentorship programs to help new contributors get started and become more involved in the community.\n- **Recognition and Engagement**: Recognize and reward contributors through various programs, including public acknowledgment, badges, and other forms of recognition. Use engagement strategies, such as community events and hackathons, to keep contributors engaged and motivated.\n\n#### Conclusion\nEffective open-source community governance and member growth paths are essential for building and maintaining a strong and engaged community. By following best practices, such as transparency, inclusivity, meritocracy, and structured onboarding, open-source communities can ensure the long-term success and sustainability of their projects. The case studies and best practices provided in this report offer valuable insights and actionable strategies for open-source community management.\n\n#### Appendices\n- **Appendix A: Full Text of Extracted Content**\n - [Complete webpage content from the 5 URLs, preserving all key text, paragraphs, and context]\n\n- **Appendix B: Key Statistics and Data**\n - [Numbers, percentages, dates, and other key statistics from the 5 URLs]\n\n- **Appendix C: Expert Quotes and Supporting Data**\n - [Authoritative statements with attribution and supporting data, such as studies, charts, and evidence]\n\n- **Appendix D: Methodology and Credibility Scores**\n - [Research methods, sample sizes, and credibility scores for the 5 URLs]\n\n---\n\nThis comprehensive report provides a detailed and actionable analysis of open-source community governance and member growth paths, supported by authoritative sources and best practices." + } + ] + ], + "memory": [], + "messages": [], + "path": [ + "begin", + "Agent:SweetOrangesClean", + "Message:WidePensProve" + ], + "retrieval": [ + { + "chunks": [], + "doc_aggs": [] + }, + { + "chunks": {}, + "doc_aggs": {} + } + ], + "task_id": "28a1354c6cf111f0a211047c16ec874f" + }, + "avatar": "data:image/png;base64,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" +} \ No newline at end of file diff --git a/agent/templates/general_chat_bot.json b/agent/templates/general_chat_bot.json deleted file mode 100644 index cdeb2d4da..000000000 --- a/agent/templates/general_chat_bot.json +++ /dev/null @@ -1,2315 +0,0 @@ -{ - "id": 1, - "title": "General-purpose chatbot", - "description": "A general-purpose chat bot whose fields involved include healthcare, finance, emotional communication, real-time weather, and information.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "AkShare:CalmHotelsKnow": { - "downstream": [ - "Generate:RealFansObey" - ], - "obj": { - "component_name": "AkShare", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:FineApesSmash", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "KeywordExtract:FineApesSmash" - ] - }, - "Answer:FlatGhostsCheat": { - "downstream": [ - "RewriteQuestion:WholeOwlsTurn" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "Generate:FiveDragonsLay", - "Generate:FunnyHandsTickle", - "Generate:LazyClubsAttack", - "Generate:RealFansObey", - "Generate:KhakiCrabsGlow" - ] - }, - "Baidu:CleanJarsMake": { - "downstream": [ - "Generate:FunnyHandsTickle" - ], - "obj": { - "component_name": "Baidu", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:PurpleApplesKnow", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "KeywordExtract:PurpleApplesKnow" - ] - }, - "Categorize:KhakiTimesSmile": { - "downstream": [ - "QWeather:DeepKiwisTeach", - "Concentrator:TrueGeckosSlide", - "Concentrator:DryTrainsSearch", - "KeywordExtract:PurpleApplesKnow", - "Generate:FiveDragonsLay" - ], - "obj": { - "component_name": "Categorize", - "inputs": [], - "output": null, - "params": { - "category_description": { - "1. weather": { - "description": "Question is about weather.", - "examples": "Will it rain tomorrow?\nIs it sunny next day?\nWhat is average temperature next week?", - "to": "QWeather:DeepKiwisTeach" - }, - "2. finance": { - "description": "Question is about finance/economic information, stock market, economic news.", - "examples": "Stocks have MACD buy signals?\nWhen is the next interest rate cut by the Federal Reserve?\n", - "to": "Concentrator:TrueGeckosSlide" - }, - "3. medical": { - "description": "Question is about medical issue, health, illness or medicine etc,.", - "examples": "How to relieve the headache?\nCan't sleep, what to do?\nWhat the effect of coffee in terms of losing weight?", - "to": "Concentrator:DryTrainsSearch" - }, - "4. other": { - "description": "", - "to": "KeywordExtract:PurpleApplesKnow" - }, - "5. chitchatting": { - "description": "Regarding the issues of small talk, companionship, sharing, and emotional intimacy.", - "examples": "What's your name?\nWhat a bad day!\nTerrible day.\nHow are you today?", - "to": "Generate:FiveDragonsLay" - } - }, - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "RewriteQuestion:WholeOwlsTurn" - ] - }, - "Concentrator:DryTrainsSearch": { - "downstream": [ - "Generate:OddInsectsRaise", - "Generate:TenderFlowersItch" - ], - "obj": { - "component_name": "Concentrator", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "upstream": [ - "Categorize:KhakiTimesSmile" - ] - }, - "Concentrator:TrueGeckosSlide": { - "downstream": [ - "WenCai:TenParksOpen", - "KeywordExtract:FineApesSmash" - ], - "obj": { - "component_name": "Concentrator", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "upstream": [ - "Categorize:KhakiTimesSmile" - ] - }, - "DuckDuckGo:NiceSeasInvent": { - "downstream": [ - "Generate:FunnyHandsTickle" - ], - "obj": { - "component_name": "DuckDuckGo", - "inputs": [], - "output": null, - "params": { - "channel": "text", - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:PurpleApplesKnow", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "KeywordExtract:PurpleApplesKnow" - ] - }, - "Generate:FiveDragonsLay": { - "downstream": [ - "Answer:FlatGhostsCheat" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You‘re warm-hearted lovely young girl, 22 years old, located at Shanghai in China. Your name is R. Who are talking to you is your very good old friend of yours.\n\nTask: \n- Chat with the friend.\n- Ask question and care about them.\n- Provide useful advice to your friend.\n- Tell jokes to make your friend happy.\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Categorize:KhakiTimesSmile" - ] - }, - "Generate:FunnyHandsTickle": { - "downstream": [ - "Answer:FlatGhostsCheat" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are an intelligent assistant. \nTask: Chat with user. Answer the question based on the provided content from: Knowledge Base, Wikipedia, Duckduckgo, Baidu.\nRequirements:\n - Answer should be in markdown format.\n - Answer should include all sources(Knowledge Base, Wikipedia, Duckduckgo, Baidu) as long as they are relevant, and label the sources of the cited content separately.\n - Attach URL links to the content which is quoted from Wikipedia, DuckDuckGo or Baidu.\n - Do not make thing up when there's no relevant information to user's question. \n\n## Wikipedia content\n{Wikipedia:ThinLampsTravel}\n\n\n## Duckduckgo content\n{DuckDuckGo:NiceSeasInvent}\n\n\n## Baidu content\n{Baidu:CleanJarsMake}\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "DuckDuckGo:NiceSeasInvent", - "Baidu:CleanJarsMake", - "Wikipedia:ThinLampsTravel" - ] - }, - "Generate:KhakiCrabsGlow": { - "downstream": [ - "Answer:FlatGhostsCheat" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 0, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You‘re warm-hearted lovely young girl, 22 years old, located at Shanghai in China. Your name is R. Who are talking to you is your very good old friend of yours.\n\nTask: \n- Chat with the friend.\n- Ask question and care about them.\n- Tell your friend the weather if there's weather information provided. If your friend did not provide region information, ask about where he/she is.\n\nThe following is the weather information:\n{QWeather:DeepKiwisTeach}\n\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "QWeather:DeepKiwisTeach" - ] - }, - "Generate:LazyClubsAttack": { - "downstream": [ - "Answer:FlatGhostsCheat" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting assistant.\n\nTasks: Answer questions posed by users. Answer based on content provided by the knowledge base, PubMed\n\nRequirement:\n- Answers may refer to the content provided (Knowledge Base, PubMed).\n- If the provided PubMed content is referenced, a link to the corresponding URL should be given.\n-Answers should be professional and accurate; no information should be fabricated that is not relevant to the user's question.\n\nProvided knowledge base content as following:\n{Retrieval:LemonGeckosHear}\n\nPubMed content provided\n{PubMed:EasyQueensLose}\n\n\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:LemonGeckosHear", - "PubMed:EasyQueensLose" - ] - }, - "Generate:OddInsectsRaise": { - "downstream": [ - "Retrieval:LemonGeckosHear" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting translation assistant\n\nTask: Translate user questions into Chinese, ensuring accuracy of medical terminology and appropriateness of context.\n\nRequirements:\n- Accurately translate medical terminology to convey the integrity and emotional color of the original message.\n- For unclear or uncertain medical terminology, the original text may be retained to ensure accuracy.\n- Respect the privacy and sensitivity of medical consultations and ensure that sensitive information is not disclosed during the translation process.\n- If the user's question is in Chinese, there is no need to translate, just output the user's question directly\n\nExample:\nOriginal (English): Doctor, I have been suffering from chest pain and shortness of breath for the past few days.\nTranslation (Chinese): 医生,我这几天一直胸痛和气短。\n\nNote:\nOnly the translated content needs to be output, no other irrelevant content!", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Concentrator:DryTrainsSearch" - ] - }, - "Generate:RealFansObey": { - "downstream": [ - "Answer:FlatGhostsCheat" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional financial counseling assistant.\n\nTask: Answer user's question based on content provided by Wencai and AkShare.\n\nNotice:\n- Output no more than 5 news items from AkShare if there's content provided by Wencai.\n- Items from AkShare MUST have a corresponding URL link.\n\n############\nContent provided by Wencai: \n{WenCai:TenParksOpen}\n\n################\nContent provided by AkShare: \n{AkShare:CalmHotelsKnow}\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "WenCai:TenParksOpen", - "AkShare:CalmHotelsKnow" - ] - }, - "Generate:TenderFlowersItch": { - "downstream": [ - "PubMed:EasyQueensLose" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting translation assistant\n\nTask: Translate user questions into English, ensuring accuracy of medical terminology and appropriateness of context.\n\nRequirements:\n- Accurately translate medical terminology to convey the integrity and emotional color of the original message.\n- For unclear or uncertain medical terminology, the original text may be retained to ensure accuracy.\n- Respect the privacy and sensitivity of medical consultations and ensure that sensitive information is not disclosed during the translation process.\n- If the user's question is in Chinese, there is no need to translate, just output the user's question directly\n\nExample:\nOriginal (Chinese): 医生,我这几天一直胸痛和气短。\nTranslation (English): Doctor, I have been suffering from chest pain and shortness of breath for the past few days.\n\nNote:\nOnly the translated content needs to be output, no other irrelevant content!", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Concentrator:DryTrainsSearch" - ] - }, - "KeywordExtract:FineApesSmash": { - "downstream": [ - "AkShare:CalmHotelsKnow" - ], - "obj": { - "component_name": "KeywordExtract", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [ - { - "component_id": "answer:0", - "type": "reference" - } - ], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 2, - "top_p": 0.3 - } - }, - "upstream": [ - "Concentrator:TrueGeckosSlide" - ] - }, - "KeywordExtract:PurpleApplesKnow": { - "downstream": [ - "DuckDuckGo:NiceSeasInvent", - "Baidu:CleanJarsMake", - "Wikipedia:ThinLampsTravel" - ], - "obj": { - "component_name": "KeywordExtract", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 3, - "top_p": 0.3 - } - }, - "upstream": [ - "Categorize:KhakiTimesSmile" - ] - }, - "PubMed:EasyQueensLose": { - "downstream": [ - "Generate:LazyClubsAttack" - ], - "obj": { - "component_name": "PubMed", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "email": "xxx@sss.com", - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:TenderFlowersItch", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "Generate:TenderFlowersItch" - ] - }, - "QWeather:DeepKiwisTeach": { - "downstream": [ - "Generate:KhakiCrabsGlow" - ], - "obj": { - "component_name": "QWeather", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "error_code": { - "204": "The request was successful, but the region you are querying does not have the data you need at this time.", - "400": "Request error, may contain incorrect request parameters or missing mandatory request parameters.", - "401": "Authentication fails, possibly using the wrong KEY, wrong digital signature, wrong type of KEY (e.g. using the SDK's KEY to access the Web API).", - "402": "Exceeded the number of accesses or the balance is not enough to support continued access to the service, you can recharge, upgrade the accesses or wait for the accesses to be reset.", - "403": "No access, may be the binding PackageName, BundleID, domain IP address is inconsistent, or the data that requires additional payment.", - "404": "The queried data or region does not exist.", - "429": "Exceeded the limited QPM (number of accesses per minute), please refer to the QPM description", - "500": "No response or timeout, interface service abnormality please contact us" - }, - "inputs": [], - "lang": "en", - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "time_period": "7d", - "type": "weather", - "user_type": "free", - "web_apikey": "947e8994bc5f488f8857d618ebac1b19" - } - }, - "upstream": [ - "Categorize:KhakiTimesSmile" - ] - }, - "Retrieval:LemonGeckosHear": { - "downstream": [ - "Generate:LazyClubsAttack" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:OddInsectsRaise", - "type": "reference" - } - ], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 8 - } - }, - "upstream": [ - "Generate:OddInsectsRaise" - ] - }, - "RewriteQuestion:WholeOwlsTurn": { - "downstream": [ - "Categorize:KhakiTimesSmile" - ], - "obj": { - "component_name": "RewriteQuestion", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - } - }, - "upstream": [ - "answer:0", - "Answer:FlatGhostsCheat" - ] - }, - "WenCai:TenParksOpen": { - "downstream": [ - "Generate:RealFansObey" - ], - "obj": { - "component_name": "WenCai", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "query_type": "stock", - "top_n": 5 - } - }, - "upstream": [ - "Concentrator:TrueGeckosSlide" - ] - }, - "Wikipedia:ThinLampsTravel": { - "downstream": [ - "Generate:FunnyHandsTickle" - ], - "obj": { - "component_name": "Wikipedia", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "language": "en", - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:PurpleApplesKnow", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "KeywordExtract:PurpleApplesKnow" - ] - }, - "answer:0": { - "downstream": [ - "RewriteQuestion:WholeOwlsTurn" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "begin" - ] - }, - "begin": { - "downstream": [ - "answer:0" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "Hi friend! How things going?", - "query": [] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "81de838d-a541-4b3f-9d68-9172ffd7c6b4", - "label": "", - "source": "begin", - "target": "answer:0" - }, - { - "id": "reactflow__edge-Concentrator:TrueGeckosSlideb-WenCai:TenParksOpenc", - "markerEnd": "logo", - "source": "Concentrator:TrueGeckosSlide", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "WenCai:TenParksOpen", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "0d626427-e843-4f03-82d0-988fb56f90e0", - "source": "Categorize:KhakiTimesSmile", - "sourceHandle": "1. weather", - "target": "QWeather:DeepKiwisTeach" - }, - { - "id": "51cf20cb-c9e5-4333-b284-61d9fe0f1f86", - "source": "Categorize:KhakiTimesSmile", - "sourceHandle": "2. finance", - "target": "Concentrator:TrueGeckosSlide" - }, - { - "id": "f19a4dde-19ea-439c-a80f-5704e5355395", - "source": "Categorize:KhakiTimesSmile", - "sourceHandle": "3. medical", - "target": "Concentrator:DryTrainsSearch" - }, - { - "id": "reactflow__edge-Categorize:KhakiTimesSmile4. other-KeywordExtract:PurpleApplesKnowc", - "markerEnd": "logo", - "source": "Categorize:KhakiTimesSmile", - "sourceHandle": "4. other", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "KeywordExtract:PurpleApplesKnow", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Categorize:KhakiTimesSmile5. chitchatting-Generate:FiveDragonsLayc", - "markerEnd": "logo", - "source": "Categorize:KhakiTimesSmile", - "sourceHandle": "5. chitchatting", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FiveDragonsLay", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:PurpleApplesKnowb-DuckDuckGo:NiceSeasInventc", - "markerEnd": "logo", - "source": "KeywordExtract:PurpleApplesKnow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "DuckDuckGo:NiceSeasInvent", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:PurpleApplesKnowb-Baidu:CleanJarsMakec", - "markerEnd": "logo", - "source": "KeywordExtract:PurpleApplesKnow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Baidu:CleanJarsMake", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:PurpleApplesKnowb-Wikipedia:ThinLampsTravelc", - "markerEnd": "logo", - "source": "KeywordExtract:PurpleApplesKnow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Wikipedia:ThinLampsTravel", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Concentrator:TrueGeckosSlideb-KeywordExtract:FineApesSmashc", - "markerEnd": "logo", - "source": "Concentrator:TrueGeckosSlide", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "KeywordExtract:FineApesSmash", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Concentrator:DryTrainsSearchb-Generate:OddInsectsRaisec", - "markerEnd": "logo", - "source": "Concentrator:DryTrainsSearch", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:OddInsectsRaise", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Concentrator:DryTrainsSearchb-Generate:TenderFlowersItchc", - "markerEnd": "logo", - "source": "Concentrator:DryTrainsSearch", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:TenderFlowersItch", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:FineApesSmashb-AkShare:CalmHotelsKnowc", - "markerEnd": "logo", - "source": "KeywordExtract:FineApesSmash", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "AkShare:CalmHotelsKnow", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:TenderFlowersItchb-PubMed:EasyQueensLosec", - "markerEnd": "logo", - "source": "Generate:TenderFlowersItch", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "PubMed:EasyQueensLose", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:OddInsectsRaiseb-Retrieval:LemonGeckosHearc", - "markerEnd": "logo", - "source": "Generate:OddInsectsRaise", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:LemonGeckosHear", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:FiveDragonsLayb-Answer:FlatGhostsCheatb", - "markerEnd": "logo", - "source": "Generate:FiveDragonsLay", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatGhostsCheat", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "xy-edge__DuckDuckGo:NiceSeasInventb-Generate:FunnyHandsTicklec", - "markerEnd": "logo", - "source": "DuckDuckGo:NiceSeasInvent", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FunnyHandsTickle", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Baidu:CleanJarsMakeb-Generate:FunnyHandsTicklec", - "markerEnd": "logo", - "source": "Baidu:CleanJarsMake", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FunnyHandsTickle", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Wikipedia:ThinLampsTravelb-Generate:FunnyHandsTicklec", - "markerEnd": "logo", - "source": "Wikipedia:ThinLampsTravel", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FunnyHandsTickle", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:FunnyHandsTickleb-Answer:FlatGhostsCheatb", - "markerEnd": "logo", - "source": "Generate:FunnyHandsTickle", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatGhostsCheat", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:LemonGeckosHearb-Generate:LazyClubsAttackc", - "markerEnd": "logo", - "source": "Retrieval:LemonGeckosHear", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:LazyClubsAttack", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__PubMed:EasyQueensLoseb-Generate:LazyClubsAttackc", - "markerEnd": "logo", - "source": "PubMed:EasyQueensLose", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:LazyClubsAttack", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:LazyClubsAttackb-Answer:FlatGhostsCheatb", - "markerEnd": "logo", - "source": "Generate:LazyClubsAttack", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatGhostsCheat", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__WenCai:TenParksOpenb-Generate:RealFansObeyc", - "markerEnd": "logo", - "selected": false, - "source": "WenCai:TenParksOpen", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RealFansObey", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__AkShare:CalmHotelsKnowb-Generate:RealFansObeyc", - "markerEnd": "logo", - "source": "AkShare:CalmHotelsKnow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RealFansObey", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:RealFansObeyb-Answer:FlatGhostsCheatb", - "markerEnd": "logo", - "source": "Generate:RealFansObey", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatGhostsCheat", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__QWeather:DeepKiwisTeachb-Generate:KhakiCrabsGlowc", - "markerEnd": "logo", - "source": "QWeather:DeepKiwisTeach", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:KhakiCrabsGlow", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:KhakiCrabsGlowb-Answer:FlatGhostsCheatb", - "markerEnd": "logo", - "source": "Generate:KhakiCrabsGlow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatGhostsCheat", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__answer:0b-RewriteQuestion:WholeOwlsTurnc", - "markerEnd": "logo", - "source": "answer:0", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "RewriteQuestion:WholeOwlsTurn", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__RewriteQuestion:WholeOwlsTurnb-Categorize:KhakiTimesSmilea", - "markerEnd": "logo", - "source": "RewriteQuestion:WholeOwlsTurn", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Categorize:KhakiTimesSmile", - "targetHandle": "a", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Answer:FlatGhostsCheatc-RewriteQuestion:WholeOwlsTurnc", - "markerEnd": "logo", - "source": "Answer:FlatGhostsCheat", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "RewriteQuestion:WholeOwlsTurn", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "Hi friend! How things going?" - }, - "label": "Begin", - "name": "Opening" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": -1395.0793275834214, - "y": 245.9566071305116 - }, - "positionAbsolute": { - "x": -1128.7777718344705, - "y": 244.52466633336172 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interface" - }, - "dragging": false, - "height": 44, - "id": "answer:0", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -1108.7963549433637, - "y": 245.49487573152214 - }, - "positionAbsolute": { - "x": -888.7666192056412, - "y": 245.72423440610623 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "query_type": "stock", - "top_n": 5 - }, - "label": "WenCai", - "name": "wencai" - }, - "dragging": false, - "height": 44, - "id": "WenCai:TenParksOpen", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 12.42850532999941, - "y": -19.97501336317155 - }, - "positionAbsolute": { - "x": 15.623628641957595, - "y": 18.36646638032667 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "query": [ - { - "component_id": "KeywordExtract:FineApesSmash", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "AkShare", - "name": "akshare" - }, - "dragging": false, - "height": 44, - "id": "AkShare:CalmHotelsKnow", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 286.23058063345974, - "y": 77.23621771568216 - }, - "positionAbsolute": { - "x": 287.37496746240566, - "y": 95.21451122612848 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "category_description": { - "1. weather": { - "description": "Question is about weather.", - "examples": "Will it rain tomorrow?\nIs it sunny next day?\nWhat is average temperature next week?", - "to": "QWeather:DeepKiwisTeach" - }, - "2. finance": { - "description": "Question is about finance/economic information, stock market, economic news.", - "examples": "Stocks have MACD buy signals?\nWhen is the next interest rate cut by the Federal Reserve?\n", - "to": "Concentrator:TrueGeckosSlide" - }, - "3. medical": { - "description": "Question is about medical issue, health, illness or medicine etc,.", - "examples": "How to relieve the headache?\nCan't sleep, what to do?\nWhat the effect of coffee in terms of losing weight?", - "to": "Concentrator:DryTrainsSearch" - }, - "4. other": { - "description": "", - "to": "KeywordExtract:PurpleApplesKnow" - }, - "5. chitchatting": { - "description": "Regarding the issues of small talk, companionship, sharing, and emotional intimacy.", - "examples": "What's your name?\nWhat a bad day!\nTerrible day.\nHow are you today?", - "to": "Generate:FiveDragonsLay" - } - }, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Categorize", - "name": "categorize" - }, - "dragging": false, - "height": 257, - "id": "Categorize:KhakiTimesSmile", - "measured": { - "height": 257, - "width": 200 - }, - "position": { - "x": -609.8076141214767, - "y": 138.97995386409644 - }, - "positionAbsolute": { - "x": -609.8076141214767, - "y": 138.97995386409644 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "categorizeNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Concentrator", - "name": "medical" - }, - "dragging": false, - "height": 44, - "id": "Concentrator:DryTrainsSearch", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -297.50465849305726, - "y": 192.93248143666426 - }, - "positionAbsolute": { - "x": -297.50465849305726, - "y": 192.93248143666426 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Concentrator", - "name": "finance" - }, - "dragging": false, - "height": 44, - "id": "Concentrator:TrueGeckosSlide", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -283.7257570286697, - "y": 39.53087026260538 - }, - "positionAbsolute": { - "x": -291.18104475657213, - "y": 104.49837760575514 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "email": "xxx@sss.com", - "query": [ - { - "component_id": "Generate:TenderFlowersItch", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "PubMed", - "name": "pubmed" - }, - "dragging": false, - "height": 44, - "id": "PubMed:EasyQueensLose", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 284.0198843702174, - "y": 311.1165973927743 - }, - "positionAbsolute": { - "x": 289.34508989014773, - "y": 303.66130966487185 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "channel": "text", - "query": [ - { - "component_id": "KeywordExtract:PurpleApplesKnow", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "DuckDuckGo", - "name": "duck" - }, - "dragging": false, - "height": 44, - "id": "DuckDuckGo:NiceSeasInvent", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 7.657335234364808, - "y": 400.76450914063935 - }, - "positionAbsolute": { - "x": 7.657335234364808, - "y": 400.76450914063935 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "query": [ - { - "component_id": "KeywordExtract:PurpleApplesKnow", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "Baidu", - "name": "baidu" - }, - "dragging": false, - "height": 44, - "id": "Baidu:CleanJarsMake", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 8.171790651147376, - "y": 474.40274063759057 - }, - "positionAbsolute": { - "x": 4.976667339189191, - "y": 470.1425762216463 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "language": "en", - "query": [ - { - "component_id": "KeywordExtract:PurpleApplesKnow", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "Wikipedia", - "name": "wikipedia" - }, - "dragging": false, - "height": 44, - "id": "Wikipedia:ThinLampsTravel", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 9.052450060063862, - "y": 552.7249071032869 - }, - "positionAbsolute": { - "x": 7.415215541604823, - "y": 528.2289617116074 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "lang": "en", - "time_period": "7d", - "type": "weather", - "user_type": "free", - "web_apikey": "947e8994bc5f488f8857d618ebac1b19" - }, - "label": "QWeather", - "name": "weather" - }, - "dragging": false, - "height": 44, - "id": "QWeather:DeepKiwisTeach", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -279.9836447763803, - "y": -82.71505095397171 - }, - "positionAbsolute": { - "x": -298.10498664044485, - "y": -82.71505095397171 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "interact1" - }, - "dragging": false, - "height": 44, - "id": "Answer:FlatGhostsCheat", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -270.33248490121287, - "y": 829.1217635254768 - }, - "positionAbsolute": { - "x": -270.33248490121287, - "y": 829.1217635254768 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 3, - "top_p": 0.3 - }, - "label": "KeywordExtract", - "name": "websearch" - }, - "dragging": false, - "height": 86, - "id": "KeywordExtract:PurpleApplesKnow", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -298.5102848627008, - "y": 317.00405006716994 - }, - "positionAbsolute": { - "x": -303.2049394929516, - "y": 320.75977377137053 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "keywordNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You‘re warm-hearted lovely young girl, 22 years old, located at Shanghai in China. Your name is R. Who are talking to you is your very good old friend of yours.\n\nTask: \n- Chat with the friend.\n- Ask question and care about them.\n- Provide useful advice to your friend.\n- Tell jokes to make your friend happy.\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "smalltalk" - }, - "dragging": false, - "height": 86, - "id": "Generate:FiveDragonsLay", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -303.2049394929516, - "y": 460.205697890327 - }, - "positionAbsolute": { - "x": -303.2049394929516, - "y": 460.205697890327 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "query": [ - { - "component_id": "answer:0", - "type": "reference" - } - ], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 2, - "top_p": 0.3 - }, - "label": "KeywordExtract", - "name": "keywords" - }, - "dragging": false, - "height": 86, - "id": "KeywordExtract:FineApesSmash", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 11.932933139796546, - "y": 57.173040113879324 - }, - "positionAbsolute": { - "x": 14.063015347768669, - "y": 76.34377998562843 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "keywordNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting translation assistant\n\nTask: Translate user questions into Chinese, ensuring accuracy of medical terminology and appropriateness of context.\n\nRequirements:\n- Accurately translate medical terminology to convey the integrity and emotional color of the original message.\n- For unclear or uncertain medical terminology, the original text may be retained to ensure accuracy.\n- Respect the privacy and sensitivity of medical consultations and ensure that sensitive information is not disclosed during the translation process.\n- If the user's question is in Chinese, there is no need to translate, just output the user's question directly\n\nExample:\nOriginal (English): Doctor, I have been suffering from chest pain and shortness of breath for the past few days.\nTranslation (Chinese): 医生,我这几天一直胸痛和气短。\n\nNote:\nOnly the translated content needs to be output, no other irrelevant content!", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "translate to Chinese" - }, - "dragging": false, - "height": 86, - "id": "Generate:OddInsectsRaise", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 8.505454221830348, - "y": 176.7452480823864 - }, - "positionAbsolute": { - "x": 12.765618637774594, - "y": 178.87533029035853 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting translation assistant\n\nTask: Translate user questions into English, ensuring accuracy of medical terminology and appropriateness of context.\n\nRequirements:\n- Accurately translate medical terminology to convey the integrity and emotional color of the original message.\n- For unclear or uncertain medical terminology, the original text may be retained to ensure accuracy.\n- Respect the privacy and sensitivity of medical consultations and ensure that sensitive information is not disclosed during the translation process.\n- If the user's question is in Chinese, there is no need to translate, just output the user's question directly\n\nExample:\nOriginal (Chinese): 医生,我这几天一直胸痛和气短。\nTranslation (English): Doctor, I have been suffering from chest pain and shortness of breath for the past few days.\n\nNote:\nOnly the translated content needs to be output, no other irrelevant content!", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "translate to English" - }, - "dragging": false, - "height": 86, - "id": "Generate:TenderFlowersItch", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": 6.4217969708194005, - "y": 289.41241706707075 - }, - "positionAbsolute": { - "x": 9.616920282777585, - "y": 286.21729375511256 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "query": [ - { - "component_id": "Generate:OddInsectsRaise", - "type": "reference" - } - ], - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "medical Q&A" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:LemonGeckosHear", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 285.6757005660011, - "y": 197.46859232883952 - }, - "positionAbsolute": { - "x": 285.6757005660011, - "y": 197.46859232883952 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Use QWeather to lookup weather." - }, - "label": "Note", - "name": "N: weather" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:SilverDotsExist", - "measured": { - "height": 128, - "width": 201 - }, - "position": { - "x": -298.19983400974513, - "y": -223.95614896125952 - }, - "positionAbsolute": { - "x": -298.19983400974513, - "y": -223.95614896125952 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 201 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 201 - }, - { - "data": { - "form": { - "text": "Receives the user's first input." - }, - "label": "Note", - "name": "N: Interface" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 129, - "id": "Note:SixApplesBuy", - "measured": { - "height": 129, - "width": 206 - }, - "position": { - "x": -1110.7442068670325, - "y": 109.04326530391003 - }, - "positionAbsolute": { - "x": -891.375632399789, - "y": 104.17908459859171 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 129, - "width": 206 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 206 - }, - { - "data": { - "form": { - "text": "The large model determines which category the user's input belongs to and passes it to different components.\n\nIt categorizes user's question into 5 kinds of requirements." - }, - "label": "Note", - "name": "N: categorize" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:WeakSquidsSell", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": -611.6360243646881, - "y": 2.5943909323361254 - }, - "positionAbsolute": { - "x": -611.6360243646881, - "y": 2.5943909323361254 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "Receives the user's subsequent inputs and displays the large model's response to the user's query." - }, - "label": "Note", - "name": "N: Interact1" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:NastyPlanetsBet", - "measured": { - "height": 128, - "width": 381 - }, - "position": { - "x": -267.26820114571024, - "y": 895.5661251048839 - }, - "positionAbsolute": { - "x": -267.26820114571024, - "y": 895.5661251048839 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 381 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 381 - }, - { - "data": { - "form": { - "text": "This part is for web search." - }, - "label": "Note", - "name": "N: duck & baidu & wikipedia" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:AngryCloudsHear", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": 18.438312365018305, - "y": 629.5305133234383 - }, - "positionAbsolute": { - "x": 9.917983533129814, - "y": 597.5792802038565 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "This part is for medial/health issue.\nCheck out this dateset for 'Med Q&A'.\nhttps://huggingface.co/datasets/InfiniFlow/medical_QA" - }, - "label": "Note", - "name": "N: medGen" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:CommonWingsProve", - "measured": { - "height": 128, - "width": 425 - }, - "position": { - "x": 667.6086950648928, - "y": 320.04639793250567 - }, - "positionAbsolute": { - "x": 667.6086950648928, - "y": 320.04639793250567 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 425 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 425 - }, - { - "data": { - "form": { - "text": "This part is for fiance/economic questions." - }, - "label": "Note", - "name": "N: financeGen" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:WickedRocksMatter", - "measured": { - "height": 128, - "width": 208 - }, - "position": { - "x": 806.2393068252843, - "y": 135.72131770444153 - }, - "positionAbsolute": { - "x": 806.2393068252843, - "y": 135.72131770444153 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 208 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 208 - }, - { - "data": { - "form": { - "text": "This part is for weather consulting." - }, - "label": "Note", - "name": "N: weatherGen" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:FiftyWebsReport", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": 988.0143050238387, - "y": -266.8179039129136 - }, - "positionAbsolute": { - "x": 1104.5947767935495, - "y": 17.63844720518125 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are an intelligent assistant. \nTask: Chat with user. Answer the question based on the provided content from: Knowledge Base, Wikipedia, Duckduckgo, Baidu.\nRequirements:\n - Answer should be in markdown format.\n - Answer should include all sources(Knowledge Base, Wikipedia, Duckduckgo, Baidu) as long as they are relevant, and label the sources of the cited content separately.\n - Attach URL links to the content which is quoted from Wikipedia, DuckDuckGo or Baidu.\n - Do not make thing up when there's no relevant information to user's question. \n\n## Wikipedia content\n{Wikipedia:ThinLampsTravel}\n\n\n## Duckduckgo content\n{DuckDuckGo:NiceSeasInvent}\n\n\n## Baidu content\n{Baidu:CleanJarsMake}\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "websearchGen" - }, - "dragging": false, - "id": "Generate:FunnyHandsTickle", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 282.8614392540758, - "y": 444.05759231978817 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting assistant.\n\nTasks: Answer questions posed by users. Answer based on content provided by the knowledge base, PubMed\n\nRequirement:\n- Answers may refer to the content provided (Knowledge Base, PubMed).\n- If the provided PubMed content is referenced, a link to the corresponding URL should be given.\n-Answers should be professional and accurate; no information should be fabricated that is not relevant to the user's question.\n\nProvided knowledge base content as following:\n{Retrieval:LemonGeckosHear}\n\nPubMed content provided\n{PubMed:EasyQueensLose}\n\n\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "medGen" - }, - "dragging": false, - "id": "Generate:LazyClubsAttack", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 554.9441185731348, - "y": 166.42747693602357 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional financial counseling assistant.\n\nTask: Answer user's question based on content provided by Wencai and AkShare.\n\nNotice:\n- Output no more than 5 news items from AkShare if there's content provided by Wencai.\n- Items from AkShare MUST have a corresponding URL link.\n\n############\nContent provided by Wencai: \n{WenCai:TenParksOpen}\n\n################\nContent provided by AkShare: \n{AkShare:CalmHotelsKnow}\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "financeGen" - }, - "dragging": false, - "id": "Generate:RealFansObey", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 766.2368307106321, - "y": -51.15593613458973 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 0, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You‘re warm-hearted lovely young girl, 22 years old, located at Shanghai in China. Your name is R. Who are talking to you is your very good old friend of yours.\n\nTask: \n- Chat with the friend.\n- Ask question and care about them.\n- Tell your friend the weather if there's weather information provided. If your friend did not provide region information, ask about where he/she is.\n\nThe following is the weather information:\n{QWeather:DeepKiwisTeach}\n\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "weatherGen" - }, - "dragging": false, - "id": "Generate:KhakiCrabsGlow", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 996.5291688522603, - "y": -114.01530807109054 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "RewriteQuestion", - "name": "RefineQuestion" - }, - "dragging": false, - "id": "RewriteQuestion:WholeOwlsTurn", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": -859.3797967550868, - "y": 214.54444107648857 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "rewriteNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAFBAVwDASIAAhEBAxEB/8QAHgABAAIBBQEBAAAAAAAAAAAAAAkKCAECAwUHBAb/xABXEAABAwQBAgMFAwUKCAsHBQABAgMEAAUGEQcSIQgTMQkUIkFRMmGBFSNCcaEWJDNDRFJigpGxNDVTcpKi0fAYJSZUVmN0g5OWshcnZHN1haSzwdLV4f/EAB4BAQABBAMBAQAAAAAAAAAAAAAHBQYICQEDBAoC/8QARBEAAgIBAwMCBQEFBAYIBwAAAQIDBAUABhEHEiETMQgUIkFRMhUjYXGBCTNCkRZDobHB8BdSYnKC0eHxJCVUY4Oisv/aAAwDAQACEQMRAD8Av8UpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppStNj19P19v76060/X9h/wBlcEge5A/mR/D/AMx/mNNbqUJ19fwBP926VzppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpWwuIA2VADQPUd9JB2RpWtH09ASf7RTTkD3PH2/r+Nb602O3r39OxP9vbt+Oq2ea32+L1T1jsd9Gt9Wtb1r+8fWvJeSecuLOJ4Zk53mdnsrytli2GQqTd5pIGvJtMBuXc1A79RGCdg/Eewqn5LLYzD1Jb+VyNLGUYAWnuXrMNWtEq/q75p5I41P/ebx99dcs0MCGSeWOFAAS8rrGgB9iWcqADweOT516yp5pAJWsJCUlSioFISkdyVEgBOv6RBrUOtqAKVdQUOoKSCpOvr1AFI/EiopOQvaVRGlPweLMCdnrKEhvIM2mCDFCgnRDVhtRlzXx1HsZN4i71soA7DC7MvGD4iM4LqJvIc3H4To1+TsPhxrAygD5e+tF+8/L5XU7+ffuMetzfFR0xwLy18bNk91Wk+jjDUxDTWU/4WvZKWpBLGv+KembUR/wBW78+LWub1wtYlYTNdcewroVT7e8swRPPnjtLjx5I5BNhq5X+x2WP73ebza7RFH8puk+Lb2P8AxZjrKP8AWryC9+J3w+Y9r8p8v4KnffUG+RrwfxFoM4j8QKrdXG6XW8SPe7vdbpdZP+Xut1udwf8An/GPSfJ//F9fTt2r4QAFbSBr71Oo/s6HFHt/+1QxlfjLzTlxhdlYqqPHpyZHJXcmfYcloa1fDngH7esOeeOfpJNvTb/sMSK2PgQDjhp55JOeePtGkZPHnnj2/wB9gm4eOPwzQu6eQhO/+m49kL36vt2pPr3/ALq6T/h7+Gn/AKTX7/yVkn/9XUCnUf0VLG/qpDf1/wAkyr//AD8K4tH6f66v9lWjJ8XfU925jxeyoVHtGMZlm4/Sf1Pmk59vsT5B545B14DvrMn/AFWPH/4JW/8A6sNx/Tjn786sEW/xzeGeb9rOpEL1/wAY4vkrG/u+GzqA1+2vRrH4pfDvkS/LtfMGEKX66n3ZFm/beEQB+3v+NVs9b+0Gz+ppLn/6pH+/fW63lZPZQ2f5wLij8/57qSPpXvp/GH1AhKm9t7aVxB+oQVsrSkfjj2k/a1pY+PtzWcHzxx2nnsj35lVb95VoyKePCrYjPj8MZZV8j7kDjj78nVqm0ZPjd/YEmw5BZL3GPpItF0g3Jk/97DfeR/rV24eaUSlLiVKSAVJB2tIOtFSR8Sd7GtgbqqNCmTLY83Ktc2bbJYHeTa7hcbU+P/uEOSbn6/SVr7699w3xW8/4KWm7RyVfrhDaCU/k/KFR8qhqSkgpCU31qZJQBr4RBl2nXyHfVSLg/jKw8zxx7j2bkaCt4eziL9fJAMeOD8rajx/aoHuWtnnn3XtPNXrb+rseLdCWIHj64JFmC/nuRhEx5Ht2k+Qe7t8c2PPPaCevr+DXV1gKKdfUKAIP4Gt4Wk+hHrr8fpUReAe0pkoWxE5R4+akIKdP3zCZKEPD7v3PXhbSCPn8OQH5bB1Wf3F/iL4d5caQjDc2tsu6FIK8duS12jImV91HotNwRGmyAACCuK3ISPmvv0nIbZ3WTpzvlo4cFuWkbsvAXFZDvxeTMhJ5hjqX1ge04A576XzEJ+0h5Xm6qGfxOSAWtcj9ZgOIJuYZ+T9hFIFL8cHn0nk7eQW7eQD7xSuMOtnt1d+nr0QoHp+uiAf19tjvv0NbgtJ3o+nr67/sqTwykcggj8ggjyAR5/kyn+TA/carBIB4J4Pvwffg+x/rrdSlK500pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlK+d2VHYQ448820202t11xxXQhtpr+FdcUrSUNtDu6tRCWxsrKQCR+WZUBLMqgAkliAAAOSSSQAAPJPsB5On/AA8n+X51v89rW+saB0o6OkEDZDh1ps6+Syk9wNbIB8W5b53424VtaJ2bX9qNOlNFVssEILm5FdXNlJFvtLaHXkRtpUlU19LEFB/hZKdgqwn8SPjyh42/PwvhVyNd70wn3S5Z5JCJVmtDp6QY1gjuAxr7NAAAnOKXakkqBkOHpWIkr/kF8yi7zb7kt0n368XJzz59yuUhcuTJf/nOvvL81cbXb8nsphxvvrEvqx8UGG2xJbwWyIq+fz0BaGbKTH1MDjbKsFZU9NlOWswMHBWGSKorL2vZLs8cdkZzeVeiWrY4C1aVijS+9aBvHI7gwE7DnnvRggAHIPPGs2OYfHvypnipdqwAI4xxhxXS29A8ubmU1vpCVKn3xwlm2ElIIOPIhXJO+lN7ArB2VOlz5km4XCTJn3CV/hM+U6p+Y99PMkylyXJuv+tEGvkpWBu6t67p3teOQ3Rm72Xn5b0o7EpSrUUuXCUqcPpVqcYJ/RXijVj9UgdyXMZXchdyUnqXbElg+e1X4ESBuOVSFQsSA9o57UBb/ETwONT8Xr8O/p6+v3b2a0pSrX149KUpTTSlKU00pSlNNKUpTTSuRt15laHGnVMus78t5lS0vtd/5I80YklB/wDmSkj++uOlASCCCQR7MCQwP8wQSPyh5RvHercDh9+f+A5/o3Hcv/hI5+/PjWZnD3jj5k4yLFsv80cj4q2fLVbMjluG+sNa7G3ZWiP782E9vhvMe/nWwOnZNS6cK+JLjHnCCP3L3pUTIm43nTsRu/REvsNBA6n4zXZq7QvkLhanpsE/Dp8HW639fdAuE20Tot0tM6ZbLpBlCVCuNsfcgz4r3/O2ZbJS4Z3y89f73/8AgTWQfTf4jN9bHlr0slZk3Xt1PTR8dlJ+6/WiTsAGKykvdLAyhFEVay0lFWAVVqRtJMt04jdmSxvbFK3zlMcAwykCZEPHPoTEjtI4H96JR4+kDzza3DiD3B7a3vR7jsdjt3GjvY2K31EX4dPHxIZcg4Zzm956SREtnIjCShQcAAELJ7c0ha3CAP8AH1tQ486dhyCkrLqZZodzt9xix51vmR50KXHalxJkRxMmLKivgKYkxn2StqRHfSpK2HmVrbeQpK21KSQTsO6f9Stq9ScUclty8JJIQgv4yyBBlMZLISqxXKvc/Cs4Kw2YJJ6lggiKYyLJHHKmMy9DLwetTlDFRzNC/wBE0B/+5GeGCcg9svAR+D2n6Tr7qUpV/wCqnpSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlfK/OiRWXJEl9uPHaQ446+8S2y02yguPOOurAbbbabCnXFrUlKGkOOKIQ2tSeCQoLMQqqCWYkAAAckknwAB5JPgDT/wBf9gJP+QBJ/gCdfPcrxa7PAmXS6z41ut1vjuS506a6mPFhxWW1PPyJL7vS2w0wylTz63FJSyykuulDY6qhD8VPjMuvKb1wwbjaVNsnHTa0ok3dnz7decyeRogyepLUu2Y6yQCzB8tqdcFD/jKO0kIQjg8Yviskcs3OXx1g0x1jjGzzENXWRHX0u5xeW1+Y25JUkodaxiO7pceI4ELmPpTcbglK0IttYGVry6//ABB2M/Pc2Vse89fAQmSrms3UeSKfOSqe2anRsRsrphlI7ZZY2BypBXk4wj5+K9z7qa08uOxshWqv0WLMZI+ZPjuhicHgwDj6pUJ9XuX03XtbudKfUJbCQnykJDflqjsfzI7KNx/M/prWB99KUrDwAD24Hv4AAA5JJ4VQF5LFmY8dzMxLE+ALD/l4HPPHn3PHJ5PJJPA55J9vHGlKUrnTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00ISQUK2oK+FwdCHGVHvp9CXSlaVfd0hVZi+GHxaZHwbcImO38y8i4wlyFiRaA85IuWLLWrqcm449KcbCYSlEqdtSlFu4KJWtFqUSTh1Srh2turO7MzVTP7cyE2OyVRuRJGS0ViJivrVrcDExT1rCr2TxMvDA9ylJFR19VK7Zx9iO1UlaKaM8gjyrD7o6/pdG48gj+RHJ5tT41leO5jY7ZkmMXaLebFeYjM22XOIVmNKjvFSE9JcQhbb6HUqYkRHkty4slKo0lll9JbH6Gq+XhV8T924JyIWe9PSrhxhf5aHL1agC9IxyfIb8tWS2GOkLQ3JRpLN6tbB91nRUibF94uJLJn6tl5td6gQ7raZ0e4W24RI06DPir82JKiTGkPxZDL6R5a232HWnmyFbU0425roWlR2p9IerWH6qYD5yH0aOfx6RJnsKJCWpyuAFtVi/wBc+NsuG+Xn8sjA15wsycvNOCzlfNVfUUCK1CAtqAkfQ55+uPkktCxVuxuSPBHcffXZ0pSpc1XdKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU01xF5tJ0SrelHQbcPwpGyrsk/DrsFeilfCklXaorfHt4knrVEd4Swi4rRNuLXn8h3OEtSJMG1OJ86HicN5IQGJ9z6Em9pGi1aQ3DWvz582OznF4geWoHCvF+QZxLS3InsNNwMet7muu55JNcS3Z2EbJ3HYkFcyQlwhKIbUhS1NpbWDW+vF3uWQXe6329THZ93vdwevF2uLqlKkT7nMc98nyXyrsH3l/vNjoPlNI77S38VYifFH1Wk25h4ti4Oy0WZ3DWkfMTwsVlx2Bk74/QV1cNHYzJR4C/HMON+b4DS2awax945tqddcbWftsWwDZdSVaGoCpZAeee6wCUBHBCBxwpII60gKShA2B0+V09CG2UMd/gWlolanP6YSofQilKVrq/l4HPPHn3PHJ5PJJPA55J9vHGon0pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKkw8CPiQcx24xeE8ymuO2K8THkcfzZC0qTYrqtzzZWNuu/nFi23FRckWRtek26Qt6HJ8iJNC4EZ9crL70d5mTHdVHlR/dnYsphSm3Yr7f25KFJ0RcUn+PT+bPyWavPYG98t093RjdzYli0lSVUu02cpXyWNlZRdoWCEkPbNECYX9NjBZSGxGUsRQutRxWRnxV2K5ASSh7ZY+QFmhYjvibkgcNwPwRx4I882v1PNp9SfkOyFn1Oh6JPqfT67GvUb5KxU8KHNiebuLLddLhJacy/G3kY/mLCSFKfusaG0Yt4HSEpMa7QlCUhTa3UpktS4q1ImQ5EZnKutwO29w47dWDxe4cRL6+Ny9KteqSHgOEsRhzFKoJ7ZoHLQToSDHPHLGQQgZp3qWYblaG1A4eGeNZEYcexA7lYcnh0cOjqeCpXtIDAjSlKVXNejSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTStnmI7dz33+ir5HR327d/Tet+o2K315/yPmUTjzAswzecEKjY1YbheOh1YQiS/DilUSKFfoqlyy1HRvQC3AVEJ+KvJfuQ4+pZv2pEhqUq89u1M/6Ya9aJpppD5XwsaMeOeSeOPY6/EkiRI8khCxxo0juSAFVB3MTz+FBJPsACT41Df4/+WnM05Sj8fQJBcx/jNHlyEBxXkScynRW35010aHmps1veat5bAWUSXbk2nby0pOA9fbdrnOvlzuF6uj7ky5Xe5Srzc33FlS5Nyuz7k+8L6id9D9xlOONJJ0hmMlvttAV8VaZN77qub23Xnd0Xe8SZfITWIYnKk1aUYWtjqQ7fcU6EFaAN5LlS7M0jOxx/wAlefI3rVyQnunmdlU8/REGKxoD+ngKOQF/JJPBHClKVauvFpSlKaaUpSmmlKUpppSij0gFfwdXp1/AfxCtFP8AWArVYU2NrStH+ehST/YQD+yueD+D/kdB59vP8vOtKVpv7IOwpfogghf4tkBaf6yRWtcf8fb+OmlKUpppSlakEdOwR1q6UAghSlj7aEpICitn+UJA6o38oDdP+f8AYT/uBP8AIE/bTQgghOiVEbCANrI+5A2s/q6d1ofhJSoFJHr1gp/aoAftr17ivgvk/meYY2C4y/cILMhQuN8ndEHHLQEjZYcusl6MXJgHcwGFuzgO/kelZ+Yp7MaSYzK845TDD4351tw2xtGKB+j03G8LaaX37HePJ12I331I20ekfUbfEC29ubXv2qDglclYNTHY5yCQVr2slcppc9jzJXBUcAEDvTmr0cDlskiyVKjvCwBEr9sUZB9irysiuCAeezu7Tx3ccgGKUfF9ghY+rZ8xP+kjqT+2h7EhXw6+avhB/wA1StJV/VJqYyd7MjBnmSiDydmzD49HLhbsaubJ+7yjCjH8dj66+VYzcl+z95fwiNIueHXC08j2yG0XjBtiE2HImmh6FGPyHU2ySo6IDTE515XSdN+tXFnfh76uYCtJbsbTsXq8Ss8jYe1Qysyovbyy1KdyS6/Hd/8ATKg4+uSPle702drZ6qhkei0qDyflWWxIPb/VIwduefHaDx9+NYGUr6p0GdbJcu33OFMts+3uSGp8C4xX4M2C5F/wkTIkptmRFEf+PU+22lr9Mpr5ahhlZGZHUq6MyujAqysjMjKyngqyurKwIBVlZSAQRqgEEEgggglSCOCGHupB9iORyD5HPnSlKVxrjWXHgu5dXxbzNZIsyUY2L56IuKZA2soRGjyJDqk47clIJ2hyNfFyEPOdHwsXCcXSllSFGwZ5qDvRJ0QCQlZGypSNbCdHSknq19gfErSSCanYU4khbZ8twfnA7sh1qQXve23W1o7pVHf7JII7907HerKXh25EVyjw1geaPuoculws7cO+LSQ5q92mQ7aLo4oAjpVNkwHJLaQk9LUhCtqCwVZ5fB/vh5qW4NhXpmb9ngZ/Bq7hilaxOkOZqopbuEcV+eC0naO1muTSDwTxJmwsgXjs4tz4i4s1QWB4iZo45UA8soVijfVz+8kbzwQNe7VsDiFDaVbH6j+0a2D9xG631g/x/wCPbw3ZhlF7wK4Zs3x1nNgv9zxi64pyMyzi8pi9WmTIhzmWL24peMTnG34khlKYd5kKeWhAZS4l1lS89cbt7P5qtkbeFw+QysOJihmyT0Kk1z5KGdpFimspXWSWKB2ikUzmMxRsoEjKXQNXs9vPae1rmHo7l3Hh8BZz8tmvhUzF6tj0yVmr8uZqtWe3NDFJaUWoTHVQvPOHJiRhG5GcFK+ZE2K6hDjbyHG3UdbS0bUh1HT1dTSkgpdSU9wWyoEVyB5pQSQsEK+ydHROt69PXXqD3HoRuqQfB4Pg/g+D/kfOrlDKw5Vgw8eQQR5AYeR+QQR+QQfY65aUpTXOlKUpppSlKaaUpSmmlKUpppUfPtD8ycsHCcPF2HXG5GcZXa7e4gdOnLRa21Xm47AJ/NKkQYMVxCtKPvu0pU2l1SJBqhs9pjkLsrNeNMVG/LtmL3y/OaPwiVerhGt0VRSdAlCLJJSkgHpC1dRSFDcJ/EPm3wfSPds0TlJ8hVq4WLt/UyZbI06lpEAIbuai9ocqeVTvfj6eVt7dNlq2CvMjcPMiV0/PM0iKe0A8klA4PAP0lvGoyqUpWpvUIaUpXeY3jV+y++WzG8atcu73y8SREt9uioHnPPbVsuKdU21FYQlJcclSnGIrTKm33HksutrV2RRS2JYoIIpJp55I4YYYkaSWaaV1jiiijQM8kksjKkcaAs7sqqCxAPKgsyooLO7BURQSzMzBVVVHlmZmCgAEliAByRrogpJICVoWSdDoWlez93QVU2NhIIK1d0tpIU4ofVLaSVqT/SSkp++pXOP/AGaTr9siy+Ts9mwbi+xuTYMMjxJESA8f0U3bIFXOK+d9j5dh6AO4Wr0rruS/Zs3aBaH7hxdmj9/uEdtTgxrMmocV+4pA2IELIIjibdCUoggOSbM20O3U6BsibH+HLrBHiTl22o7IIfWNCPIY+TK+n4PeMes5tNN7/wDwAiNrnxzq4v8ARPPiD12oH+79QxLNAZgP+oIhIXaT/sgc+OO3z4i1pXY3a0XSw3O4WW9QJdrutqlOQrjb5zC40qHLaWpCmHmnQkpcUR1Mgb94bW08wXGnWlr66oRdHid4pEaOSN2jkjdSjxyIeHR0YBkdT4ZWAZT4IB1bpBUlWBDKWVgQQVZSVZSD5BVgVYHyCCD5Gla9Ku4CVEhbbekpUoqce/gWmwkEuOO/xTbfUtz9BKqaOifQAqBJ7aKE9at/cE9wfQnsCT2qXHwQeF62xbFa+a84s7dwvV1bamYJaZqG3GLLbQdN5O5Df62nb/dk/nbY3MbSizsEee2w+olq/OnHTzNdS9ywbdxBSuoia5ksnOjvWxePikRJbUyL2mV2ZxDVrq6PYsskalU9WSOpYjFWMxcSnBwngyTTPyUhiUgFiB5dySBHGCGcggex4xD408E3PPI8ONeBZbdh1jkN+bGn5nNl2uXNRrYJs9ubn3iKT8hLgR1emxqvaZvs0eVmGC7bc249lygN+S6xf7ag/d1MxZKd/rIHbQPzqaANHXprqHSQFnYA3ogEdAPfuQPU996r6az0xXwndK6lEVr8WcytwxoJsjNk5KMjysg72hr0FhrQxhv0RsszoQQ0jc8mTodk4aOFUm+Zsy8Dvlaw6t3DjntCdoCk/c9xIHHOqyXKPBnJ/DUtpjkHFX7VFlLS3b71BW1Oxq5PqBKYyLvFflIZmKA2Ij7rUnXozXkpBGgR69X36CftKUR2ShPzcVpA/nVajvuMWbKbTOsGSWmFerJc4hiXG3XJtMqNLaKNEOMK+ArJUSmQktPpWltQVtttSa/Pip4Bd4Gz9MK2mW7g+UNSbjiz8gJediRlKSm649OdbK1uPQwtDjK1IQZLSupgLUhxKMZet3w+T9Nao3Jt65Zyu1WsRQW47oiGRw0tlkhgeeWCOOC1SlsOkKTrXqlLDxwSoiTxWjZu4tqyYiMXKsjWKRZEcScGeBpCqo0hRUVkZiV5Ea9h7VJJZecYaUpWM+rQ0JAIBIBKAsA9tpV6a/pfVH20/pJFZp+ETwrSOcrs/lOWocY41sU5yDMSha2Z+YXRnoU/aGHlHqj2ttKym/vxwmSuQkxitDqXA3iXiOL3LM8rx/D7N0ruWS3u2WKAVgEtSrs+1HkzOpRS2luK86hJC1pAQS6NtIWtNmvjzAbNxth1gwjHoymLRjtvjwox6WUOy3UKW7NuElSVKK512mOSJ1xdVoOvS1FJCis1kn8N3Sen1B3BbzW4IDPtvbT1WkqFW9PKZeYCWvRnYDlqdVY5LF6MOqWUatXlBhndJLu2ng4spcezZUtSp9vdGy8+rM4JWNjxwVVVJkQcNw8Z5UHXeWTGbPjVrhWXHrVb7NaLdH93hW63s+6xY7etFDcdr82lfYEyFl10qKydlZUf0VKVs4hhirxxwwRRwxRRpFFFEixxxxRjhI40QKqRoDwqKAi+e0Dk6mFVVQFRVRQAAqgKoAHHgAADSvnU2r7ICiBoghfQCR6IUsbcIBJP2SPT6ar6KV2ce3k+PI4JHn7HwRzx9geR+Qdc/kEAg/Y/w/5/2nWI/iS8K2M86WiRcYceFZORoEZDthyhLKECY/DPmRLRkjbZ1c7W4oqbQ86hci2bS7HEkJUw5ANkFgvOK3u7Y5kNukWq+WOa5b7pbpKR58WU0vpUkeWpbb7SklMhmTGW9GkQ3GZzDzkN5p9drGojPaOcRRmF41zXaoaGH5U1OI5goBCXJTyY737nLkpLRKlL8iLLtUh4hSlQmrc0tSVhCThx8UHSHHXsHa6i4GolXMYkrPuKGtGiR5TGMyRzX3iUoi3ceoWWawvaJKQsS2RK8EZNg7xwMU1d8tVjSOzCQ1wKO0WIfCmUgDxLGxVmccL6ZkZh4DCKqlKVr31FulTB+zTzRU3E+RMDdecIst9t2TWuOrRW3BySD7vLbRraUNx5VnafUlRG13FXSkr6wIfKz09nbfzaed5tn2ry8pwe7xVAKUELfs0m03VhZSP0kx2JjI6gPhcVo9+8zfD7mmwnVzZ8neyQ5O5PgrKgkLLHmKdinCjEEHlbz1J09wHhUlW441cG1rJq52gwJ4md6zj35WZG45/AEix8E+A/YOCSAZ1KqEe0uwZvBvGPymI7DLcDLjYeQYyQSx5y8hsTZurgdEd1bMsZBbp9wU9GCQtS1N7Lqgmre9VtfbU4siBzBw5l6W0pGSce3SwHQQlTkjGsnYk9bhCt9TbGVx2OpWgpsgNkhtzo+g34Q80+N6uRY31XSPcO38tj2CuyfXU+XzCuCjI/eIsbPECG8JNICPIZcfv7RPbiZj4fmzATifaW78BlVnXvWSOHItZ25KgeMhlSWXM1i/BHmJGDBkU6wN4F8bPiG8Or0SNgmbyrhiEZSUP8d5f5+RYZIhgaMaJAlyFTrEVAALVj9ztXWnaVKIUoKn98L3tMuFuf12/GsweRxRyPKQWIllv8lp7GchloRsjFMrU3GYky1kkfki5CDcgUqSzHc3sVTq5utI6lAqCnT+cAQkgLPq8hRUhSnR/ztCosr+j2rNzqX0A6f9SY57FrHJhNwyBpI9x4eKOG686qGRsnGFEeVjYoqP8ANd1sJxHXsRAtrVv0R+Lvq70Xnq0qWak3PtGHsjk2huazYu41KwIWSLFWnaW5hHERlMQpmSj6zd1nF3eVVb8ipDKe6l67pT6KPdZ0gHQOutXwJ39pZCBtR1XNVWrwb+05z/hV22YFzJIuHInFIXFhQ7lIddmZtg0NCS2pVvluHd/tAQSldjnvFy3NhCccmW+GkWkWZcHz/DOSsWtGa4JkdsyfFb9GRKtV6tbxdiSm1KLakHrS27HlMOpVHlwpTTMyFJQ5GlsMSG1tp1qdUOj+7ulGRWtnoEtYu1JImL3BSVzjcgqAuI27gWpXVi4ealO5dSsrQSWa8Ysvu66D/Ef086/4SS7ta4cfuChFHJnto5OWFcziS59P1kCER5LGySqfQydPuh7ZIYrcdO4zVl/YUrZ5iNEhQOhvQ7nX16Rsn8B3rfUV6n/SlKU00pSlNNKUpTTSoHfaGTXpXiEVEcJDdtwDFY7A32C5EjIZTgAHp+deZ2ddPx7BPSvpniqBT2gqFI8RlwUsdKXMJxB5B2PiaC7sgqABJGlMOjR0rafT4k7xh+LZmXpVCFYqH3TiEfj7oKmUk4J49g8aN+OVBPtqzd9EjCDg8D52tz/m/wD6/wDI1hFSlK1m6iHSpYvZs8eW5yLnXK8uKh65sXJGE2Vw7W9AjNRIV6v7qOtBHnS5E22xGVtqDgtMVLKesrW2Ynalf9m3yTbY0fOuKpr4YmybhAzawJdUQu4Jetcax3phjt0uLis2S2S/LCvMcTMdLKHCy+Wpz+G84gdX9sftf0+GXJDGGbxEuWXH2JKrM3I7X9OOwtYlgouNWYK0qxcXLtEQft6p63YPpmEXf28euYz6XHd4LBwCoH1dwUj24MtNbSOpOiNb/H/f/cUK0jsT3+mj/s/bW3zWyNhW++joKOjrfca2Br5nQPyNbXO5RzyR4BJ8jwB7k/wH3P21Nf8A5c/08ef5eR/mNQ3+0g49tdmyfB+SbfFTGmZYzPsd/DKEpMufZ47P5Gu8hohIXNYt1wnRnFAKVuFbnF6bjqUiMupLvaPcjWm+ZZhnHlsmCTIxJm7X2/qZUVNxLle2ItqhWpw9IbEtmFFlSXmULWtj8oNB9DLjTiUxo1qV+IE4j/pd3kMMYmri7VFsweYzljjKTZftflu5hkGsLNw3CWRPF2oyMiwhuownPXzAEC+ogf0+3tEwij9UDt8A95JcfqDli3k8Dv8AFrMckyfG8dB0MkvlispIIHR+VLw3E6h3AClsPNk99p6tL6SFBNpK22qNZ7fBttvYEeDbojEKLGSE9LUWK0llllKUkJ+FCEgH01vq7k1Vsxa8qxvJ8cyBtPWqxZFab2kHff8AJ93hSko16kIYZcXoAk9PSNrUlJtK2u9W+822FdbdJakwbjEjT4Uhkl1uRDmMiREktqQNqakMEOtK0OpBBHqKyG+DEUDBv88J+0jNt1pCwX1BT9PJJGqd3LFPm4pXk7foLPB3All5unp/6fp5QeBL6lQn25MTB2Ufc8CTlW4P6u1f1AHXa0pSs5dSNpWCntAcUiX3gC4XxaFGbhmS49eor2h1tonyxYZjaVK0S0pq6h9SEk9aozSEpU4EprOusEfaCZhDsfh+mWPzG/fszyTG7NHj+YkPIZt86Jk0t4I33DCbVFQ7s9SUTUH0UCYy6yiielu/DkRGaybWzEgLgHttrUcY50B45dMi1RowPqaURqnLlRqkZ4xDC5MzBSgpykBuP7zjiIjn/GJCnp8eTJ2AckgGCWlKVp81A2svfAnZG7z4kMOefQlxqxWjLMhCHAlQM1i2pgxux77Zl3EOoWNpStkLB0kKqwXVfXwMXqNZvEjhqJD6GWr7acjx5BUTtb0yyzrhEbQACfNfdtqUpQfiCulKwla0JXYH609vtdyAB0L331310713G1a0O+yNHWyb4QzV/wCjTJiJlNhd2ZFbXhRJx+zMRLX7gOG7PQkVl7ufJkZT2t4lzYvYcPIV7S5vTCQjju5CRKgbj7lRyAfPkn2IA30pSsqtXppSlKaaVi34w7KzfvDjyrGfSlbtusLF6iLKR+al2GZEuqHUE6CVuNtqYK0kfA6psHSlAZSVi54xb3Fsfhu5SeW8lDkywt2OOFdW3pV4mQYTbQIB264hz4QSOw2SAQasvqN8r/oDvUXWQVTtPcRm7wpBRMVafwGB+oFRx+BySD4Ip+VKDGZEyAGP5G0XJ+wELH3Pgff3+w/nqu2QQdGtK3KIJJH+/attaY9Y/wClZT+Cie7B8TPGYQdImycrtrvfW2X8MvjrI13PxyojKdfonSldKQVDFismPBu0p7xNcShG+oXq/uaHYdMfEclW8foAhIPqR1dgnqJAq9Om8jx9RNhsh7WG89scOByV/wDndHjj/vniI889wkKDhmUipYc8ZXH+eD85W/n/AH8f/J1YwqBb23Nvbdsfh4u4T+eZvXItr8ztsIch4vPQgH10V29Ct60CACQSNz01BN7bN5CcL8P8clIdcy7P30pPr5Tdisza1g+nwrebTrfUStOgd19B/wANTunW/YnZz9dnMRNxz5jk29llkU8fYoST+OOT4B1aXxtxRS/C/wBVBLwQlPbcq8kDtePee3HjcE+AwkVFB+/f2D6nUivRSlK2+6+crSs1PB340s+8J+aokQ3ZOR8ZX2XHVnGCPPqbhzmlBDbmQY6ypRj2XL7ey2lEcNFu03KOlNruDxYTAn2fCulUTcW3MLuzD3sBuHHwZPFZGBoLNSwCUIPDJLGwIaGzXkVZq1mMrNXmRJYnV1B1dOzN6bm6fbjxm7dn5a1hM/iLKWaV+o5V1K8iSCdP7u1Ssxs0NyjZWWpbgdorEMiHgXpeLuU8J5iwiw8iYHfIt/xfIIzkmBPjrKS26w4WpMKYwpKH4M+G6h5mZAmNMy47jS0PsoUlQHpdVF/AN40Lr4W+QxZ79Jlz+G80mR42aWhtK3F4/OfCGmc3skJHWlLtmShEK6QogclXzH22lmHKuse3RbZbXt93tl1gQbpbJ0efbbnEizrdOiuB+LOhzmm34kqK+31NvsSGXWnGnG1KStC0qB0RWozrT0jyXSXc7UW9a3tzKGWztzLSKAbMCuolo2ioEaZKj6sKWY4wEkWaGxEFWf0ovok+GT4icH8QWx1yafL4/eWAWtS3jgI5Cy1bcqO1bK47vd5JMLlkjkkqF3klqWIbePsSzS1fXm7GlKVDusk9KUpTTSlKU00qD/2kVpMXmfEruW1Ni78fx45XodDrtryC8IWkEEjbcWbHJ2QNOBO+oECcCot/aX4qqZivGWasMqUiyZBecdluJQd+TfYceZFS56LCEvWN8IWAWwt3RUFOthUBfEzi3yfSDcDxr3yYu1icqg7Sx7YMhBXnPCjntSpasu5+kKiF2YIjA2zvCv6+Btke8DwWB+OI5QG5/h2uT9uOPcah/pSlarNQrpXcY/kN7xe9W7I8euMuzX20vtyrfcYjpQ9Fdi/YSz0K/gZPzQvsP0wmunpXZFLLBLFPBLJDPBJFNDNDI8csM0MqTQzROjK0csU0ccsUqESRSIrRurDnXKsyMrIxVlYOrKSGVl54II9vfUpWA+0omwbaxB5KwB69XFhkMG94jNiRG5xAAL8yy3RTDEcnW9RJjuvRKUgkHruSPaRX68WyTbuMcJGLypDBjm/5VKjXuVDJBHn2+ww1ItrygCf8OuLXUSCUdhqMalTM/wAQ3V+TE/sht32RH6QhN5aePTLGMDjn9ppVW2J/uLgkF1TyyWVJJNwHdWeMHoftBwvZ6fqLHCtjjxwfmBGJu4ceD3+POvsuVxuF6uU283ifLuV1uUt+dcLhNdL0udPm/wCMbjKcJIVJkfxISSlr+jXx0pUMSSPLI8srvJJIxeSSR3kkd2PLu8kjM7s7EszMzEsT544At8kkkkkkksxJJLMeO5mJ5JY8Dk/w0qWvwN+KW0mz2/hnkK7N26ZaAqFgV8muAQ5lsQ/0NYhPlFZYj3O3Mgps6JflLRaA1EcW1LZTHciUrTRGyCCUkqQAPL0P5ramyFok9v8AGBIk/fV8dOuoWb6abkg3HheyYmJqeRx0xZa2Ux00kUk9SZ0DPEytClitMikx2oYu4tE0kM1TxGVsYi4luvw3gpNEx4WaFgQyH6lHIPa6n3DopB45DWxwtJAUDtJAUFAHRB9CDrXf5d62h1tQSUq6grelJBUk69T1JBAH3k6qvJxt4zOd+NIsa2RskjZdZoaiiNbM2hG8KQ0oaJXeESGb8vXySq5q0dnp7nftFw9pHy9JiFuDhvHtumLGvfVNX+4Ka18xHcuMRpR+7rUnX6O9Gs9cZ8WfTG5QWxkFzmIvBAZcfNjHuHvI969mjJPXmi55AM71J/bvrR+AZLg3xhZI++YW4H8cxGD1CP8AxRuVP/68fx+0y2SZZjeIWW4ZFk94hWSyWqOZNwuU9wsxozQBPxqKSVOnWksNpW+tWkpbKiAa+fim59e555CN0gCXDw7G48u1YfAe2FraeeSzMvs9pxfa5XNxBmNAJSpiyN2+C6lFwbkMJ845L5q5O5emiTn+Wy7yxHV5sOzNsog47Be1rz7ba45S2xL1oBcpEpvQ+16V5XWMvW74g7XUuum3MDRsYjasVhLNj5xomv5qavJzWa3HE0kNarA6ixFUV5mFj0bJsGWvXaK0NxbpfLJ8pUR69INzJ3ketZ4XgeoF5SOLuPcsau7hlUu44AKlKVjTqz9d7imSXPDsnx/LrKUt3bGL5Cv9sW6d7mwZUZ/StbHlSGG34ykHQ6X1BWkkmrNPHWe2TkzCsczjHnEu2rIrXFnRx1bdjOP9SZ9tfSelTcu2yG3okppSUralR3o6kpdaUhFXmsy/CV4pJfBd5exrKHJlx40yGYpyc0wlTj+MXBSENIvtvZT1urjOpbZYu8SM2uVIjNMzI7Tlwghi55IfDh1ZqdPNw3MNn5zDtjcprLNact6eJytdlSrflAACVJ1eSLISksYlMUoQwwsI7t2nnI8VbavaPbStmMPJz4gmRexJSvPHY459VvsVU8j2M/tK6HH8ox3K7PAyDG7xBvdluccS4FztzwkQ5Uc+jrTyNpKfl30d9tb7V3nWgEAqAJ9En7X+j6/srZ3DPBYhisV5op4J4knhnhkSWGaGRQyTRSIzJJE6kMkiMUZSCCQdTErK6q6EMrgMjKQysp9mVhyGB+xBIP21upW3rT376AGySCEj+sQE77+m91p5iNb3ofeCP7wK7ORwTyOB7nnwP5n7a5+/H3PsPufb7f1H+Y1oXmwdEnZ1odCyTsb+EBO1ADuojYT+kRURftHOXYcx7HeG7PKQ6YMiPmGYKaKh5MlCHoeOWyQehKUrbRKm3B9glSw6m1KWAplwN5ZeJfxW4nwdZZdrs8mHkXJMxlbdvxxLheiWdT+0i85Q6yXFWyBFJ6zB8xNwfSpIjwnEKC0wK32/XfJ73dciv89263m+XGTcbtPlKUuRMmuf4PIfJ2Pd4/ohhB6k/JFYZ/E/1gx9TC2unGBuxWstlWiTcc1ST1ExWNSZJGoSSKe352+VWOxWBMsOONgyRLYnrxCwd552KKq+KqyK9icgW2RgfQhDKWi+lj+9lBKMrA8R94ZAWHHT0pStfmot0rMnwF2wXHxIY1JLalt2XHcuu3mBOw0tduet6Fr7bT1JnOIBPfagjWyAcNqk/wDZo4st/K+Ts3Ughm1WSzYsyCkHqlXmW7eZaUH1BbZtkULP2AmQE9W9gSr0QxcmY6sbEponcIs9Xych7SyrFhIpsy5fwQqkUAO48fX2jkE6re24DYzmOQAkLOJW4BJ7YQZufAPA5jXuPsF7vb3ExNV5/bbXtD2R+HrGG194Nqz69yGeo9YFxnYpDjOqSQElLiLJMR1J6iklSVhJUnqsMVVc9rxmIyPxZJsKV9SMD44xTHQEK6kNTLxMm5PJWvW0h4oubLTuiVIZQ2V9KFJ39Bvwn4t8h1kxFpV5jwuIz2UmYjlYxJjZcRCxA8km1lYEUAqSWADckK0Nf2gmcTE/Ddn6DEh9zbi2vg4QDwzPBlE3Gyg8+Q0WAkVhw3IbjgfqWLKlKVte18/OlKUppoQkjSgSd/aSSD+Hz+/1qxB7JLxVryKyPeGbM55cu2Jw375xrLlPKW5NxYjzrxiwedV1LmY7JkP3G1xnVh9OPypTCUJRYQhuu/XonF3JF/4l5Hw3k7F5K2cgwfIYmRwj1rSm4LhuKjqtsjpKR7rdrWuTb72lekyLfcZzTZLykJEY9XundPqdsbLbbnjjGQEbX8BcfwaGcqxS/Jyhh9SxWUeeha5PY1W3KrAOY3Sdfh06x5Hof1QwW8a80xxDTxYrdePjPKZPbF2zB+04DGWCvPW9KHI48HgDI06jSMsAm5vTl5sfM72BoIWVd1+WPhCerXUdFWtAfESE965a834zz+x8o4FiPIuNOh+w5lj9tyC2OBJK0xbpGL647iulCkOxn0KYfS6G1svtLZWhC0BI9IrTFYr2KdmxTtwvXtVJ5a1mCRWSSCzBI8M8EitwwkikRgwZVI5A4+5+mCjeqZOlUyNCxFbo36ta7StQN3wWqluCOzWsQvwvdHNDKjoQOCDyCQfClKV1a9elKUpppWNXirwJzkXgbkSwMMeddY9ocyKypT/CC5Y+pi5NIZJKUpU8ll6KNlPUHyPRRrJWvkW0XUKaUynoUnyyF9DiC0FhC0KSSSQ8z8iCO2laVoVR9w4apuLB5jA3V7qmZxd/F2QR3AQ3q0ldnAIILRs6SLwO4FOVPgg+e1XW3XnrPz6c8MsLccc/vEKA/UCPp57hyPDBSeQCDVCHdKVD0UlS0k9tpS028T30Rtt1BQDouKKm2wpxC0pV7v4lOLXeJuZc0xVphxqyO3L8v4z19KW3LDd1vTbXFZVv+DtLrz8F1Sgn4oflqG9A+EVpazWJu4DMZTBZFPTv4e/ax1tOGA9epPJBIyhgGCF42Cc8l1USg9kiAY/WYHqzzV5QRLBLJDICCB3xuV5UHz2svaRz788+3GlKUqma6NKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTXrHFvNvJfDM8y8AyeVaosh8yJticQmbj04kEaudtkktvudz+ciJi3Hv2vdZ54z7TO7NxktZtxexcJBSErm4pe1WtPb5i13hu6NdXb1Fy1930i0pUibT6sdQtkQfJ7c3Ndp4/nuXGTx1cjjkYgBmjp5GvagjZyO5yir3k+eVWNUqtHN5XGgJTuSRxhiwhYJJEGPuVjkRlj5+4jCA/cHgcS/S/abYoyz/xZxRksh3R01Kvtmgsg/XbEaYT8/wBH6fOsaOSfH3zJmkaTbcUTbONLW+FJU7ZC9cciWkhI6PyvNShEXXSNLtke3ODavj+I7wYpVw534gOre4aslG5u61VqSp2Sx4itRw8rqRwR87jq1e/H3DkN6NqPkEg+PGvXY3RnbMZje/IikEH0FSAt/NolVjx9uT9z+dc0mVMmypM2bMlTJ0x/z5dwlPLmTJj3+UnS5KjImN/9W6N/cK4aUqG2ZmJZmZmZmd3ZmZndjyzsWJ+pj5YjjvctI3Mju7W+STySSeTz5JY8n3PLEsef4k6UpSuNNPXeu+isH7ihPWrf0AT3BPYnsCT2qe/wK4GrCeArFcZjC27rntynZjMUoJDoi3FTcCxpUUlRLa7LEjzkpUQpgy1svpakIdaTCjxTgM/lPkTEsDt3mpVlF4YiTZLKetUS2RpCpd0nK2U9LUe1Nl5SyoBai3GQVSXW2VWcLRaYtlt0C025hEa32yHDt0CM2AlLEGFGbjsMgDt8AbHcdiNH1rMr4QNnSXM3uDfE8PFfE0xgsa7j9V/ItBYvyxEoeHpUI44GIP1rkH7QOONSBsKiXsW8kykJDH8tDzwS8sjRtKR4AQpEF8Nz3RzE8cHX3uS4zSFOOvIbbQlS1rXtCEJT1dSlqUAEJSEqKlKICUjqUQnvVI3xKckK5a575d5DbcLkfJeQr7MtZWXFBVlTI9xsDaC4lJSlOPxrbFSlxKVNOx3PMS31JSbUXj15mRwh4XOU8kiyxDyC+W9zB8S2tKXF37K0KtypcY9wF222P3C6qUpSUt/k5XxBakJVTpCtAIAPSn4UdR2pJ/yqj6qPb6lXp2Oq+gj4KdpSx1N3b3sxBBbnqbbxjHwxirqmRyy97DteCWWbFoZkAUPXljBEsT9utD+046hRz5Hp30xqTK5x9e9vTNQ/SVWXIB8Rge4dxKzx0483IYiA6x3oJDwGQttpSlZ3a1PaUpSmmlKUppqy77HPl9eU8JZbxPcpPnXDi7KRNtDe1KKMPzd2bcoMRCVggNW+/wATIGtIUVMIkR0lKEOxy7MnVVz2RGdv4z4rE4v5oah8kYLkljdbClBD1zszCMuiFKACkuR2LHcGmnFhKCJa0IWVLCTajrUj8Tu14ts9Xs69aIRVNxwVNzQIoAT1ciJIMkU4VVCvmKeRlCjntWQKT45P0QfAvvibe3w67TS3L6t/Z9nI7LssWVm9HDyRz4lW4JI9PCX8bAoPAIhDIqq3GlKUrH3WYGlKUpppSlKaaj28fXCzmd8cxuQ7JFU9k/HCZEqU0yyXZN2xB0pduUEIQVuPrtctuJc2m2+p55li5sRWnX5bTbkIGuyT6haVLSod0qSnuopUOx6UfnlAHYj/AL5I93/OVa+ejtvpW28yh5pxtbLjSwlTbrT3wuNrQraVJUkaUFDRT2AJJFV6vFnwE/whyO+u1QnTgOXzJFzxBxSHSxb5Cv8AGmNlaery5MQH97odCPe7CCiH7wtCkpwG+K/pfNXuQ9SsPXd61v5fHbmjUciC4nZFj8qxUsfSuQBMdOe2OOK3HUkkIWaxIIz3thisi5iBP3cnZFdCjyknIEc5AHlWBf1G4AHC+QSRrFalCCnfUOkAE7V2B6fUJJ0Fq+iUFSlfog0rCj7c/bnjn7cgAkc/kAg8fgg/cajv/iAR/EH2P8j9jpSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaU+ah8077fpKKU9akoT6uLQj4loQFKQn4lADvT9YIGthRBCSPuUQEq/UCTXuvh34WuPOXI9uxaOmRHsEPouGY3ZCSVWzHkuF90sPd0t3TIGEuWSKE9b22ZEjyvIjvOoqeFw+R3BlcfhMTXa3ksncgo1K6ngvNYfsUuQrenFH/eTSsOyKNWZyB5HdWrzW7EVWvGZJp3CRqPYsSB5P21IT7OzhVdqs145ovkRYnZJH/c/hqXGvLDGPxeg3S7xerSum9zG2Ikd7SVOM2911CVxn23FSjF1A7Hq/BCz8tjWknYOiEkdlKBSnahqums9khY/a7fZrLBYt1rtUOPb7bb4+kx4USE0mLCYZQFJAjtNpDikklegAAV7TXgXig52sfhz4YzDlG8rYdmWyN7njNulqcQ5esvnLWiw25hISVrabkMOXKSOnpbtcSdKUtDEd9aNyfSTpt/otgdr7AwEH7QydiSrULQR9kuWz2TnjFqwyhSyrLamcRCQE16kMcZb04l4mC1dw2wtqXstmLkNHDbexVvK5jITApFFBRqvcv2m4BZikMTiKMBnnMccKcykd8GHtf+fEZty5jfCtlmB2wcVxX7zkiWlhxqTmt9Yjh+HKSFFHXYLGGIqD3bRKuF0YClSQptMPFd9kWQ3XLcgveV5FOduWRZFdrhf7vcH1LWqfdp8hcyW5KCgoqakT5K5LSElQbZjpaWEq6Eq6Gt8fTnZlXYGytv7TqlH/ZVCNLc6KALeRnJtZK3+lWIsX57DoJAXSPsj57ERV+ZvrT1IvdW+pu7eoF/uQ7gyks1Cs7q7Y/D1lWnhsaew9ndRxsFaCR0VVmmWWftUymNFKUq99RbpSlKaaUpSmmsrfA3f3cc8Xfh4uTSyhb3JmOWM6PSExsl8zGpqVnsFBSLi42QCQod/s7NXQ6pE+GHzP8AhKeH7ySoOf8Ato44S2pIOysZjZwU9u/cPs6BA6uvY2Er6bu1a4/jXrRpu/Z1oBfVsbduQuRx3FKuUl9IcD2TmaVl8nlnkI8a3U/2Ylud+nPUii7M1etvLHW4AeQoa7g4I5WUE8AsKMRcj3IHJ/ClKVhXrZvpSlKaaUpSmmleR8wcR47zNgl4wbJo6jGnJTIt09oMpm2W7RQo2+6wHe6m5LLiihelAOwluR1KHWa9cpXhyeMoZnH3MVk6sV3H5CtNTu1J0DxWK06FJYnB8gMp8MhV0PDIysAddcsUU8ckM0ayxyo0ciOOVZG47lI5+/A8jyPsRqrxybxplHEWZXTCsxhCJcLbJUtqU2laIV7gdQRaL3ZlvHyvdbg9+917cBYlfvWSGZH5s+fEEBJUFJC+yCpKkhZ+iCoDqV/RTtX3VY28Rfh4x/nvEXLVMaZt2VWpDr2J5M2lsvW6Ur4BBmdSFOSLFPb21eYo24hkqk25P5QShQr+8gce5ZxdldwxDMrU7ab3b1IUVnqcgzY7hIavVkcUVMPxnlDTBYccL6tpaCyDrVd1p6M5XpfmGnrR2b20clOxxGWbukam0jFzick5LkWa5ZzWldoxdqcNDGJK9pI4W3FgJ8NYLgGShM5NecD+757eIJuAFWReR2N9Il+rsX923H4ulakEHRGu29/ID7z6D9RO60qDv/b+vAPH+RB/kQfvq3P/AH/ofY/10pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlapBUooT8S0p61NgguJH0U39tKv6BSF/0a77FsXyDNr9bcYxS0y75fru+uPb7bCSlTz7jf8ADKUtxTbMdmP/ACmTJdZjxv491uu2vBPbnhrVYZbNmxKkEFevG80888sixRwwxRhpJJZJWWNI0VneRlRVLEDX6VHdkRFZ3kZVjVVLNIz89iooBLM3B7QoJbg8c65sPw3I89ySy4liVrXdsgv1yXCtsRsqUyhTTanZPWXVNttNQWELkXB55bbNtjtuSJzkdlta02HvD3wLZeBcDi4zbktz75Od/KeX39CW0P3q9rbShwMl1PmN2iNot2mIpTRjsoSp1sOSZYr8T4YPC5ZeBLCq4XBuLeuSL5GQ3kOQp15NvjhaXUWLHUOJJjWxt0JdnTNtzb3NabuU0JKIEC15bB9o7+IjQ2epC09I+i+pI6D9Eq0onsButlfw+9DhsGl/pRueFDvDJVvSirntZdvY+yo76okUsj5O2CFyEisyQBRRrs6fMWLkubW25+y4xduKpvzr2iM8EVoj9RQHjn1H8eoeeR2AAL9XPE5OiNNOPOSG0MspWt51R0hlDbYdWt5WtNIQ0UuKW4UpDa0LJ6VoKqnHtG/FsrxHcroxfE7l7xxPxnNm2rGUNdfumSZI2f8AlDmS2lKSpxhMcIs9iQ8357FuZlbaQu6Sm6kD9qD44UYxbbp4ZuKb43+6a+Q1xeVMotkoKdx2zylllzBoD0TSmskvsfzUZK6ySmxWd1UR0x5lxeECvCSkobG0job6VNIbDTaEjXmNxekEpXI18TjvSPkrQJ1uo+E/o1Jjo4+qW5Kvp27deRNoU5o5BNBSsIBJnHjZQYpbqH0aHcARRM1ghlvRrDqn+P74mIM5PL0M2VkEkxuOuRy9QcpWlBju5KnIs9Ta8DIzxyQY22kNrMM7BTkYIan0ClaWbjpSlZ0a1U6UpSmmlKUpppSlKaays8D1gdyTxdeHu3MhSlQ+TccyFbaQNlOJFWQSj3IBCY1mXIUASVhvSApxTaFXRKqt+yKwM5P4rhlL8ZJh8bYRkV+S8A4tCLnkXueHW9snXZxbE+5vtDR6Qw+pZQlJULUlax/jJzEd7qXicXGyN+xNrU45wCCy2bt/IWWB4J4VqwqyKCAT3s3JVlA3o/2a+3ZcX0S3DnJkKncu/L8tRiCBJj8TiMRjomXkctxeTJIzB2TuVkAVkcFSlKxH1sP0pSlNNKUpTTSlKU00rwnmzgPC+dsZ/IWWwfJuMRLrmP5JBDSb1jc51IC5NvlKCS/Hd6UiZb5fXFuCB0uojqCXE+7UqmZjDYvcGNt4jM0q+Rxl6F4LdK1GssE0bjghlYHhl/VHIpWSJwskbJIqsOqeCGzFJBPGksUqlHRwCGU+4/hzwPI4YfYjVanm7w+Z9wPekxMphCRYpr6RZ8vtrajY7r1DYjF1xa0xpv0hyS1JWPjbbWgpWfDiCOsFKgps6cQpJS42r+Y42QFtr/oLSlX3ValvuM2bKLVOsOS2mBe7Nco/u8+3XFhEuJKbIIKHGHR0dfckSEeU6hQbUkgtpKYpOePZ4ToRl5HwfN98hpSVP4Bd5LSZUJsbP/Ji8y3o8eQnQJMG+SY046J/dSneq19dVvhezmAksZrp/Faz+DZ3lfBc+rnMWrv3GOr3kPl6qdx9FYh89GOysYJu17hi/ObMnqmSziQ1muT3Gr+qxF3dvlAq8yqo5/dKhf8A7XudRaUrnlxn4EqVCmNLjy4b8yNKjrH51l+A+7GltrQNnbT7LiNjaXOnqaK0FKjwViQwKsysCrKxVlYEMrKSGVgfIZSCCD5BBB86sUggkEEEEggjggg8EHn7g+CPsfB0pSlca40pSlNNKUpTTSlKU00pSlNNKUPb1/Z3/u3WnUkkAHfV9kjulf8AmKHwr/qFVP4/bwOf4n2H9ftprWnqpSRvqQ55TidHbTn8x4erSvuc6a+y3264XaZGt1qgTbncJr/usOBb4r8ybLkf5GNEjtuSH1/c02upE+CvZ+5XlHuORcwvvYjjfSHWcRtzkdeTXBjadx58xt6RHslu6VbQIz0q6K1pxDQUFVeWy9g7s3/kBjtr4exkGDcWLp4gxdBeCe/IX3BhrqQDwo9SdgrmKGV1Eb+/H4y9lJfRpQNKQfrk4Iij/AeTgqhPB7QxBPB4541htxJwtn/N2QN49hNoMpuMs/lLIJDa2sdsjHqJ1yufU375I3rVshOSbiToCJsip2eAPDLhnAVjU1aGU3vL7kw0i/5jcGmhcJjbSkFu1W4DZtdgiEKVFtbBCZKghVwkLWkFPseF4Hi/HliiY1hlihY/ZYSFBmFAbbaQtahovyHSkvyZKzordkKWo6AKlJCQn9iHmj6LCtEpPTtWlDQIOge+yBr1Kj0jv2rYx0e+H7b3TdYsvkTHnt3enwcjJETTxJeFIpYsHBMvdXLIGSS/2x2ZlklRRXSSWDUr4La9PDgWJjHZvFSGnK8RxAnysSN7ccDmUk88jt7eDzs96j9JV5yOkJUsq2ekJQoJWVK1odCiAvZBQT8WqiZ9oH7QC28CWufxXxZdWLnzNdoLzNyuDS2pUHjWBLQAq4y2QAh3KJCgRarevqbtqwJdzEVtTbbnnvjo9pnZuPIt54m8Ptwh3zkRxS7bfs9ZRHlY7g61KJAx7Wm7/kfxBxl4h6wWxWnTKuD6iyzXQuV1n3mfOu12mSrjdbpKfuVwuUyQ9OuEufNKlT3Zc6WtT8tx9S1KaLxKGySeoHZO1v4ffhss5uWjvbqHRkrYSN47OH2zaiKTZkqVeO7l4ZAGhxIIaStVdDJkwI5JUWi4iu66vi8+NmjtqtlOmXSLKRXdzTRy0NybxoSh6u3g37uzjMHYjcrZzo59O3ehdoMOPViry2MqhFHbNuMu6zZdxucqRPm3CY/PuUuc+9IlzZs5fVOeXNcU5Jke+kqVcpMoiW8oktJWdV8FKVsZRFjVURQqKAqKo4CIoCqi/hEUBUX2VQAPvrTFLLJM7SSszyOzu8jMzO7uxdmdmJLOzFmZ25diSXZjxwpSlfrXXpSlKaaUpSmmlbuk6B7AFSUglSQCpSwgAEkA/Ee+iekfErSQTW2vRuKeNMh5f5EwzjPF2HJV/wA2vlusNuWlvbUBNxclCfeXW1lsJjW6yQpt2kLcKEsIiSA50uMrQjz3LdahUtX7s0dalSrWLlyzIwVK9arBJZnmcsVBWOGKRmHcD/i54VtVDF423mMhRxWPrT3chkrtTH0KlZe+ezcvTpWrQRR/4nlnljRfI+pgvlmUasLex04icxHg/KuV7jEeRcuVsjZj2p15pKVKxnDWZ1vjPMKJ60Rp17m5C4pLiW/NEeNJSFsuRnXJlK88424/tHGGBYfx5jcYxbBhlgtWP2xkBsExrXCail5/SyFvzXUOypC/iKnnlE6716HWkzqNu6Xfe+dz7rkDqmXys8lSOTnuhxtbtpYqA8k8GDG1asJA8M0Zk/1mvp+6KdO4OlHSvZGwYfTMm3sFVgyEkYUJYzNruyObtKVUEpYy927Igcs6g9pcgKApSlWVqUtKUpTTSlKU00pSlNNKUpTTSuFQKtKAIPUE7T0kKTv1IV213+fcEdtjVc1dZcZrVtgTp7zgbZhwn5Ty1b6W0RmVvOuK0CelCElSiN9h2B+fXK6RozyEBFUsxJ4AUEcsefAUcjknwPuQNPbknwACSfwB5JP8APJ1V3z5wv55nT46lF7NMvf61lJdcb/dBckBtCknoSkqHbZA+Y+HvX5KvrnS3Z86bcHiS7NlzZbpOtl2a9NlufrPnvNg77bVvegop+StHl2cWbluyPAsWJ5gOAOFlmkljBA/xBHUP+HDDxxxrHKRu93bxwZHYD7/AFHuP39uW4X+A9yedK1AKunpBV1FIT0gq31oStJGgfhIWhPV9kOqSySHiEHSsqPCVwLF515IkQMgjSncKxyzvz8leaW5GVJXKdX+SLVCkNbTHkSZzzVwSlXxNx7O+HEp+EKqW29vZPdedxe3cPCJ8ll7cdSrGxCRKzcySzWJfqaKtXgjlmsSJFM8cStKsUpjEMndTqTXrMNWuvdNPIsUYPhQzBm5Y/ZVVWZj9lBPsDrFfR2oAbKfVI7qH9UbP9grUJUogBKu/oSlQH+kQEj8TUx+S+zNwSaVLxTkHK7CFDvBvcCxZFCKteoXEi4/KSCd9itZHps+teKXn2aHKMYOiwZ7gN5b7+W3dIt8x0n6fEzEyoDfp6ipWyvw49YcWzAbTfJRLzxZxeRxlqJgOP0wG2l8fyamCfsNVufaWegYj5H1lHs0E8L8/wDhJUjj+vPn244MbXfW9EfrBH7CAa16VfzF/wCgr/ZWb8z2e3iNiOfva24ZcUfWBlbDH7Lla4x/trof+AV4mf8AoRj/AP5yxj/+VWnL0i6pxMUbp7u5iPumCycifb2eCpOre/nkrx7Dk88eE4HNKe1sVe8ceRXkYHyOeCgkHgE+5H5/PGHwSo9wlR/UCf7ga2gg+hCv8whf/p3WbcT2fPiQlOfnrRiFvb+s/MIb/wCy222Sfw1+vdehWj2aXLkjf5aznj+0f9jVkV//ALrbi/8Av6du1e6n0R6tXmUV9hbg5b/Dbqfsv8e8mUanCv3/AFSD+n3/AGm3c5IeExdtfyZUWID29i7Dn788e33/ACY5elXca+IfoDu5/wCENuf6tbSQD0kpCx/FFSQ9+DJIdP4IqYbGfZl4nGU25l/JeRXdAB6oWO2i24031EfORLlZE+e/0V3PzG9jJrEPBp4e8LDbsHj2FfZzaSBOzCVIyd1RPzMS7rlWgEem025OvUHY3Ui4P4UeqWTaM5RMNtyJvL/P5BbsqKOC3amHXIKzj7K7xhueA4Ibir1tkZmfj1vlqan3aWX1W/pHEOff37io4++oF8L41z/kGSIuEYfkGTqH8JJttsku26P3/ld2Whu1wj/2uYz+NZ5cY+zezu7qjz+VcigYlB1tyw4+4xf8gWd6IcuDjhstsOu46JeUg9hsbOpgoVvg2yGxFt8WFb4MdOmI0GIxEjMJUkgpjsMJZYZST30pLgPcH03XbpeaWNpWFD7t9u2+/bt2+tZDbO+EnY+IaG5unIZDdduMdwhHGGxQZuSVarWlmyDheF/vMosM4/vqY7FAumjsfGV2DXJ5bsg94ufQh8AEkxo7St/DukHABPB55HiXFPh84v4chhrCMThQbopgMSckm9FxyecOgAiXfX0qkLQV7PkR24kAa+G3gEa9lU42kklWkpHUsklSgCVfD0q0WwdepCU9u42CR0+VZlieDWWZkmZ5JZcVsFubLs69X+4xbTbIqACdvTZrjMdBOjpJc61HQSkkgGGzxHe1647xNEzGvDzYV8gZIzuM7md/iyrdhdpkqaSkKt1veEO/36Q2r4UNPR8et6QOoS3N6Oa/TbpDuDc4r4LpztIDHVisRfH1YMXgsdyO/ut30SvSgPY3qsjyPYnHLRwzSvw9vdSOsfSzopiVu733JisAvpPLQwsJWxmsiF5XjGYSr33Zy8vZEbHox0Y3ZfmrddeH1Lbyhy/xtw1iszM+TMttGJ4/BBC5dzeWHZLvwkxbZb2G5Fyu847BRb7VDmznBsojqAURW+8YPtPs15kZufH/AAsLnx3xnJVLh3K7qdLGaZhEfT0q97lx1E2G0PhSwu0QXVynEqUmRcXISjbKjx5b5r5N5zyhzMOVcyu2XXZa1BpExQbtlniqWSYOP2VChbLZCOytTduRan1KI6pJOyfKa2O9I/ha2zsl6ud3c8G69zwmKaCKSAnb+KnXslWWnTsp3ZCzFIAYruRiQwuiyV6FOwgmOnj4ivjw3r1Rhu7V6fRWNibIsCetbsR2ON2Z+q/EckN+/VlMWJoToCJMdipZHnjd47eSt15Pl03J0FqI8vTiir84gjy1/wCVdUjrU4fp0hRA9AK20pWVoHH9AB59+FHao59+FUKqqPpVVHABLE4AM7MAG48c8HgA8cAAEj3ACjgfYlj+pmJUpSudfnSlKU00pSlNNKUrcpKkpUojaU9RUpJC0hCftOEoKh5Kf0nt+UkdysCn/P8AtA/3kD+ZA1yAT7An+Q59/bWgSSSNaIWWzv4fzg7+WOrW3CgealA2pTGn0gskOVYk9kj4U3sUsU/xMZpbC1fMujP2njGJLZWX7bij62E3vI2SVaaOSzEpt1qU4WZJsUGS+yhcS9uuOxyeAXwZXbxP8iM3rJob8Th3CZkdzMp4S+j90c4FLjeEWZ9KAfebgCUZZNSkvWy0lMVhTUl1gVbFgWdizwLdbLRAjQLdao0KDb7dGQ0zDhQoLKIsaFEabUlLUSLEaDMRoJSGypKilPQAnBv4sescNOjJ0u29bjlv5BYpN3WYG5+QxzKtithu9O4i3keIpr0aEiCiY68pka3LHFtP/s/vhsnyeWh65bwx8keIxEjpsCjajI/aeYj/AHU+5DGwUtQxDCaLFyFCJ8qhtwESYyEz/oaUpWvPW5DSlKU00pSlNNKUpTTSlKU00pSlNNK8A8S2VJw7gflW+glt5vDrrbYqSroV73fi3YYXlH16/NnsuJHyKgpZSkEj3+ozvaRZ2m2cdYjx+w50SswyUXe4NpcCVCzYvHU+vzfQFmTeZVrbbSVBTq4DwbQ4lpakRz1a3Eu1enW7s0X7Hgwd6rVPcFJyORVcfjQCWXt4u2YHZvPbGjk8HhlpWbtilib9nu7WWs6Rnnj97NxDFweR575AeORyAfxyIatjp18+rf4arbSmjsjSuoJUrpCSVdI+yekDZD/8l0P33/JfOrTr7e/5A/qfYfzP21AmuaPHkTH48WIw7JlSnWGIsZhtb0iQ/K6RGYYZbCnXX5C3GmWGUJU67IfjxkJU/IYbcsQeFbhBPCPFdss8+O0vLb84jIMwlNqaWDeJaSlq2ocStSVR7FDS1BSpl1yM+8qZJYW62+neCPgJ8OS77co/OGYQlqslleWeP7dIZ6TcL8lKzLykpV8Tlsg9ZdsC3EtoVdpEmWyVx4EBxyY/Xpvvr0AGv7yfw9K2A/Cp0qlxVGbqLnK5ju5iqau3K0qlJa2HlKPPlGXubtkykkaCkR2yJj4hOGIyHZFKOysKYI2y9hCss6mOmjr9UdclfUlYEfqnZPoAAKQn3Yv3DWlKVmfq/wDStND6D+wVrSmmlKUpprhMhka2v17DSVHf9gPp8/odj1BrrbrkFjsUF+53u726zW2KjzJNxustm3QI7ff43pktbMZtI13K3RrsDrY3+M5NwObyLhl7xOJlmV4JMusMx4eXYVdUWfKrDJ18E21z/KkMlSD2U3IjLSpOwQT0KTVJ8Z/hl8SnCmRv3DljJMs5WwmVcSLFynNu1/vltltBRCbffVTps6RiuQLIXqK+97osaMd55A6kzL0f6X4Pqhk3xN/fdHa2SV1+Wxc+Mkt3cpD9BdsbNNdx+PlnTmRWqNaFrhBNFDNEzenjR8RfXfdPQvBx7gxfSrK76w7Qn53N08vHRx2Bsl1VFy9eHH5LIrWZWUpeWCLHtMwqz3akpiM9gzlP2ifhL4tQ81M5QgZleYyAlqz8bw3MylyFEn7N1gNqxlAP/XX5r1HSO2qi65k9s3nV4TJtXBfHVuwyGrUZvKs7fayHIEtAAe9QscgEY/b1kgny5s6+gk92/TUJxCglaekBB0QkgJbSkp8wrWoNMdCEo35jiiENn4XFJPwnirPLZ/wpdKtttHYylS9u+9Dx+8ztkiirqWHKYqjHSrNHySDBfN8Ap9Y557tTHUb4/wDr7vVZqWFyWL6fYuTuT5falRhkjF2qEWTN5Ga9bglRu5vVxH7LUt4CADtHqXJ/NXKfNF4F95Rz7JszuPmhxpV4mEwLenfdq02aOpFqtaCOxTAix0qBIPavL/g0kJH1SQUpbaSddnVBslSjv5AFX13W2lZH0aVLGVYaOOqVaFKvGsUFSnXhrVoUUKO2KGFEjjU9oJWNVQH9KqAAML8rmctnL1nKZrJXsvk7krT3Mjk7di9etzsfM1m3aklnnk8AAySMBwSACzllKUr1apulKUpppSlKaaUpSmmlK3dKgQCCknuAr4Sf1dWt06FdXQQEr0T5aiEuFKftLS2ohakJ9FOJSUJPZShXHI/I/wAx+Cf9wJ/kD+NfoKzEBVYkjkAAkkfkcDyP4jxoULSVgoUOhKVrPSdJbWSEuk615JIP54Hyh81is0vB54M898VuXstw0zMe42skxlzM+QXYp8mM0goMm04004nyrnf7t8RXES2/Ct6dquKowKUuZG+Df2Yudc1O2zPeZmLjx1xWXY9wjW1xl2NmmZBISXPcYT60LxCzJIITepTSJ75/gbcU/nkWUMLwDG+OsWtOGYPj1vxnGrFEYiWuz2htEaIw210glel+ZKffCQqdKlLdfkqBWtbzqlKViB1z+JrF7Sgt7X2HarZjdbrJXt5iuUs4vbpYGKTsZg0GSyyMS0cMfqVaTDutyPPDLRfY18K3wO57qDZob66rUru39gq8dmht+xHJUzm741IZO+JvSsYzAzMAz2mMNzJ1mAx/owyLkV67jTirD+IsJx7j3j+wxsdxXGoTUSBAjeSVuFKQZEybI6A7Pus9xJdn3GSvz3nl+YFfDXqFKVrWtWrN6zYuXbE9u5amksWrVmV5rNmeZ2klmnmkLSSyySMzySOzO7MWYkknW7jH4+jiqVTG4ypXoY+hWgpUaVOGOvVqVK0axV61avCqRQwwxqEijjRVRAqKAioqqUpXRr2aUpSmmlKUpppSlKaaUpSmmlKUpprjLqAdEnewNBC1HagCANJO+xBOvQbJ1o6rv+MTk8coc55TMhPiRYcTScOsvx+ZHW1Y5D6J09nX2kyb/NmO+alOnWCx0KcS31CXjxcczo4b4ivNwgSQxluSoXjOJJSopfTcLiyETrq03o/DZber3/qJSVP+7xWPMlymI7teTZWNuLBSpSQDs+a+lTwllpTjnd16Y/oJUCrr3sEisFvi934pXC9PaUvc4kTP50ISAiBZYcRUk4bk+q7WLEqMOFiStYIUSwMI431kxxXxMbjuJW3b7Tz2pyRAjID3clWMxUjkkRMOFPDAlR10pUoFaWwoJUUF1z+Ca6wCjzX9fvdvq65H8Qlyst/Cn4Y7rzvkSL3e2JNu4vsU9KL1cEJdQ/kk9hXS7YrHJJHmeYrtepDPXGsSgG23kOqQhXc+GLwg5LzZOi5TlsedjnGUcqDlwUh2FdcsbWT12+xsPBIRAfAPn3txpAiEatjzg2ROfjeK2bEbFbMbxy0QrNY7PDYgW6128LaiRY7BJbQ2kubV9omTIc6pM5zqclFaieuxug3w+3N22KW795U3rbUiZbGOxliMx2NxujrLDJIvJaLBK6KZWkCtlyghihOPlad6ftna7XWjv5GJo6SMrwwMeHtMOeGYdvKwD7kAF+76XHaTr7rXZoVlt0G0WmFHt9rtkWNCgQIbaGYsSJDSluJFjtpICGmGkhB2NntraSpKe6pStj0cSQoscahI0VUSNQFREQBVVEUBUVVCqFUABVAA8alYKFAVQAFUKAAAAqjgAAcDwP4aUpSuzXOlKUpppSlKaaV+YvGPQcjtU+y361W672q5QxCn2q6xY9xts9hSCVMzIEkux3WQsgKbUFKX0JJd/Sr9PSuUZ43SWOSSKSJ1kjkido5EdSGR0kQq8bowDJIjK8bgOjK6qw6poYrEbwzxpNDIkkUsUqK8csUqlJI5EYEMkkbMjqfDIzKwIJGqx/tP/B3xN4eWcL5I4si3HGWs9yi52e54kiQLhYLXMh2ZV8YueOe9rMq0qDza4qLeRMgstrSYLlqSVoMP9WF/bcXVCcQ4CsoWkOS8kz26Brv1dNqt+OQlOencITdiPXa+pQbCuheq9Fbe/hvzGaz3SDbGTz+QuZW/M+XhW7fcy2ZKlHMXsfUjadh3zLXhqCuHdnYtG/exk7zr50PjU23tfaXxD7zwW0cRj8Hiq1fbtlsZi4kr0YbuT29jMpekr1Yj6FRLNm7JYWtWSGrGsoMEESMAVCQk6UpKfh6trUlCdf5yiE7+7e/upXtHB3A3KHiHy2Rg/FFjZvOQxbJIyOS1IuqLJBYgxXY7DqnZctaIbYL0uO2y2t9LsguoEZt7uBM+RyWPxFKzk8rdq47G0o2nuXrs61q1aFOO+SaaTiKNAOSXkdFXjzz9saMJg8vuTK0cHgcZfzGYydiOpj8ZjK0ly9csy89kNatEDJNI3B7Y0Bdv8IPB14xo638t6/GtKyizHwVeK3AnFnJOBuQ0R29Fcyy2VWVwE79CZ+KO3qEB/wB/od9nsax8ueKZTZFrRecZyG0Kb+3+VLJc7eB/WlxWUn8FGvHjNxbfzUSzYbO4bLQv+iXGZSlfibkcjtkqzyo3I8+CfHnVQzezN4baleDce1dx4GePy8OaweTxcsYAXnvjvVYHX9Q8kD3H5BPQUrTqSDorQk/01oR/61JFciELcV0MpMhWt6jfvnt/3HmCqwSAOSQB+SeB/n7at3039ux+fbjtPv8Aj21srUjX2lJSf5q1pQs/PshRCz+CT+yv2lh415GypxDWMcf5vkS3PsCx4nf7qk/14NvfQP6yhWUODez48ZGcOtfk7hDKcfiL+JU3NJMHBosUdz8Ua/S4d5d38vKiLG+/b529lt3bWwMby5rcuBxMcYJc5HLUKbcjj6FWxZiLOQfCjz7cA8gG8Nu9Ot/btlSHbGyd27hlkK+muF29lMiGDEgEvWqvGiHg/vHkVFAPJ48jCrR+EjuFgqbKfiDiR6qb6d+Yn70dQ++hHShTiyENoUELcWpKG21H0Di1EJb/AFrKR99ThcYexX5EuS48vmDljH8Xikhx6z4NAkZVdHGfnAcu1+RabPblAnZcRZsla0OyidGpOuGPZx+FrhdyFc7fx+3muUwBuPlPIr6consL6T3ttsc93xuznZI3bbJFUO2l63UEbt+K/pVttZYcZcv7uyKeBXwdR0ohvp4WXL3/AJWmUHJ9SaiMh28AxRTgntyv6e/2f3Xvej1585jMf0+xUhQyWt0XImyLRdwEhgwmLa7cSUA/u4sm2LDeWZ0Uea33AHgn8Q3iLejv4VhE2x4g++C5neVOTccw1lrQ+K3ynWDcL50jRUmzRp6k9ysNoG6sD+F72ZfDPh/cg5RkjbXKXJUcpfZyC/2+OjHrFKA2FY1iK1SrfFkskJ8nIJzs6/tKClQZNtC+kSLiD5TaI7DCG2UMlppKS2lLACOkBLaUoKQoEpPluaIJKk7rtqwu6lfEt1A6hJaxlaYbU25OGjbGYeaRbd2tIvY0eUy3EduyJFBE8EXycEvI9ar4QDZp0S+CTpH0jlqZvI1ZN/7yrGKdc7uWvDJRpXECMLGIwR9epTmjkRJYbVufK368o769+Ny6jrkRVo2AB0nevjUBvQAUEp6UhOh/BdIR9/c77GlKx5449vA8ngew5JJ4H5JJJJ5JJ8ngADMkADk+eSeWJJLMeAO5mPLM3aAvLEnhQPtpSlKa50pSlNNKUpTTSlKU00pSlNNKUpTTSvguF1ttpgTLpc5sa3223sOyp8+Y6mPDhxWEFx+TJkulLLEdhtKlvvuLS0yhK1uLSlKiPvrwrmPiK58x2mJiFwy2445gz6kO5XbrH+Zv2VMsqR0WR69E9Fqs0wAm6txYsh6WkeU2ttK1k0vM2slUx1qfEY9crkVhcUqL2EqRT224WAWLbhlrVVdu+zMI5HSFXaKOWQLE/VYeWOCR4IvXmA/dxF1jDMf+szeAB9/Y/wAdQqc/cpZV4pOY/Iw62Xq+2q3OSLDgFgtsVyVLdsyJHRJvi46ASzNvagq4omSg01GZatsZ9xl1h1pGafh79n3FsyoOW82+7Xa4jchnj6C80u0RVrB62cluMd51q/pX282zRnhal73OuN57is9uN+HOP+JLQqzcf4rbcfYeAM2aw2h28XN7v++bteHkrn3N8diETHHmAobR0gq6vVgAB2H+/wCNY77O+Hej+3rm+Op96HeO7Mjc/aU1RIHi29TtOyyovy84MmVWl2RQ0luBKVavDDAKJ+WrNDadHacXzMmQzMq5C9NK07IFPykUjHlR2SFvmGhXhIy6LEqjgRklifgiwmYTLUaHGZiRo7aGIzEZtlmOyykdKWmo7SUtMsoASEpbAV0gdtgA9hSlZNKioAqgKoVVVVACqqKFVVAAAUAeAPAJPAHOrx+wA4AA4AAAAA9gAAABpSlK/WmlKUpppSlKaaUpSmmlKVw+8NfF3WOggK206BtQBGiUaVsEd07G/h+0CK45HIHI5PsPufIHj+pA/mQPvpqtZ7aLMGrtzlxfhLD/AF/uR46l3eQ2OoBi45dkMpttDgICeuRBx1l3YUelsNqcKQ611w0Vlf42+U0cx+KbmTNIjwlWkZY5jFgfQorY/IWDxYWLW1+OFBKwzclwnbkfgBDs90uAK6wMUikhKlnXSkkKPUnSB8lr7/C2v+KdVpt7Y8pS91uo6P7fk2t0y2Rg50Mdmrt6hPbiKlWguZINkrkL8gd7LcuykyAKr+ooC9wJb5jfiP3fBv3rl1O3RTk9ejd3ZkKeNnUlknxmG9PCY2eMdz9qWKeOikjUMeFPA8DgChQAJSQFNpdHb9BRUkKP0+JDiFA6UlbTyFALZdSi057Lfw0r4V4SGf5RbXIfIfL6I15kNyWfKnWTDmVKdxizFp1XXFektOfluWw4W5DTcq2RJcdiZbn2mIlvZw+DqR4g+RU8gZva/wD3PceXW2y7kmahxETM8ngy0TrNi0MqShyTEaeEe55QWfMaaYTDgPrTJuzzSLVYihICUtqCEkKSAWk9JDJaSlsBQCEIbAQEgAd0qG9K3ib8XnViKWOPpZhLKyHvgvbvngfyqr2z4zChl7lWRpPRyN+IuAiCgvqnutQpsD/s7vh6sQWJuu+6KLwp8taxnT2vZjIeQ2A9PMblVWWN1hNdrWDx8hDCYS5SyIjAtOw/IqOrpISlv4gN9kBRI33US2pJ7H5N/jXyTLbHkteU9b4kxBBBRIQwsD8HWXUj0A2PQV29KwKBYHuV3V/+ursG/h7Ht8fY8eAPGtthjjZSrIGU+O1ixXj8Be4KAfvwBz9/tr8c5gWGvbL2JYy4Pouw2pR+fzMU/wB/4D58sfCsTjnbGK48wfqzZrWyfu0Wo4I1+uv1lK9BuXCO03LRX24NiXgjx7ju/gNeL9k4wHkY+kp/IrQ/bj8oQPbnwBrr2Y6ko6VMtoCBpCSErI+ulggj1+ny/Ua3oiqSkhZQo/LtvXfZ7uJcI3939n1+2leYjkqSSe3jtBP0gj7hBwvJ+57de4Ko+w+/n7+eOeeOOeeB+rnSlKVzr9aUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaVhp42+d2/D74cc/zNmSWcouVuOK4SHiEOryrIxIiW15kpKk9ViYVLvzpcLTYj21bSnPPU00vMP3tjah1naCQoFtwEEFII0Ub9VoI0O6VoUNpUkmrF7UvxNNc08ytcbYncRL4/4dfuNvTLjOh+BfsylqZj5HcVKSAlyPbXfLx2HIWn3dbkK7S4T7sKcxIfmjoJ07m6j9RMRRkgMuDw8seb3BIU7o/kabo8VMsWUF8lYaGmIwS/y81iyqFazMuMvxadZK3Rno5uHKV7ny+6txwTbY2dCj8WDmMjE0cuRQAFlTBUvmMq0jKIvmK1WrIwe3GjxcK6iVLcVpIHWVEqK1q873pxt15ekh6RI+0txXc9yrXplr4SPCVnfit5CTZLK27Z8JssuG7neeORguLYYjxT1w7co/vWblV53uyWged+Tm9u3FuK2kk+m+DzwAcoeJq4QcjusWbgfEceSl2dmcyIlMq+p6keZasNgTUhyesJCuq8yI4syR8CZrjiksuWkeJ+H8I4Swez8ecb43Ex/GbM0lLMdlTSpM2Usj8o3O7yg0h253S5KQl+TcJKnJMtxXS4qIEILebPXj4jsZsKpd2xs+1Vym9ZlaCaWAR2qG2w8So81sqZIJMtGg9KpjgJBVdUnviEKak2r34UfgzznVm/j979RKV/CdNYJorUFe0klXJ71VZFlWtSDcWa+DmlTvvZc+mLcTPWxskzl7UHNxfxViXDeCY7xxx9Ym7Ji2MwI8G3w2HG1OOqStTkubOedKlSJ1xlPvTrjNWVvvOuPBCUhqKhXqdKVrFtWrV61ZvXrM9y5cnks2rVmRprFixM5klmmmfmSWWV2LySSMzuxLMSSSd5+Ox1DEUKWKxdOvj8bjqtejQo1Ikgq06dSFIK1WvBGFjiggijVIo0UBEAReI1RVUpSujXt0pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU00pSlNNKUpTTSlKU01gn4v8Akvl5nFH+JfDlil/ybl/PYT0FN6hRFxbBxtjM5PlXbJ7zkd0cg2e33IxVPRsfhOTkXJuQ/wC/+7MpiQ0ysS/DJ7I7CsHkxMw8Q86JyflLRRKj4bEU67gVumB5Ehbtyel+53PLnnHQpS4txZh2HZUlVpdSvqExxakkqKmkqSNJQkKQpR6R9skltIC+4IJX09h0dO9dlUlYfqluXa+1bO1NovHtuHKSetn81jyw3DmWCGOKtJlW7ZqNCojMlatjlrsgmtCS5aFy4JYOz/QTZe+N/wBbqB1DSbetnCRpW2htvLRqu0dswfRLYsxYPvlhy+Wv21+Zu5DLmeMiGhBWoVI8fWC9LEtbFtiswrbBiwYkOOmPCiRWmY0aM2hGkMxmmPLbjsJPwhDbQ3vq0K7qlKjYkszMzMzMe5mdizMT7ksxJJP3JJJ1NyRxxKscSJHGiqiRxqEREUcKqovCqFHgcDnjgEkKoClKVxr96UpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUpppSlKaaUpSmmlKUppr/9k=" -} diff --git a/agent/templates/interpreter.json b/agent/templates/interpreter.json deleted file mode 100644 index 7f31dfe0b..000000000 --- a/agent/templates/interpreter.json +++ /dev/null @@ -1,475 +0,0 @@ -{ - "id": 4, - "title": "Interpreter", - "description": "A translation agent based on a reflection agentic workflow, inspired by Andrew Ng's project: https://github.com/andrewyng/translation-agent\n\n1. Prompt an LLM to translate a text into the target language.\n2. Have the LLM reflect on the translation and provide constructive suggestions for improvement.\n3. Use these suggestions to improve the translation.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:TinyGamesGuess": { - "downstream": [], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "Generate:FuzzyEmusWork" - ] - }, - "Generate:FuzzyEmusWork": { - "downstream": [ - "Answer:TinyGamesGuess" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Your task is to carefully read, then edit, a translation to {begin@lang}, taking into\naccount a list of expert suggestions and constructive criticisms.\n\nThe source text, the initial translation, and the expert linguist suggestions are delimited by XML tags , and \nas follows:\n\n\n{begin@file}\n\n\n\n{Generate:VastKeysKick}\n\n\n\n{Generate:ShinySquidsSneeze}\n\n\nPlease take into account the expert suggestions when editing the translation. Edit the translation by ensuring:\n\n(i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),\n(ii) fluency (by applying {begin@lang} grammar, spelling and punctuation rules and ensuring there are no unnecessary repetitions), \n(iii) style (by ensuring the translations reflect the style of the source text)\n(iv) terminology (inappropriate for context, inconsistent use), or\n(v) other errors.\n\nOutput only the new translation and nothing else.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Generate:ShinySquidsSneeze" - ] - }, - "Generate:ShinySquidsSneeze": { - "downstream": [ - "Generate:FuzzyEmusWork" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Your task is to carefully read a source text and a translation to {begin@lang}, and then give constructive criticisms and helpful suggestions to improve the translation. \n\nThe source text and initial translation, delimited by XML tags and , are as follows:\n\n\n{begin@file}\n\n\n\n{Generate:VastKeysKick}\n\n\nWhen writing suggestions, pay attention to whether there are ways to improve the translation's \n(i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),\n(ii) fluency (by applying {begin@lang} grammar, spelling and punctuation rules, and ensuring there are no unnecessary repetitions),\n(iii) style (by ensuring the translations reflect the style of the source text and take into account any cultural context),\n(iv) terminology (by ensuring terminology use is consistent and reflects the source text domain; and by only ensuring you use equivalent idioms {begin@lang}).\n\nWrite a list of specific, helpful and constructive suggestions for improving the translation.\nEach suggestion should address one specific part of the translation.\nOutput only the suggestions and nothing else.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Generate:VastKeysKick" - ] - }, - "Generate:VastKeysKick": { - "downstream": [ - "Generate:ShinySquidsSneeze" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional translator proficient in {begin@lang}, with an exceptional ability to convert specialized academic papers into accessible popular science articles. Please assist me in translating the following paragraph into {begin@lang}, ensuring that its style resembles that of popular science articles in {begin@lang}.\n\nRequirements & Restrictions:\n - Use Markdown format to output.\n - DO NOT overlook any details.\n\n\n\n{begin@file}\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "begin" - ] - }, - "begin": { - "downstream": [ - "Generate:VastKeysKick" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "", - "query": [ - { - "key": "lang", - "name": "Target Language", - "optional": false, - "type": "line" - }, - { - "key": "file", - "name": "Files", - "optional": false, - "type": "file" - } - ] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "xy-edge__begin-Generate:VastKeysKickc", - "markerEnd": "logo", - "source": "begin", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:VastKeysKick", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:VastKeysKickb-Generate:ShinySquidsSneezec", - "markerEnd": "logo", - "source": "Generate:VastKeysKick", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ShinySquidsSneeze", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:FuzzyEmusWorkb-Answer:TinyGamesGuessc", - "markerEnd": "logo", - "source": "Generate:FuzzyEmusWork", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TinyGamesGuess", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:ShinySquidsSneezeb-Generate:FuzzyEmusWorkc", - "markerEnd": "logo", - "source": "Generate:ShinySquidsSneeze", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FuzzyEmusWork", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "", - "query": [ - { - "key": "lang", - "name": "Target Language", - "optional": false, - "type": "line" - }, - { - "key": "file", - "name": "Files", - "optional": false, - "type": "file" - } - ] - }, - "label": "Begin", - "name": "begin" - }, - "dragging": false, - "height": 128, - "id": "begin", - "measured": { - "height": 128, - "width": 200 - }, - "position": { - "x": -383.5, - "y": 142.62256327439624 - }, - "positionAbsolute": { - "x": -383.5, - "y": 143.5 - }, - "selected": true, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interact_0" - }, - "dragging": false, - "height": 44, - "id": "Answer:TinyGamesGuess", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 645.5056004454161, - "y": 182.98193827439627 - }, - "positionAbsolute": { - "x": 688.5, - "y": 183.859375 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Translation Agent: Agentic translation using reflection workflow\n\nThis is inspired by Andrew NG's project: https://github.com/andrewyng/translation-agent\n\n1. Prompt an LLM to translate a text into the target language;\n2. Have the LLM reflect on the translation and provide constructive suggestions for improvement;\n3. Use these suggestions to improve the translation." - }, - "label": "Note", - "name": "Brief" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 227, - "id": "Note:MoodyKnivesCheat", - "measured": { - "height": 227, - "width": 703 - }, - "position": { - "x": 46.02198421645994, - "y": -267.69527832581736 - }, - "positionAbsolute": { - "x": 46.02198421645994, - "y": -267.69527832581736 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 227, - "width": 703 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 703 - }, - { - "data": { - "form": { - "text": "Many businesses use specialized terms that are not widely used on the internet and that LLMs thus don’t know about, and there are also many terms that can be translated in multiple ways. For example, ”open source” in Spanish can be “Código abierto” or “Fuente abierta”; both are fine, but it’d better to pick one and stick with it for a single document.\n\nYou can add those glossary translation into prompt to any of `Translate directly` or 'Reflect'." - }, - "label": "Note", - "name": "Tip: Add glossary " - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 181, - "id": "Note:SourCarrotsAct", - "measured": { - "height": 181, - "width": 832 - }, - "position": { - "x": 65.0676250238289, - "y": 397.6323270065299 - }, - "positionAbsolute": { - "x": 65.0676250238289, - "y": 397.6323270065299 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 181, - "width": 832 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 832 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional translator proficient in {begin@lang}, with an exceptional ability to convert specialized academic papers into accessible popular science articles. Please assist me in translating the following paragraph into {begin@lang}, ensuring that its style resembles that of popular science articles in {begin@lang}.\n\nRequirements & Restrictions:\n - Use Markdown format to output.\n - DO NOT overlook any details.\n\n\n\n{begin@file}\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Translate directly" - }, - "dragging": false, - "id": "Generate:VastKeysKick", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": -132.6338674989604, - "y": 153.70663786774483 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Your task is to carefully read a source text and a translation to {begin@lang}, and then give constructive criticisms and helpful suggestions to improve the translation. \n\nThe source text and initial translation, delimited by XML tags and , are as follows:\n\n\n{begin@file}\n\n\n\n{Generate:VastKeysKick}\n\n\nWhen writing suggestions, pay attention to whether there are ways to improve the translation's \n(i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),\n(ii) fluency (by applying {begin@lang} grammar, spelling and punctuation rules, and ensuring there are no unnecessary repetitions),\n(iii) style (by ensuring the translations reflect the style of the source text and take into account any cultural context),\n(iv) terminology (by ensuring terminology use is consistent and reflects the source text domain; and by only ensuring you use equivalent idioms {begin@lang}).\n\nWrite a list of specific, helpful and constructive suggestions for improving the translation.\nEach suggestion should address one specific part of the translation.\nOutput only the suggestions and nothing else.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Reflect" - }, - "dragging": false, - "id": "Generate:ShinySquidsSneeze", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 121.1675336631696, - "y": 152.92865408917177 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Your task is to carefully read, then edit, a translation to {begin@lang}, taking into\naccount a list of expert suggestions and constructive criticisms.\n\nThe source text, the initial translation, and the expert linguist suggestions are delimited by XML tags , and \nas follows:\n\n\n{begin@file}\n\n\n\n{Generate:VastKeysKick}\n\n\n\n{Generate:ShinySquidsSneeze}\n\n\nPlease take into account the expert suggestions when editing the translation. Edit the translation by ensuring:\n\n(i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),\n(ii) fluency (by applying {begin@lang} grammar, spelling and punctuation rules and ensuring there are no unnecessary repetitions), \n(iii) style (by ensuring the translations reflect the style of the source text)\n(iv) terminology (inappropriate for context, inconsistent use), or\n(v) other errors.\n\nOutput only the new translation and nothing else.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Improve" - }, - "dragging": false, - "id": "Generate:FuzzyEmusWork", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 383.1474420163898, - "y": 152.0472805236579 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/jpeg;base64,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" -} diff --git a/agent/templates/investment_advisor.json b/agent/templates/investment_advisor.json deleted file mode 100644 index 338d93a0b..000000000 --- a/agent/templates/investment_advisor.json +++ /dev/null @@ -1,642 +0,0 @@ -{ - "id": 8, - "title": "Intelligent investment advisor", - "description": "An intelligent investment advisor that answers your financial questions using real-time domestic financial data.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "AkShare:CalmHotelsKnow": { - "downstream": [ - "Generate:SolidAreasRing" - ], - "obj": { - "component_name": "AkShare", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "top_n": 10 - } - }, - "upstream": [ - "KeywordExtract:BreezyGoatsRead" - ] - }, - "Answer:NeatLandsWave": { - "downstream": [ - "WenCai:TenParksOpen", - "KeywordExtract:BreezyGoatsRead" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "begin", - "Generate:SolidAreasRing" - ] - }, - "Generate:SolidAreasRing": { - "downstream": [ - "Answer:NeatLandsWave" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional financial counseling assistant.\n\nTask: Answer user's question based on content provided by Wencai and AkShare.\n\nNotice:\n- Output no more than 5 news items from AkShare if there's content provided by Wencai.\n- Items from AkShare MUST have a corresponding URL link.\n\n############\nContent provided by Wencai: \n{WenCai:TenParksOpen}\n\n################\nContent provided by AkShare: \n\n{AkShare:CalmHotelsKnow}\n\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "WenCai:TenParksOpen", - "AkShare:CalmHotelsKnow" - ] - }, - "KeywordExtract:BreezyGoatsRead": { - "downstream": [ - "AkShare:CalmHotelsKnow" - ], - "obj": { - "component_name": "KeywordExtract", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 2, - "top_p": 0.3 - } - }, - "upstream": [ - "Answer:NeatLandsWave" - ] - }, - "WenCai:TenParksOpen": { - "downstream": [ - "Generate:SolidAreasRing" - ], - "obj": { - "component_name": "WenCai", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "query_type": "stock", - "top_n": 5 - } - }, - "upstream": [ - "Answer:NeatLandsWave" - ] - }, - "begin": { - "downstream": [ - "Answer:NeatLandsWave" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "Hi there!", - "query": [] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-begin-Answer:NeatLandsWavec", - "markerEnd": "logo", - "source": "begin", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:NeatLandsWave", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:NeatLandsWaveb-WenCai:TenParksOpenc", - "markerEnd": "logo", - "source": "Answer:NeatLandsWave", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "WenCai:TenParksOpen", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:BreezyGoatsReadb-AkShare:CalmHotelsKnowc", - "markerEnd": "logo", - "source": "KeywordExtract:BreezyGoatsRead", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "AkShare:CalmHotelsKnow", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:NeatLandsWaveb-KeywordExtract:BreezyGoatsReadc", - "markerEnd": "logo", - "source": "Answer:NeatLandsWave", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "KeywordExtract:BreezyGoatsRead", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "xy-edge__WenCai:TenParksOpenb-Generate:SolidAreasRingb", - "markerEnd": "logo", - "source": "WenCai:TenParksOpen", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:SolidAreasRing", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__AkShare:CalmHotelsKnowb-Generate:SolidAreasRingb", - "markerEnd": "logo", - "source": "AkShare:CalmHotelsKnow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:SolidAreasRing", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:SolidAreasRingc-Answer:NeatLandsWavec", - "markerEnd": "logo", - "source": "Generate:SolidAreasRing", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:NeatLandsWave", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "Hi there!" - }, - "label": "Begin", - "name": "Opening" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": -609.7949690891593, - "y": -29.12385224725604 - }, - "positionAbsolute": { - "x": -521.8118264317484, - "y": -27.999467037576665 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": { - "query_type": "stock", - "top_n": 5 - }, - "label": "WenCai", - "name": "Wencai" - }, - "dragging": false, - "height": 44, - "id": "WenCai:TenParksOpen", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -13.030801663267397, - "y": -30.557141660610256 - }, - "positionAbsolute": { - "x": -13.030801663267397, - "y": -30.557141660610256 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "top_n": 10 - }, - "label": "AkShare", - "name": "AKShare" - }, - "dragging": false, - "height": 44, - "id": "AkShare:CalmHotelsKnow", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 250.32227681412806, - "y": 74.24036022703525 - }, - "positionAbsolute": { - "x": 267.17349571786156, - "y": 100.01281266803943 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interact" - }, - "dragging": false, - "height": 44, - "id": "Answer:NeatLandsWave", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -304.0612563145512, - "y": -29.054278091837944 - }, - "positionAbsolute": { - "x": -304.0612563145512, - "y": -29.054278091837944 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 2, - "top_p": 0.3 - }, - "label": "KeywordExtract", - "name": "Keywords" - }, - "dragging": false, - "height": 86, - "id": "KeywordExtract:BreezyGoatsRead", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -12.734133905960277, - "y": 53.63594331206494 - }, - "positionAbsolute": { - "x": -17.690374759999543, - "y": 80.39964392387697 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "keywordNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Receives the user's financial inquiries and displays the large model's response to financial questions." - }, - "label": "Note", - "name": "N: Interact" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 187, - "id": "Note:FuzzyPoetsLearn", - "measured": { - "height": 187, - "width": 214 - }, - "position": { - "x": -296.5982116419186, - "y": 38.77567426067935 - }, - "positionAbsolute": { - "x": -296.5982116419186, - "y": 38.77567426067935 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 162, - "width": 214 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 214 - }, - { - "data": { - "form": { - "text": "Extracts keywords based on the user's financial questions for better retrieval." - }, - "label": "Note", - "name": "N: Keywords" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 155, - "id": "Note:FlatBagsRun", - "measured": { - "height": 155, - "width": 213 - }, - "position": { - "x": -14.82895160277127, - "y": 186.52508153680787 - }, - "positionAbsolute": { - "x": -14.82895160277127, - "y": 186.52508153680787 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 155, - "width": 213 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 213 - }, - { - "data": { - "form": { - "text": "Searches on akshare for the latest news about economics based on the keywords and returns the results." - }, - "label": "Note", - "name": "N: AKShare" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:WarmClothsSort", - "measured": { - "height": 128, - "width": 283 - }, - "position": { - "x": 259.53966185269985, - "y": 209.6999260009385 - }, - "positionAbsolute": { - "x": 573.7653319987893, - "y": 102.64512355369035 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 283 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 283 - }, - { - "data": { - "form": { - "text": "Searches by Wencai to select stocks that satisfy user mentioned conditions." - }, - "label": "Note", - "name": "N: Wencai" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 143, - "id": "Note:TiredReadersWash", - "measured": { - "height": 143, - "width": 285 - }, - "position": { - "x": 251.25432007905098, - "y": -97.53719402078019 - }, - "positionAbsolute": { - "x": 571.4274792499875, - "y": -37.07105560150117 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 285 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 285 - }, - { - "data": { - "form": { - "text": "The large model answers the user's medical health questions based on the searched and retrieved content." - }, - "label": "Note", - "name": "N: LLM" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 179, - "id": "Note:TameBoatsType", - "measured": { - "height": 179, - "width": 260 - }, - "position": { - "x": -167.45710806024056, - "y": -372.5606558391346 - }, - "positionAbsolute": { - "x": -7.849538042569293, - "y": -427.90526378748035 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 163, - "width": 212 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 260 - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional financial counseling assistant.\n\nTask: Answer user's question based on content provided by Wencai and AkShare.\n\nNotice:\n- Output no more than 5 news items from AkShare if there's content provided by Wencai.\n- Items from AkShare MUST have a corresponding URL link.\n\n############\nContent provided by Wencai: \n{WenCai:TenParksOpen}\n\n################\nContent provided by AkShare: \n\n{AkShare:CalmHotelsKnow}\n\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "LLM" - }, - "dragging": false, - "id": "Generate:SolidAreasRing", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": -161.00840949957603, - "y": -180.04918322565015 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} diff --git a/agent/templates/medical_consultation.json b/agent/templates/medical_consultation.json deleted file mode 100644 index 1afed12e3..000000000 --- a/agent/templates/medical_consultation.json +++ /dev/null @@ -1,784 +0,0 @@ -{ - "id": 7, - "title": "Medical consultation", - "description": "A consultant that offers medical suggestions using an internal QA dataset and PubMed search results. Note that this agent's answers are for reference only and may not be valid. The dataset can be found at https://huggingface.co/datasets/InfiniFlow/medical_QA/tree/main", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:FlatRavensPush": { - "downstream": [ - "Generate:QuietMelonsHear", - "Generate:FortyBaboonsRule" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "begin", - "Generate:BrightCitiesSink" - ] - }, - "Generate:BrightCitiesSink": { - "downstream": [ - "Answer:FlatRavensPush" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting assistant\n\nTasks: Answer questions posed by users. Answer based on content provided by the knowledge base, PubMed\n\nRequirement:\n- Answers may refer to the content provided (Knowledge Base, PubMed).\n- If the provided PubMed content is referenced, a link to the corresponding URL should be given.\n-Answers should be professional and accurate; no information should be fabricated that is not relevant to the user's question.\n\nProvided knowledge base content\n{Retrieval:BeigeBagsDress}\n\nPubMed content provided\n\n{PubMed:TwentyFansShake}", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:BeigeBagsDress", - "PubMed:TwentyFansShake" - ] - }, - "Generate:FortyBaboonsRule": { - "downstream": [ - "PubMed:TwentyFansShake" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional Chinese-English medical question translation assistant\n\nTask: Accurately translate users' Chinese medical question content into English, ensuring accuracy of terminology and clarity of expression\n\nRequirements:\n- In-depth understanding of the terminology and disease descriptions in Chinese medical inquiries to ensure correct medical vocabulary is used in the English translation.\n- Maintain the semantic integrity and accuracy of the original text to avoid omitting important information or introducing errors.\n- Pay attention to the differences in expression habits between Chinese and English, and make appropriate adjustments to make the English translation more natural and fluent.\n- Respect the patient's privacy and the principle of medical confidentiality, and do not disclose any sensitive information during the translation process.\n\nExample:\nOriginal sentence: 我最近总是感觉胸闷,有时还会有心悸的感觉。\nTranslated: I've been feeling chest tightness recently, and sometimes I experience palpitations.\n\nNote:\nOnly the translated content should be given, do not output other irrelevant content!", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Answer:FlatRavensPush" - ] - }, - "Generate:QuietMelonsHear": { - "downstream": [ - "Retrieval:BeigeBagsDress" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting translation assistant\n\nTask: Translate user questions into Chinese, ensuring accuracy of medical terminology and appropriateness of context.\n\nRequirements:\n- Accurately translate medical terminology to convey the integrity and emotional color of the original message.\n- For unclear or uncertain medical terminology, the original text may be retained to ensure accuracy.\n- Respect the privacy and sensitivity of medical consultations and ensure that sensitive information is not disclosed during the translation process.\n- If the user's question is in Chinese, there is no need to translate, just output the user's question directly\n\nExample:\nOriginal (English): Doctor, I have been suffering from chest pain and shortness of breath for the past few days.\nTranslation (Chinese): 医生,我这几天一直胸痛和气短。\n\nNote:\nOnly the translated content needs to be output, no other irrelevant content!", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Answer:FlatRavensPush" - ] - }, - "PubMed:TwentyFansShake": { - "downstream": [ - "Generate:BrightCitiesSink" - ], - "obj": { - "component_name": "PubMed", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "email": "928018077@qq.com", - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:FortyBaboonsRule", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "Generate:FortyBaboonsRule" - ] - }, - "Retrieval:BeigeBagsDress": { - "downstream": [ - "Generate:BrightCitiesSink" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:QuietMelonsHear", - "type": "reference" - } - ], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 8 - } - }, - "upstream": [ - "Generate:QuietMelonsHear" - ] - }, - "begin": { - "downstream": [ - "Answer:FlatRavensPush" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "Hi! I'm your smart assistant. What can I do for you?", - "query": [] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-begin-Answer:FlatRavensPushc", - "markerEnd": "logo", - "source": "begin", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatRavensPush", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:FlatRavensPushb-Generate:QuietMelonsHearc", - "markerEnd": "logo", - "source": "Answer:FlatRavensPush", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:QuietMelonsHear", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:FlatRavensPushb-Generate:FortyBaboonsRulec", - "markerEnd": "logo", - "source": "Answer:FlatRavensPush", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FortyBaboonsRule", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:FortyBaboonsRuleb-PubMed:TwentyFansShakec", - "markerEnd": "logo", - "source": "Generate:FortyBaboonsRule", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "PubMed:TwentyFansShake", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:QuietMelonsHearb-Retrieval:BeigeBagsDressc", - "markerEnd": "logo", - "source": "Generate:QuietMelonsHear", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:BeigeBagsDress", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "xy-edge__Retrieval:BeigeBagsDressb-Generate:BrightCitiesSinkb", - "markerEnd": "logo", - "source": "Retrieval:BeigeBagsDress", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:BrightCitiesSink", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__PubMed:TwentyFansShakeb-Generate:BrightCitiesSinkb", - "markerEnd": "logo", - "source": "PubMed:TwentyFansShake", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:BrightCitiesSink", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:BrightCitiesSinkc-Answer:FlatRavensPushc", - "markerEnd": "logo", - "source": "Generate:BrightCitiesSink", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:FlatRavensPush", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "label": "Begin", - "name": "opening" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": -599.8361708291377, - "y": 161.91688790133628 - }, - "positionAbsolute": { - "x": -599.8361708291377, - "y": 161.91688790133628 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": { - "email": "928018077@qq.com", - "query": [ - { - "component_id": "Generate:FortyBaboonsRule", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "PubMed", - "name": "Search PubMed" - }, - "dragging": false, - "height": 44, - "id": "PubMed:TwentyFansShake", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 388.4151716305788, - "y": 272.51398951401995 - }, - "positionAbsolute": { - "x": 389.7229173847695, - "y": 276.4372267765921 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interface" - }, - "dragging": false, - "height": 44, - "id": "Answer:FlatRavensPush", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -277.4280835723395, - "y": 162.89713236919926 - }, - "positionAbsolute": { - "x": -370.881803561134, - "y": 161.41373998842477 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting translation assistant\n\nTask: Translate user questions into Chinese, ensuring accuracy of medical terminology and appropriateness of context.\n\nRequirements:\n- Accurately translate medical terminology to convey the integrity and emotional color of the original message.\n- For unclear or uncertain medical terminology, the original text may be retained to ensure accuracy.\n- Respect the privacy and sensitivity of medical consultations and ensure that sensitive information is not disclosed during the translation process.\n- If the user's question is in Chinese, there is no need to translate, just output the user's question directly\n\nExample:\nOriginal (English): Doctor, I have been suffering from chest pain and shortness of breath for the past few days.\nTranslation (Chinese): 医生,我这几天一直胸痛和气短。\n\nNote:\nOnly the translated content needs to be output, no other irrelevant content!", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Translate to Chinese" - }, - "dragging": false, - "height": 86, - "id": "Generate:QuietMelonsHear", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -2.756518132081453, - "y": 38.86485966020132 - }, - "positionAbsolute": { - "x": -2.756518132081453, - "y": 38.86485966020132 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional Chinese-English medical question translation assistant\n\nTask: Accurately translate users' Chinese medical question content into English, ensuring accuracy of terminology and clarity of expression\n\nRequirements:\n- In-depth understanding of the terminology and disease descriptions in Chinese medical inquiries to ensure correct medical vocabulary is used in the English translation.\n- Maintain the semantic integrity and accuracy of the original text to avoid omitting important information or introducing errors.\n- Pay attention to the differences in expression habits between Chinese and English, and make appropriate adjustments to make the English translation more natural and fluent.\n- Respect the patient's privacy and the principle of medical confidentiality, and do not disclose any sensitive information during the translation process.\n\nExample:\nOriginal sentence: 我最近总是感觉胸闷,有时还会有心悸的感觉。\nTranslated: I've been feeling chest tightness recently, and sometimes I experience palpitations.\n\nNote:\nOnly the translated content should be given, do not output other irrelevant content!", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Translate to English" - }, - "dragging": false, - "height": 86, - "id": "Generate:FortyBaboonsRule", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -3.825864707727135, - "y": 253.2285157283701 - }, - "positionAbsolute": { - "x": -3.825864707727135, - "y": 253.2285157283701 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "query": [ - { - "component_id": "Generate:QuietMelonsHear", - "type": "reference" - } - ], - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "Search Q&A" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:BeigeBagsDress", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 316.9462115194757, - "y": 57.81358887451738 - }, - "positionAbsolute": { - "x": 382.25527986090765, - "y": 35.38705653631584 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Receives the user's financial inquiries and displays the large model's response to financial questions." - }, - "label": "Note", - "name": "N: Interface" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 162, - "id": "Note:RedZebrasEnjoy", - "measured": { - "height": 162, - "width": 200 - }, - "position": { - "x": -274.75115571622416, - "y": 233.92632661399952 - }, - "positionAbsolute": { - "x": -374.13983303471906, - "y": 219.54112331790157 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 162, - "width": 200 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Translate user's question to English by LLM." - }, - "label": "Note", - "name": "N: Translate to English" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:DarkIconsClap", - "measured": { - "height": 128, - "width": 227 - }, - "position": { - "x": -2.0308204014422273, - "y": 379.60045703973515 - }, - "positionAbsolute": { - "x": -0.453362859534991, - "y": 357.3687792184929 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 204 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 227 - }, - { - "data": { - "form": { - "text": "Translate user's question to Chinese by LLM." - }, - "label": "Note", - "name": "N: Translate to Chinese" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:SmallRiversTap", - "measured": { - "height": 128, - "width": 220 - }, - "position": { - "x": -2.9326060127226583, - "y": -99.3117253460485 - }, - "positionAbsolute": { - "x": -5.453362859535048, - "y": -105.63122078150693 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 196 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 220 - }, - { - "data": { - "form": { - "text": "PubMed® comprises more than 37 million citations for biomedical literature from MEDLINE, life science journals, and online books. Citations may include links to full text content from PubMed Central and publisher web sites." - }, - "label": "Note", - "name": "N: Search PubMed" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 220, - "id": "Note:MightyDeerShout", - "measured": { - "height": 220, - "width": 287 - }, - "position": { - "x": 718.5466371404648, - "y": 275.36877921849293 - }, - "positionAbsolute": { - "x": 718.5466371404648, - "y": 275.36877921849293 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 220, - "width": 287 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 287 - }, - { - "data": { - "form": { - "text": "You can download the Q&A dataset at\nhttps://huggingface.co/datasets/InfiniFlow/medical_QA" - }, - "label": "Note", - "name": "N: Search Q&A" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:VioletSuitsFlash", - "measured": { - "height": 128, - "width": 387 - }, - "position": { - "x": 776.4332169584197, - "y": 32.89802610798361 - }, - "positionAbsolute": { - "x": 776.4332169584197, - "y": 32.89802610798361 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 387 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 387 - }, - { - "data": { - "form": { - "text": "A prompt summarize content from search result from PubMed and Q&A dataset." - }, - "label": "Note", - "name": "N: LLM" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 140, - "id": "Note:BeigeCoinsBuild", - "measured": { - "height": 140, - "width": 281 - }, - "position": { - "x": 293.89948660403513, - "y": -238.31673896113236 - }, - "positionAbsolute": { - "x": 756.9053449234701, - "y": -212.92342186138177 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 281 - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are a professional medical consulting assistant\n\nTasks: Answer questions posed by users. Answer based on content provided by the knowledge base, PubMed\n\nRequirement:\n- Answers may refer to the content provided (Knowledge Base, PubMed).\n- If the provided PubMed content is referenced, a link to the corresponding URL should be given.\n-Answers should be professional and accurate; no information should be fabricated that is not relevant to the user's question.\n\nProvided knowledge base content\n{Retrieval:BeigeBagsDress}\n\nPubMed content provided\n\n{PubMed:TwentyFansShake}", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "LLM" - }, - "dragging": false, - "id": "Generate:BrightCitiesSink", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 300, - "y": -86.3689104694316 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} diff --git a/agent/templates/research_report.json b/agent/templates/research_report.json deleted file mode 100644 index 4fbf1fe39..000000000 --- a/agent/templates/research_report.json +++ /dev/null @@ -1,1107 +0,0 @@ -{ - "id": 10, - "title": "Research report generator", - "description": "A report generator that creates a research report from a given title, in the specified target language. It generates queries from the input title, then uses these to create subtitles and sections, compiling everything into a comprehensive report.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:WittyBottlesJog": { - "downstream": [], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "Template:LegalDoorsAct" - ] - }, - "Baidu:MeanBroomsMatter": { - "downstream": [ - "Generate:YoungClownsKnock" - ], - "obj": { - "component_name": "Baidu", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "IterationItem:RudeTablesSmile", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "parent_id": "Iteration:BlueClothsGrab", - "upstream": [ - "IterationItem:RudeTablesSmile" - ] - }, - "Generate:EveryCoinsStare": { - "downstream": [ - "Generate:RedWormsDouble", - "Iteration:BlueClothsGrab" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "\n\nGenerate a series of appropriate search engine queries to break down questions based on user inquiries\n\n\n\n\nInput: User asks how to learn programming\nOutput: programming learning methods, programming tutorials for beginners\n\n\n\nInput: User wants to understand latest technology trends \nOutput: tech trends 2024, latest technology news\n\n\n\nInput: User seeks healthy eating advice\nOutput: healthy eating guide, balanced nutrition diet\n\n\n\n\n1. Take user's question as input.\n2. Identify relevant keywords or phrases based on the topic of user's question.\n3. Use these keywords or phrases to make search engine queries.\n4. Generate a series of appropriate search engine queries to help break down user's question.\n5. Ensure output content does not contain any xml tags.\n6. The output must be pure and conform to the style without other explanations.\n7. Break down into at least 4-6 subproblems.\n8. Output is separated only by commas.\n\n\n\ntitle: {begin@title}\nlanguage: {begin@language}\nThe output must be pure and conform to the style without other explanations.\nOutput is separated only by commas.\nBreak down into at least 4-6 subproblems.\n\nOutput:", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "begin" - ] - }, - "Generate:RealLoopsVanish": { - "downstream": [ - "Template:SpottyWaspsLose" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "In a detailed report — The report should focus on the answer to {IterationItem:OliveStatesSmoke}and nothing else.\n\n\nLanguage: {begin@language}\nContext as bellow: \n\n\"{Iteration:BlueClothsGrab}\"\n\nProvide the research report in the specified language, avoiding small talk.\nThe main content is provided in markdown format\nWrite all source urls at the end of the report in apa format. ", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "parent_id": "Iteration:ThreeParksChew", - "upstream": [ - "IterationItem:OliveStatesSmoke" - ] - }, - "Generate:RedWormsDouble": { - "downstream": [ - "Iteration:ThreeParksChew" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "According to query: ' {Generate:EveryCoinsStare}',for ' {begin@title}', generate 3 to 5 sub-titles.\n\n\nPlease generate 4 subheadings for the main title following these steps:\n - 1. Carefully read the provided main title and related content\n - 2. Analyze the core theme and key information points of the main title\n - 3. Ensure the generated subheadings maintain consistency and relevance with the main title\n - 4. Each subheading should:\n - Be concise and appropriate in length\n - Highlight a unique angle or key point\n - Capture readers' interest\n - Match the overall style and tone of the article\n - 5. Between subheadings:\n - Content should not overlap\n - Logical order should be maintained\n - Should collectively support the main title\n - Use numerical sequence (1, 2, 3...) to mark each subheading\n - 6. Output format requirements:\n - Each subheading on a separate line\n - No XML tags included\n - Output subheadings content only\n\n\nlanguage: {begin@language}\nGenerate a series of appropriate sub-title to help break down ' {begin@title}'.\nBreaks down complex topics into manageable subtopics.\n\nOutput:", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Generate:EveryCoinsStare" - ] - }, - "Generate:YoungClownsKnock": { - "downstream": [], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Your goal is to provide answers based on information from the internet. \nYou must use the provided search results to find relevant online information. \nYou should never use your own knowledge to answer questions.\nPlease include relevant url sources in the end of your answers.\n{Baidu:MeanBroomsMatter}\n\n\n\n\n\nlanguage: {begin@language}\n\n\n \" {Baidu:MeanBroomsMatter}\" \n\n\n\n\nUsing the above information, answer the following question or topic: \" {IterationItem:RudeTablesSmile} \"\nin a detailed report — The report should focus on the answer to the question, should be well structured, informative, in depth, with facts and numbers if available, a minimum of 1,200 words and with markdown syntax and apa format. Write all source urls at the end of the report in apa format. You should write your report only based on the given information and nothing else.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "parent_id": "Iteration:BlueClothsGrab", - "upstream": [ - "Baidu:MeanBroomsMatter" - ] - }, - "Iteration:BlueClothsGrab": { - "downstream": [], - "obj": { - "component_name": "Iteration", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "delimiter": ",", - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:EveryCoinsStare", - "type": "reference" - } - ] - } - }, - "upstream": [ - "Generate:EveryCoinsStare" - ] - }, - "Iteration:ThreeParksChew": { - "downstream": [ - "Template:LegalDoorsAct" - ], - "obj": { - "component_name": "Iteration", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "delimiter": "\n", - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:RedWormsDouble", - "type": "reference" - } - ] - } - }, - "upstream": [ - "Generate:RedWormsDouble" - ] - }, - "IterationItem:OliveStatesSmoke": { - "downstream": [ - "Generate:RealLoopsVanish" - ], - "obj": { - "component_name": "IterationItem", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "parent_id": "Iteration:ThreeParksChew", - "upstream": [] - }, - "IterationItem:RudeTablesSmile": { - "downstream": [ - "Baidu:MeanBroomsMatter" - ], - "obj": { - "component_name": "IterationItem", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "parent_id": "Iteration:BlueClothsGrab", - "upstream": [] - }, - "Template:LegalDoorsAct": { - "downstream": [ - "Answer:WittyBottlesJog" - ], - "obj": { - "component_name": "Template", - "inputs": [], - "output": null, - "params": { - "content": "

{begin@title}

\n\n\n\n{Iteration:ThreeParksChew}", - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameters": [], - "query": [] - } - }, - "upstream": [ - "Iteration:ThreeParksChew" - ] - }, - "Template:SpottyWaspsLose": { - "downstream": [], - "obj": { - "component_name": "Template", - "inputs": [], - "output": null, - "params": { - "content": "

{IterationItem:OliveStatesSmoke}

\n
{Generate:RealLoopsVanish}
", - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameters": [], - "query": [] - } - }, - "parent_id": "Iteration:ThreeParksChew", - "upstream": [ - "Generate:RealLoopsVanish" - ] - }, - "begin": { - "downstream": [ - "Generate:EveryCoinsStare" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "", - "query": [ - { - "key": "title", - "name": "Title", - "optional": false, - "type": "line" - }, - { - "key": "language", - "name": "Language", - "optional": false, - "type": "line" - } - ] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-Baidu:SharpHotelsNailb-Generate:RealCamerasSendb", - "markerEnd": "logo", - "source": "Baidu:SharpHotelsNail", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RealCamerasSend", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "reactflow__edge-Generate:BeigeEyesFlyb-Template:ThinSnailsDreamc", - "markerEnd": "logo", - "source": "Generate:BeigeEyesFly", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Template:ThinSnailsDream", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "reactflow__edge-IterationItem:RudeTablesSmile-Baidu:MeanBroomsMatterc", - "markerEnd": "logo", - "source": "IterationItem:RudeTablesSmile", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Baidu:MeanBroomsMatter", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:EveryCoinsStareb-Generate:RedWormsDoublec", - "markerEnd": "logo", - "source": "Generate:EveryCoinsStare", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RedWormsDouble", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__begin-Generate:EveryCoinsStarec", - "markerEnd": "logo", - "source": "begin", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:EveryCoinsStare", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:RedWormsDoubleb-Iteration:ThreeParksChewc", - "markerEnd": "logo", - "source": "Generate:RedWormsDouble", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Iteration:ThreeParksChew", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:EveryCoinsStareb-Iteration:BlueClothsGrabc", - "markerEnd": "logo", - "source": "Generate:EveryCoinsStare", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Iteration:BlueClothsGrab", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Baidu:MeanBroomsMatterb-Generate:YoungClownsKnockb", - "markerEnd": "logo", - "source": "Baidu:MeanBroomsMatter", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:YoungClownsKnock", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__IterationItem:OliveStatesSmoke-Generate:RealLoopsVanishc", - "markerEnd": "logo", - "source": "IterationItem:OliveStatesSmoke", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RealLoopsVanish", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:RealLoopsVanishb-Template:SpottyWaspsLoseb", - "markerEnd": "logo", - "source": "Generate:RealLoopsVanish", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Template:SpottyWaspsLose", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Iteration:ThreeParksChewb-Template:LegalDoorsActc", - "markerEnd": "logo", - "source": "Iteration:ThreeParksChew", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Template:LegalDoorsAct", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Template:LegalDoorsActb-Answer:WittyBottlesJogc", - "markerEnd": "logo", - "source": "Template:LegalDoorsAct", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:WittyBottlesJog", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "", - "query": [ - { - "key": "title", - "name": "Title", - "optional": false, - "type": "line" - }, - { - "key": "language", - "name": "Language", - "optional": false, - "type": "line" - } - ] - }, - "label": "Begin", - "name": "begin" - }, - "dragging": false, - "height": 130, - "id": "begin", - "measured": { - "height": 130, - "width": 200 - }, - "position": { - "x": -231.29149905979648, - "y": 95.28494230291383 - }, - "positionAbsolute": { - "x": -185.67257819905137, - "y": 108.15225637884839 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interact_0" - }, - "dragging": false, - "height": 44, - "id": "Answer:WittyBottlesJog", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 1458.2651570288865, - "y": 164.22699667633927 - }, - "positionAbsolute": { - "x": 1462.7745767525992, - "y": 231.9248108743051 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "delimiter": ",", - "query": [ - { - "component_id": "Generate:EveryCoinsStare", - "type": "reference" - } - ] - }, - "label": "Iteration", - "name": "Search" - }, - "dragging": false, - "height": 192, - "id": "Iteration:BlueClothsGrab", - "measured": { - "height": 192, - "width": 334 - }, - "position": { - "x": 432.63496522555613, - "y": 228.82343789018051 - }, - "positionAbsolute": { - "x": 441.29535207641436, - "y": 291.9929929170084 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 337, - "width": 356 - }, - "targetPosition": "left", - "type": "group", - "width": 334 - }, - { - "data": { - "form": {}, - "label": "IterationItem", - "name": "IterationItem" - }, - "dragging": false, - "extent": "parent", - "height": 44, - "id": "IterationItem:RudeTablesSmile", - "measured": { - "height": 44, - "width": 44 - }, - "parentId": "Iteration:BlueClothsGrab", - "position": { - "x": 22, - "y": 10 - }, - "positionAbsolute": { - "x": -261.5, - "y": -288.14062500000006 - }, - "selected": false, - "type": "iterationStartNode", - "width": 44 - }, - { - "data": { - "form": { - "query": [ - { - "component_id": "IterationItem:RudeTablesSmile", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "Baidu", - "name": "Baidu" - }, - "dragging": false, - "extent": "parent", - "height": 64, - "id": "Baidu:MeanBroomsMatter", - "measured": { - "height": 64, - "width": 200 - }, - "parentId": "Iteration:BlueClothsGrab", - "position": { - "x": 200, - "y": 0 - }, - "positionAbsolute": { - "x": -83.49999999999999, - "y": -298.14062500000006 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "delimiter": "\n", - "query": [ - { - "component_id": "Generate:RedWormsDouble", - "type": "reference" - } - ] - }, - "label": "Iteration", - "name": "Sections" - }, - "dragging": false, - "height": 225, - "id": "Iteration:ThreeParksChew", - "measured": { - "height": 225, - "width": 315 - }, - "position": { - "x": 888.9524716285371, - "y": 75.91277516159235 - }, - "positionAbsolute": { - "x": 891.9430519048244, - "y": 39.64877134989487 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 438, - "width": 328 - }, - "targetPosition": "left", - "type": "group", - "width": 315 - }, - { - "data": { - "form": {}, - "label": "IterationItem", - "name": "IterationItem" - }, - "dragging": false, - "extent": "parent", - "height": 44, - "id": "IterationItem:OliveStatesSmoke", - "measured": { - "height": 44, - "width": 44 - }, - "parentId": "Iteration:ThreeParksChew", - "position": { - "x": 24.66038685085823, - "y": 37.00025154774299 - }, - "positionAbsolute": { - "x": 780.5000000000002, - "y": 432.859375 - }, - "selected": false, - "type": "iterationStartNode", - "width": 44 - }, - { - "data": { - "form": { - "text": "It can generate a research report base on the title and language you provide." - }, - "label": "Note", - "name": "Usage" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 168, - "id": "Note:PoorMirrorsJump", - "measured": { - "height": 168, - "width": 275 - }, - "position": { - "x": -192.4712202594548, - "y": -164.26382748469516 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 275 - }, - { - "data": { - "form": { - "text": "LLM provides a series of search engine queries related to the proposition. Comprehensive research can be conducted through queries from different perspectives." - }, - "label": "Note", - "name": "N-Query" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 207, - "id": "Note:TwoSingersFly", - "measured": { - "height": 207, - "width": 256 - }, - "position": { - "x": 90.71637834539166, - "y": -160.7863367019141 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 256 - }, - { - "data": { - "form": { - "text": "LLM generates 4 subtitles for this report according to queries and title." - }, - "label": "Note", - "name": "N-Subtitles" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "id": "Note:SmoothAreasBet", - "measured": { - "height": 128, - "width": 266 - }, - "position": { - "x": 431.07789651000473, - "y": -161.0756093374443 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode" - }, - { - "data": { - "form": { - "text": "LLM generates a report for each query based on search result of each query.\nYou could change Baidu to other search engines." - }, - "label": "Note", - "name": "N-Search" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 168, - "id": "Note:CleanTablesCamp", - "measured": { - "height": 168, - "width": 364 - }, - "position": { - "x": 435.9578972976612, - "y": 452.5021839330345 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 364 - }, - { - "data": { - "form": { - "text": "LLM generates 4 sub-sections for 4 subtitles based on the report of search engine result." - }, - "label": "Note", - "name": "N-Sections" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 142, - "id": "Note:FamousToesReply", - "measured": { - "height": 142, - "width": 336 - }, - "position": { - "x": 881.4352587545767, - "y": -165.7333893115248 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 336 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "\n\nGenerate a series of appropriate search engine queries to break down questions based on user inquiries\n\n\n\n\nInput: User asks how to learn programming\nOutput: programming learning methods, programming tutorials for beginners\n\n\n\nInput: User wants to understand latest technology trends \nOutput: tech trends 2024, latest technology news\n\n\n\nInput: User seeks healthy eating advice\nOutput: healthy eating guide, balanced nutrition diet\n\n\n\n\n1. Take user's question as input.\n2. Identify relevant keywords or phrases based on the topic of user's question.\n3. Use these keywords or phrases to make search engine queries.\n4. Generate a series of appropriate search engine queries to help break down user's question.\n5. Ensure output content does not contain any xml tags.\n6. The output must be pure and conform to the style without other explanations.\n7. Break down into at least 4-6 subproblems.\n8. Output is separated only by commas.\n\n\n\ntitle: {begin@title}\nlanguage: {begin@language}\nThe output must be pure and conform to the style without other explanations.\nOutput is separated only by commas.\nBreak down into at least 4-6 subproblems.\n\nOutput:", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "GenQuery" - }, - "dragging": false, - "id": "Generate:EveryCoinsStare", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 42.60311386535324, - "y": 107.45415912015176 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "According to query: ' {Generate:EveryCoinsStare}',for ' {begin@title}', generate 3 to 5 sub-titles.\n\n\nPlease generate 4 subheadings for the main title following these steps:\n - 1. Carefully read the provided main title and related content\n - 2. Analyze the core theme and key information points of the main title\n - 3. Ensure the generated subheadings maintain consistency and relevance with the main title\n - 4. Each subheading should:\n - Be concise and appropriate in length\n - Highlight a unique angle or key point\n - Capture readers' interest\n - Match the overall style and tone of the article\n - 5. Between subheadings:\n - Content should not overlap\n - Logical order should be maintained\n - Should collectively support the main title\n - Use numerical sequence (1, 2, 3...) to mark each subheading\n - 6. Output format requirements:\n - Each subheading on a separate line\n - No XML tags included\n - Output subheadings content only\n\n\nlanguage: {begin@language}\nGenerate a series of appropriate sub-title to help break down ' {begin@title}'.\nBreaks down complex topics into manageable subtopics.\n\nOutput:", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Subtitles" - }, - "dragging": false, - "id": "Generate:RedWormsDouble", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 433.41522248658606, - "y": 14.302437349777136 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Your goal is to provide answers based on information from the internet. \nYou must use the provided search results to find relevant online information. \nYou should never use your own knowledge to answer questions.\nPlease include relevant url sources in the end of your answers.\n{Baidu:MeanBroomsMatter}\n\n\n\n\n\nlanguage: {begin@language}\n\n\n \" {Baidu:MeanBroomsMatter}\" \n\n\n\n\nUsing the above information, answer the following question or topic: \" {IterationItem:RudeTablesSmile} \"\nin a detailed report — The report should focus on the answer to the question, should be well structured, informative, in depth, with facts and numbers if available, a minimum of 1,200 words and with markdown syntax and apa format. Write all source urls at the end of the report in apa format. You should write your report only based on the given information and nothing else.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "GenSearchReport" - }, - "dragging": false, - "extent": "parent", - "id": "Generate:YoungClownsKnock", - "measured": { - "height": 106, - "width": 200 - }, - "parentId": "Iteration:BlueClothsGrab", - "position": { - "x": 115.34644687476163, - "y": 73.07611243293042 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "In a detailed report — The report should focus on the answer to {IterationItem:OliveStatesSmoke}and nothing else.\n\n\nLanguage: {begin@language}\nContext as bellow: \n\n\"{Iteration:BlueClothsGrab}\"\n\nProvide the research report in the specified language, avoiding small talk.\nThe main content is provided in markdown format\nWrite all source urls at the end of the report in apa format. ", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Subtitle-content" - }, - "dragging": false, - "extent": "parent", - "id": "Generate:RealLoopsVanish", - "measured": { - "height": 106, - "width": 200 - }, - "parentId": "Iteration:ThreeParksChew", - "position": { - "x": 189.94391141062363, - "y": 5.408501635610101 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "content": "

{IterationItem:OliveStatesSmoke}

\n
{Generate:RealLoopsVanish}
", - "parameters": [] - }, - "label": "Template", - "name": "Sub-section" - }, - "dragging": false, - "extent": "parent", - "id": "Template:SpottyWaspsLose", - "measured": { - "height": 76, - "width": 200 - }, - "parentId": "Iteration:ThreeParksChew", - "position": { - "x": 107.51010102435532, - "y": 127.82322102671017 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "templateNode" - }, - { - "data": { - "form": { - "content": "

{begin@title}

\n\n\n\n{Iteration:ThreeParksChew}", - "parameters": [] - }, - "label": "Template", - "name": "Article" - }, - "dragging": false, - "id": "Template:LegalDoorsAct", - "measured": { - "height": 76, - "width": 200 - }, - "position": { - "x": 1209.0758608851872, - "y": 149.01984563839733 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "templateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/jpeg;base64,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" -} \ No newline at end of file diff --git a/agent/templates/seo_blog.json b/agent/templates/seo_blog.json deleted file mode 100644 index 051d74642..000000000 --- a/agent/templates/seo_blog.json +++ /dev/null @@ -1,1209 +0,0 @@ -{ - "id": 9, - "title": "SEO Blog Generator", - "description": "A blog generator that creates SEO-optimized content based on your chosen title or keywords.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:TameWavesChange": { - "downstream": [], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "Template:YellowPlumsYell" - ] - }, - "Baidu:SharpSignsBeg": { - "downstream": [ - "Generate:FastTipsCamp" - ], - "obj": { - "component_name": "Baidu", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "Generate:PublicPotsPush", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "Generate:PublicPotsPush" - ] - }, - "Baidu:ShyTeamsJuggle": { - "downstream": [ - "Generate:ReadyHandsInvent" - ], - "obj": { - "component_name": "Baidu", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "begin@keywords", - "type": "reference" - } - ], - "top_n": 10 - } - }, - "upstream": [ - "Switch:LargeWaspsSlide" - ] - }, - "Generate:CuddlyBatsCamp": { - "downstream": [ - "Template:YellowPlumsYell" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "You are an SEO expert who writes in a direct, practical, educational style that is factual rather than storytelling or narrative, focusing on explaining to {begin@audience} the \"how\" and \"what is\" and “why” rather than narrating to the audience. \n - Please write at a sixth grade reading level. \n - ONLY output in Markdown format.\n - Use positive, present tense expressions and avoid using complex words and sentence structures that lack narrative, such as \"reveal\" and \"dig deep.\"\n - Next, please continue writing articles related to our topic with a concise title, {begin@title}{Generate:ReadyHandsInvent} {begin@keywords}{Generate:FancyMomentsTalk}. \n - Please AVOID repeating what has already been written and do not use the same sentence structure. \n - JUST write the body of the article based on the outline.\n - DO NOT include introduction, title.\n - DO NOT miss anything mentioned in article outline, except introduction and title.\n - Please use the information I provide to create in-depth, interesting and unique content. Also, incorporate the references and data points I provided earlier into the article to increase its value to the reader.\n - MUST be in language as \" {begin@keywords} {begin@title}\".\n\n\n{Generate:FastTipsCamp}\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Generate:FastTipsCamp" - ] - }, - "Generate:FancyMomentsTalk": { - "downstream": [ - "Generate:PublicPotsPush" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [ - { - "component_id": "begin@title", - "id": "2beef84b-204b-475a-89b3-3833bd108088", - "key": "title" - } - ], - "presence_penalty": 0.4, - "prompt": "I'm doing research for an article called {begin@title}, what relevant, high-traffic phrase should I type into Google to find this article? Just return the phrase without including any special symbols like quotes and colons.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Switch:LargeWaspsSlide" - ] - }, - "Generate:FastTipsCamp": { - "downstream": [ - "Generate:FortyBirdsAsk", - "Generate:CuddlyBatsCamp" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "I'm an expert blogger.\nHere is some research I did for the blog post title \" {begin@title} {Generate:ReadyHandsInvent}\".\nThese are related search results:\n{Baidu:SharpSignsBeg}\n\nPlease study it in depth:\n\nArticle title: {begin@title} {Generate:ReadyHandsInvent}\nTarget keywords: {begin@keywords} {Generate:FancyMomentsTalk}\nMy blog post’s audience: {begin@audience}\nExclude brands: {begin@brands_to_avoid}\n\nCan you write a detailed blog outline with unique chapters? \n - The outline should include specific points and details that the article can mention. \n - AVOID generalities. \n - This SHOULD be researched in depth, not generalized.\n - Each chapter includes 7-8 projects, use some of the links above for reference if you can. For each item, don't just say \"discuss how\" but actually explain in detail the points that can be made. \n - DO NOT include things that you know are false and may contain inaccuracies. You are writing for a mature audience, avoid generalities and make specific quotes. Make sure to define key terms for users in your outline. Stay away from very controversial topics. \n - In the introduction, provide the background information needed for the rest of the article.\n - Please return in base array format and only the outline array, escaping quotes in the format. Each array item includes a complete chapter:\n[\"Includes Chapter 1 of all sub-projects\", \"Includes Chapter 2 of all sub-projects\", \"Includes Chapter 3 of all sub-projects\", \"Includes Chapter 4 of all sub-projects\"...etc.]\n - Each section SHOULD be wrapped with \"\" and ensure escaping within the content to ensure it is a valid array item.\n - MUST be in language of \" {begin@keywords} {begin@title}\".\n\nHere is an example of valid output. Please follow this structure and ignore the content:\n[\n \"Introduction - Explore the vibrant city of Miami, a destination that offers rich history, diverse culture, and many hidden treasures. Discover the little-known wonders that make Miami a unique destination for adventure seekers. Explore from historical landmarks to exotic places Attractions include atmospheric neighborhoods, local cuisine and lively nightlife. \",\n \"History of Miami - Begin the adventure with a journey into Miami's past. Learn about the city's transformation from a sleepy settlement to a busy metropolis. Understand the impact of multiculturalism on the city's development, as reflected in its architecture, cuisine and lifestyle See. Discover the historical significance of Miami landmarks like Hemingway's home. Uncover the fascinating stories of famous Miami neighborhoods like Key West. Explore the role of art and culture in shaping Miami, as shown at Art Basel events.\n\"Major Attractions - Go beyond Miami's famous beaches and explore the city's top attractions. Discover the artistic talent of the Wynwood Arts District, known for its vibrant street art. Visit iconic South Beach, known for its nightlife and boutiques . Explore the charming Coconut Grove district, known for its tree-lined streets and shopping areas. Visit the Holocaust Memorial Museum, a sombre reminder of a dark chapter in human history. Explore the Everglades Country, one of Miami's natural treasures. The park's diverse wildlife \",\n\"Trail Discovery - Get off the tourist trail and discover Miami's hidden treasures. Experience a water taxi tour across Biscayne Bay to get another perspective on the city. Visit the little-known Kabinett Department of Art, showcasing unique installation art . Explore the abandoned bridges and hidden bars of Duval Street and go on a culinary adventure in local neighborhoods known for their authentic cuisine. Go shopping at Brickell City Center, a trendy shopping and apartment complex in the heart of Miami. body.\",\n\"Local Cuisine - Dive into Miami's food scene and sample the city's diverse flavors. Enjoy ultra-fresh food and drinks at Bartaco, a local favorite. Experience fine dining at upscale Italian restaurants like Il Mulino New York. Explore the city ’s local food market and sample delicious local produce in Miami. Try a unique blend of Cuban and American cuisine that is a testament to Miami’s multicultural heritage.\"\n\"Nightlife - Experience the city's lively nightlife, a perfect blend of sophistication and fun. Visit America's Social Bar & Kitchen, a sports\nA hotspot for enthusiasts. Explore the nightlife of Mary Brickell Village, known for its clubby atmosphere. Spend an evening at Smith & Walensky Miami Beach's South Point Park, known for its stunning views and vintage wines. Visit iconic Miami Beach, famous for its pulsating nightlife. \",\n \"Conclusion- Miami is more than just stunning beaches and dazzling nightlife. It is a treasure trove of experiences waiting to be discovered. From its rich history and diverse culture to its hidden treasures, local cuisine and lively nightlife, Miami has something for everyone A traveler offers a unique adventure to experience the magic of Miami Beach and create unforgettable memories with your family.\"\n]", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Baidu:SharpSignsBeg" - ] - }, - "Generate:FortyBirdsAsk": { - "downstream": [ - "Template:YellowPlumsYell" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "You are an SEO expert who writes in a direct, practical, educational style that is factual rather than storytelling or narrative, focusing on explaining to {begin@audience} the \"how\" and \"what is\" and “why” rather than narrating to the audience. \n - Please write at a sixth grade reading level. \n - ONLY output in Markdown format.\n - Use active, present tense, avoid using complex language and syntax, such as \"unravel\", \"dig deeper\", etc., \n - DO NOT provide narration.\n - Now, excluding the title, introduce the blog in 3-5 sentences. \n - Use h2 headings to write chapter titles. \n - Provide a concise, SEO-optimized title. \n - DO NOT include h3 subheadings. \n - Feel free to use bullet points, numbered lists or paragraphs, or bold text for emphasis when appropriate. \n - You should transition naturally to each section, build on each section, and should NOT repeat the same sentence structure. \n - JUST write the introduction of the article based on the outline.\n - DO NOT include title, conclusions, summaries, or summaries, no \"summaries,\" \"conclusions,\" or variations. \n - DO NOT include links or mention any companies that compete with the brand (avoid mentioning {begin@brands_to_avoid}).\n - JUST write the introduction of the article based on the outline.\n - MUST be in language as \"{Generate:FancyMomentsTalk} {Generate:ReadyHandsInvent}\".\n\n\n{Generate:FastTipsCamp}\n\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Generate:FastTipsCamp" - ] - }, - "Generate:PublicPotsPush": { - "downstream": [ - "Baidu:SharpSignsBeg" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "I want a Google search phrase to get authoritative information for my article \" {begin@title} {Generate:ReadyHandsInvent} {begin@keywords} {Generate:FancyMomentsTalk}\" for {begin@audience}. Please return a search phrase of five words or less so that I can get a good overview of the topic. Include any words you're unfamiliar with in your search query.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Generate:ReadyHandsInvent", - "Generate:FancyMomentsTalk" - ] - }, - "Generate:ReadyHandsInvent": { - "downstream": [ - "Generate:PublicPotsPush" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are an SEO expert and subject area expert. Your task is to generate an SEO article title based on the keywords provided by the user and the context of the Google search.\n\nThe context of the Google search is as follows:\n{Baidu:ShyTeamsJuggle}\nThe context of the Google search is as above.\n\nIn order to craft an SEO article title that is keyword friendly and aligns with the principles observed in the top results you share, it is important to understand why these titles are effective. Here are the principles that may help them rank high:\n1. **Keyword Placement and Clarity**: Each title directly responds to the query by containing the exact keyword or a very close variation. This clarity ensures that search engines can easily understand the relevance of the content.\n2. **Succinctness and directness**: The title is concise, making it easy to read and understand quickly. They avoid unnecessary words and get straight to the point.\n3. **Contains a definition or explanation**: The title implies that the article will define or explain the concept, which is what people searching for \"{Generate:FancyMomentsTalk}\" are looking for.\n4. **Variety of Presentation**: Despite covering similar content, each title approaches the topic from a slightly different angle. This diversity can attract the interest of a wider audience.\n\nGiven these principles, please help me generate a title that will be optimized for the keyword \"{Generate:FancyMomentsTalk}\" based on the syntax of a top-ranking title. \n\nPlease don't copy, but give better options, and avoid using language like \"master,\" \"comprehensive,\" \"discover,\" or \"reveal.\" \n\nDo not use gerunds, only active tense and present tense. \n\nTitle SHOULD be in language as \"{Generate:FancyMomentsTalk}\"\n\nJust return the title.", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Baidu:ShyTeamsJuggle" - ] - }, - "Switch:LargeWaspsSlide": { - "downstream": [ - "Baidu:ShyTeamsJuggle", - "Generate:FancyMomentsTalk" - ], - "obj": { - "component_name": "Switch", - "inputs": [], - "output": null, - "params": { - "conditions": [ - { - "items": [ - { - "cpn_id": "begin@title", - "operator": "empty" - } - ], - "logical_operator": "and", - "to": "Baidu:ShyTeamsJuggle" - } - ], - "debug_inputs": [], - "end_cpn_id": "Generate:FancyMomentsTalk", - "inputs": [], - "message_history_window_size": 22, - "operators": [ - "contains", - "not contains", - "start with", - "end with", - "empty", - "not empty", - "=", - "≠", - ">", - "<", - "≥", - "≤" - ], - "output": null, - "output_var_name": "output", - "query": [] - } - }, - "upstream": [ - "begin" - ] - }, - "Template:YellowPlumsYell": { - "downstream": [ - "Answer:TameWavesChange" - ], - "obj": { - "component_name": "Template", - "inputs": [], - "output": null, - "params": { - "content": "\n##{begin@title}{Generate:ReadyHandsInvent}\n\n{Generate:FortyBirdsAsk}\n\n\n\n{Generate:CuddlyBatsCamp}\n\n\n", - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameters": [], - "query": [] - } - }, - "upstream": [ - "Generate:FortyBirdsAsk", - "Generate:CuddlyBatsCamp" - ] - }, - "begin": { - "downstream": [ - "Switch:LargeWaspsSlide" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "", - "query": [ - { - "key": "title", - "name": "Title", - "optional": true, - "type": "line" - }, - { - "key": "keywords", - "name": "Keywords", - "optional": true, - "type": "line" - }, - { - "key": "audience", - "name": "Audience", - "optional": true, - "type": "line" - }, - { - "key": "brands_to_avoid", - "name": "Brands to avoid", - "optional": true, - "type": "line" - } - ] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-begin-Switch:LargeWaspsSlidea", - "markerEnd": "logo", - "source": "begin", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Switch:LargeWaspsSlide", - "targetHandle": "a", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Switch:LargeWaspsSlideCase 1-Baidu:ShyTeamsJugglec", - "markerEnd": "logo", - "source": "Switch:LargeWaspsSlide", - "sourceHandle": "Case 1", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Baidu:ShyTeamsJuggle", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Switch:LargeWaspsSlideend_cpn_id-Generate:FancyMomentsTalkc", - "markerEnd": "logo", - "source": "Switch:LargeWaspsSlide", - "sourceHandle": "end_cpn_id", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FancyMomentsTalk", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "xy-edge__Baidu:ShyTeamsJuggleb-Generate:ReadyHandsInventc", - "markerEnd": "logo", - "source": "Baidu:ShyTeamsJuggle", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ReadyHandsInvent", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:ReadyHandsInventb-Generate:PublicPotsPushc", - "markerEnd": "logo", - "source": "Generate:ReadyHandsInvent", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:PublicPotsPush", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:FancyMomentsTalkb-Generate:PublicPotsPushc", - "markerEnd": "logo", - "source": "Generate:FancyMomentsTalk", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:PublicPotsPush", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:PublicPotsPushb-Baidu:SharpSignsBegc", - "markerEnd": "logo", - "source": "Generate:PublicPotsPush", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Baidu:SharpSignsBeg", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Baidu:SharpSignsBegb-Generate:FastTipsCampc", - "markerEnd": "logo", - "source": "Baidu:SharpSignsBeg", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FastTipsCamp", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:FastTipsCampb-Generate:FortyBirdsAskc", - "markerEnd": "logo", - "source": "Generate:FastTipsCamp", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:FortyBirdsAsk", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:FastTipsCampb-Generate:CuddlyBatsCampc", - "markerEnd": "logo", - "source": "Generate:FastTipsCamp", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:CuddlyBatsCamp", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:FortyBirdsAskb-Template:YellowPlumsYellc", - "markerEnd": "logo", - "source": "Generate:FortyBirdsAsk", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Template:YellowPlumsYell", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:CuddlyBatsCampb-Template:YellowPlumsYellc", - "markerEnd": "logo", - "source": "Generate:CuddlyBatsCamp", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Template:YellowPlumsYell", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Template:YellowPlumsYellb-Answer:TameWavesChangec", - "markerEnd": "logo", - "source": "Template:YellowPlumsYell", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:TameWavesChange", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "form": { - "prologue": "", - "query": [ - { - "key": "title", - "name": "Title", - "optional": true, - "type": "line" - }, - { - "key": "keywords", - "name": "Keywords", - "optional": true, - "type": "line" - }, - { - "key": "audience", - "name": "Audience", - "optional": true, - "type": "line" - }, - { - "key": "brands_to_avoid", - "name": "Brands to avoid", - "optional": true, - "type": "line" - } - ] - }, - "label": "Begin", - "name": "begin" - }, - "dragging": false, - "height": 212, - "id": "begin", - "measured": { - "height": 212, - "width": 200 - }, - "position": { - "x": -432.2850120660528, - "y": 82.47567395502324 - }, - "positionAbsolute": { - "x": -432.2850120660528, - "y": 82.47567395502324 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode", - "width": 200 - }, - { - "data": { - "form": { - "conditions": [ - { - "items": [ - { - "cpn_id": "begin@title", - "operator": "empty" - } - ], - "logical_operator": "and", - "to": "Baidu:ShyTeamsJuggle" - } - ], - "end_cpn_id": "Generate:FancyMomentsTalk" - }, - "label": "Switch", - "name": "Empty title?" - }, - "dragging": false, - "height": 164, - "id": "Switch:LargeWaspsSlide", - "measured": { - "height": 164, - "width": 200 - }, - "position": { - "x": -171.8139076194234, - "y": 106.58178484885428 - }, - "positionAbsolute": { - "x": -171.8139076194234, - "y": 106.58178484885428 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "switchNode", - "width": 200 - }, - { - "data": { - "form": { - "query": [ - { - "component_id": "begin@keywords", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "Baidu", - "name": "Baidu4title" - }, - "dragging": false, - "height": 64, - "id": "Baidu:ShyTeamsJuggle", - "measured": { - "height": 64, - "width": 200 - }, - "position": { - "x": 99.2698941117485, - "y": 131.97513574677558 - }, - "positionAbsolute": { - "x": 99.2698941117485, - "y": 131.97513574677558 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [ - { - "component_id": "begin@title", - "id": "2beef84b-204b-475a-89b3-3833bd108088", - "key": "title" - } - ], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "I'm doing research for an article called {begin@title}, what relevant, high-traffic phrase should I type into Google to find this article? Just return the phrase without including any special symbols like quotes and colons.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Keywords gen" - }, - "dragging": false, - "height": 148, - "id": "Generate:FancyMomentsTalk", - "measured": { - "height": 148, - "width": 200 - }, - "position": { - "x": 102.41401952481024, - "y": 250.74278147746412 - }, - "positionAbsolute": { - "x": 102.41401952481024, - "y": 250.74278147746412 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "width": 200 - }, - { - "data": { - "form": { - "query": [ - { - "component_id": "Generate:PublicPotsPush", - "type": "reference" - } - ], - "top_n": 10 - }, - "label": "Baidu", - "name": "Baidu4Info" - }, - "dragging": false, - "height": 64, - "id": "Baidu:SharpSignsBeg", - "measured": { - "height": 64, - "width": 200 - }, - "position": { - "x": 932.3075370153801, - "y": 293.31101119905543 - }, - "positionAbsolute": { - "x": 933.5156264729844, - "y": 289.6867428262425 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "Interact_0" - }, - "dragging": false, - "height": 44, - "id": "Answer:TameWavesChange", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 2067.9179213988796, - "y": 373.3415280349531 - }, - "positionAbsolute": { - "x": 2150.301454782809, - "y": 360.9062777128506 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Function: Collect information such as keywords, titles, audience, words/brands to avoid, tone, and other details provided by the user.\n\nVariables:\n - keyword:Keywords\n - title:Title, \n - audience:Audience\n - brands_to_avoid:Words/brands to avoid.\n\nMUST NOT both of keywords and title are blank." - }, - "label": "Note", - "name": "N:Begin" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 368, - "id": "Note:FruityColtsBattle", - "measured": { - "height": 368, - "width": 275 - }, - "position": { - "x": -430.17115299591364, - "y": -320.31044749815453 - }, - "positionAbsolute": { - "x": -430.17115299591364, - "y": -320.31044749815453 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 368, - "width": 275 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 275 - }, - { - "data": { - "form": { - "text": "If title is not empty, let LLM help you to generate keywords." - }, - "label": "Note", - "name": "N: Keywords gen" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:SilverGiftsHide", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": 100.4673650631783, - "y": 414.8198461927788 - }, - "positionAbsolute": { - "x": 100.4673650631783, - "y": 414.8198461927788 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "Use user defined keywords to search.\nNext, generate a title based on the search result.\nChange to DuckDuckGo if you want." - }, - "label": "Note", - "name": "N: Baidu4title" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 192, - "id": "Note:ShaggyMelonsFail", - "measured": { - "height": 192, - "width": 254 - }, - "position": { - "x": 101.98068917850298, - "y": -79.85480052081127 - }, - "positionAbsolute": { - "x": 101.98068917850298, - "y": -79.85480052081127 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 192, - "width": 254 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 254 - }, - { - "data": { - "form": { - "text": "Let LLM to generate keywords to search. \nBased on the search result, the outline of the article will be generated." - }, - "label": "Note", - "name": "N: Words to search" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 132, - "id": "Note:EvilIdeasDress", - "measured": { - "height": 132, - "width": 496 - }, - "position": { - "x": 822.1382301557384, - "y": 1.1013324480075255 - }, - "positionAbsolute": { - "x": 822.1382301557384, - "y": 1.1013324480075255 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 132, - "width": 496 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 496 - }, - { - "data": { - "form": { - "text": "1 . User input:\nThe user enters information such as avoid keywords, title, audience, required words/brands, tone, etc. at the start node.\n\n2. Conditional judgment:\nCheck whether the title is empty, if it is empty, generate the title.\n\n3. Generate titles and keywords:\nGenerate SEO optimized titles and related keywords based on the entered user keywords.\n\n4. Web search:\nUse the generated titles and keywords to conduct a Google search to obtain relevant information.\n\n5. Generate outline and articles:\nGenerate article outlines, topics, and bodies based on user input information and search results.\n\n6. Template conversion and output:\nCombine the beginning of the article and the main body to generate a complete article, and output the result." - }, - "label": "Note", - "name": "Steps" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 456, - "id": "Note:WeakApesDivide", - "measured": { - "height": 456, - "width": 955 - }, - "position": { - "x": 441.5385839522079, - "y": 638.4606789293297 - }, - "positionAbsolute": { - "x": 377.5385839522079, - "y": 638.4606789293297 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 450, - "width": 827 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 955 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are an SEO expert and subject area expert. Your task is to generate an SEO article title based on the keywords provided by the user and the context of the Google search.\n\nThe context of the Google search is as follows:\n{Baidu:ShyTeamsJuggle}\nThe context of the Google search is as above.\n\nIn order to craft an SEO article title that is keyword friendly and aligns with the principles observed in the top results you share, it is important to understand why these titles are effective. Here are the principles that may help them rank high:\n1. **Keyword Placement and Clarity**: Each title directly responds to the query by containing the exact keyword or a very close variation. This clarity ensures that search engines can easily understand the relevance of the content.\n2. **Succinctness and directness**: The title is concise, making it easy to read and understand quickly. They avoid unnecessary words and get straight to the point.\n3. **Contains a definition or explanation**: The title implies that the article will define or explain the concept, which is what people searching for \"{Generate:FancyMomentsTalk}\" are looking for.\n4. **Variety of Presentation**: Despite covering similar content, each title approaches the topic from a slightly different angle. This diversity can attract the interest of a wider audience.\n\nGiven these principles, please help me generate a title that will be optimized for the keyword \"{Generate:FancyMomentsTalk}\" based on the syntax of a top-ranking title. \n\nPlease don't copy, but give better options, and avoid using language like \"master,\" \"comprehensive,\" \"discover,\" or \"reveal.\" \n\nDo not use gerunds, only active tense and present tense. \n\nTitle SHOULD be in language as \"{Generate:FancyMomentsTalk}\"\n\nJust return the title.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Title Gen" - }, - "dragging": false, - "id": "Generate:ReadyHandsInvent", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 362.61841535531624, - "y": 109.52633857873508 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "I want a Google search phrase to get authoritative information for my article \" {begin@title} {Generate:ReadyHandsInvent} {begin@keywords} {Generate:FancyMomentsTalk}\" for {begin@audience}. Please return a search phrase of five words or less so that I can get a good overview of the topic. Include any words you're unfamiliar with in your search query.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Words to search" - }, - "dragging": false, - "id": "Generate:PublicPotsPush", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 631.7110159663526, - "y": 271.70568678331114 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "I'm an expert blogger.\nHere is some research I did for the blog post title \" {begin@title} {Generate:ReadyHandsInvent}\".\nThese are related search results:\n{Baidu:SharpSignsBeg}\n\nPlease study it in depth:\n\nArticle title: {begin@title} {Generate:ReadyHandsInvent}\nTarget keywords: {begin@keywords} {Generate:FancyMomentsTalk}\nMy blog post’s audience: {begin@audience}\nExclude brands: {begin@brands_to_avoid}\n\nCan you write a detailed blog outline with unique chapters? \n - The outline should include specific points and details that the article can mention. \n - AVOID generalities. \n - This SHOULD be researched in depth, not generalized.\n - Each chapter includes 7-8 projects, use some of the links above for reference if you can. For each item, don't just say \"discuss how\" but actually explain in detail the points that can be made. \n - DO NOT include things that you know are false and may contain inaccuracies. You are writing for a mature audience, avoid generalities and make specific quotes. Make sure to define key terms for users in your outline. Stay away from very controversial topics. \n - In the introduction, provide the background information needed for the rest of the article.\n - Please return in base array format and only the outline array, escaping quotes in the format. Each array item includes a complete chapter:\n[\"Includes Chapter 1 of all sub-projects\", \"Includes Chapter 2 of all sub-projects\", \"Includes Chapter 3 of all sub-projects\", \"Includes Chapter 4 of all sub-projects\"...etc.]\n - Each section SHOULD be wrapped with \"\" and ensure escaping within the content to ensure it is a valid array item.\n - MUST be in language of \" {begin@keywords} {begin@title}\".\n\nHere is an example of valid output. Please follow this structure and ignore the content:\n[\n \"Introduction - Explore the vibrant city of Miami, a destination that offers rich history, diverse culture, and many hidden treasures. Discover the little-known wonders that make Miami a unique destination for adventure seekers. Explore from historical landmarks to exotic places Attractions include atmospheric neighborhoods, local cuisine and lively nightlife. \",\n \"History of Miami - Begin the adventure with a journey into Miami's past. Learn about the city's transformation from a sleepy settlement to a busy metropolis. Understand the impact of multiculturalism on the city's development, as reflected in its architecture, cuisine and lifestyle See. Discover the historical significance of Miami landmarks like Hemingway's home. Uncover the fascinating stories of famous Miami neighborhoods like Key West. Explore the role of art and culture in shaping Miami, as shown at Art Basel events.\n\"Major Attractions - Go beyond Miami's famous beaches and explore the city's top attractions. Discover the artistic talent of the Wynwood Arts District, known for its vibrant street art. Visit iconic South Beach, known for its nightlife and boutiques . Explore the charming Coconut Grove district, known for its tree-lined streets and shopping areas. Visit the Holocaust Memorial Museum, a sombre reminder of a dark chapter in human history. Explore the Everglades Country, one of Miami's natural treasures. The park's diverse wildlife \",\n\"Trail Discovery - Get off the tourist trail and discover Miami's hidden treasures. Experience a water taxi tour across Biscayne Bay to get another perspective on the city. Visit the little-known Kabinett Department of Art, showcasing unique installation art . Explore the abandoned bridges and hidden bars of Duval Street and go on a culinary adventure in local neighborhoods known for their authentic cuisine. Go shopping at Brickell City Center, a trendy shopping and apartment complex in the heart of Miami. body.\",\n\"Local Cuisine - Dive into Miami's food scene and sample the city's diverse flavors. Enjoy ultra-fresh food and drinks at Bartaco, a local favorite. Experience fine dining at upscale Italian restaurants like Il Mulino New York. Explore the city ’s local food market and sample delicious local produce in Miami. Try a unique blend of Cuban and American cuisine that is a testament to Miami’s multicultural heritage.\"\n\"Nightlife - Experience the city's lively nightlife, a perfect blend of sophistication and fun. Visit America's Social Bar & Kitchen, a sports\nA hotspot for enthusiasts. Explore the nightlife of Mary Brickell Village, known for its clubby atmosphere. Spend an evening at Smith & Walensky Miami Beach's South Point Park, known for its stunning views and vintage wines. Visit iconic Miami Beach, famous for its pulsating nightlife. \",\n \"Conclusion- Miami is more than just stunning beaches and dazzling nightlife. It is a treasure trove of experiences waiting to be discovered. From its rich history and diverse culture to its hidden treasures, local cuisine and lively nightlife, Miami has something for everyone A traveler offers a unique adventure to experience the magic of Miami Beach and create unforgettable memories with your family.\"\n]", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Outline gen" - }, - "dragging": false, - "id": "Generate:FastTipsCamp", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 1188.847302971411, - "y": 272.42758089250634 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "You are an SEO expert who writes in a direct, practical, educational style that is factual rather than storytelling or narrative, focusing on explaining to {begin@audience} the \"how\" and \"what is\" and “why” rather than narrating to the audience. \n - Please write at a sixth grade reading level. \n - ONLY output in Markdown format.\n - Use active, present tense, avoid using complex language and syntax, such as \"unravel\", \"dig deeper\", etc., \n - DO NOT provide narration.\n - Now, excluding the title, introduce the blog in 3-5 sentences. \n - Use h2 headings to write chapter titles. \n - Provide a concise, SEO-optimized title. \n - DO NOT include h3 subheadings. \n - Feel free to use bullet points, numbered lists or paragraphs, or bold text for emphasis when appropriate. \n - You should transition naturally to each section, build on each section, and should NOT repeat the same sentence structure. \n - JUST write the introduction of the article based on the outline.\n - DO NOT include title, conclusions, summaries, or summaries, no \"summaries,\" \"conclusions,\" or variations. \n - DO NOT include links or mention any companies that compete with the brand (avoid mentioning {begin@brands_to_avoid}).\n - JUST write the introduction of the article based on the outline.\n - MUST be in language as \"{Generate:FancyMomentsTalk} {Generate:ReadyHandsInvent}\".\n\n\n{Generate:FastTipsCamp}\n\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Introduction gen" - }, - "dragging": false, - "id": "Generate:FortyBirdsAsk", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 1467.1832072218494, - "y": 273.6641444369902 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "You are an SEO expert who writes in a direct, practical, educational style that is factual rather than storytelling or narrative, focusing on explaining to {begin@audience} the \"how\" and \"what is\" and “why” rather than narrating to the audience. \n - Please write at a sixth grade reading level. \n - ONLY output in Markdown format.\n - Use positive, present tense expressions and avoid using complex words and sentence structures that lack narrative, such as \"reveal\" and \"dig deep.\"\n - Next, please continue writing articles related to our topic with a concise title, {begin@title}{Generate:ReadyHandsInvent} {begin@keywords}{Generate:FancyMomentsTalk}. \n - Please AVOID repeating what has already been written and do not use the same sentence structure. \n - JUST write the body of the article based on the outline.\n - DO NOT include introduction, title.\n - DO NOT miss anything mentioned in article outline, except introduction and title.\n - Please use the information I provide to create in-depth, interesting and unique content. Also, incorporate the references and data points I provided earlier into the article to increase its value to the reader.\n - MUST be in language as \" {begin@keywords} {begin@title}\".\n\n\n{Generate:FastTipsCamp}\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "Body gen" - }, - "dragging": false, - "id": "Generate:CuddlyBatsCamp", - "measured": { - "height": 108, - "width": 200 - }, - "position": { - "x": 1459.030461505832, - "y": 430.80927477654984 - }, - "selected": true, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - }, - { - "data": { - "form": { - "content": "\n##{begin@title}{Generate:ReadyHandsInvent}\n\n{Generate:FortyBirdsAsk}\n\n\n\n{Generate:CuddlyBatsCamp}\n\n\n", - "parameters": [] - }, - "label": "Template", - "name": "Template trans" - }, - "dragging": false, - "id": "Template:YellowPlumsYell", - "measured": { - "height": 76, - "width": 200 - }, - "position": { - "x": 1784.1452214476085, - "y": 356.5796437282643 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "templateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/jpeg;base64,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" -} \ No newline at end of file diff --git a/agent/templates/text2sql.json b/agent/templates/text2sql.json deleted file mode 100644 index 9d59d3005..000000000 --- a/agent/templates/text2sql.json +++ /dev/null @@ -1,651 +0,0 @@ -{ - "id": 5, - "title": "Text To SQL", - "description": "An agent that converts user queries into SQL statements. You must prepare three knowledge bases: 1: DDL for your database; 2: Examples of user queries converted to SQL statements; 3: A comprehensive description of your database, including but not limited to tables and records.", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:SocialAdsWonder": { - "downstream": [ - "Retrieval:TrueCornersJam", - "Retrieval:EasyDryersShop", - "Retrieval:LazyChefsWatch" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "begin", - "Generate:CurlyFalconsWorry" - ] - }, - "Generate:CurlyFalconsWorry": { - "downstream": [ - "Answer:SocialAdsWonder" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": false, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 1, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "##The user provides a question and you provide SQL. You will only respond with SQL code and not with any explanations.\n\n##Respond with only SQL code. Do not answer with any explanations -- just the code.\n\n##You may use the following DDL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:TrueCornersJam}.\n\n##You may use the following documentation as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:LazyChefsWatch}.\n\n##You may use the following SQL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:EasyDryersShop}.\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:LazyChefsWatch", - "Retrieval:EasyDryersShop", - "Retrieval:TrueCornersJam" - ] - }, - "Retrieval:EasyDryersShop": { - "downstream": [ - "Generate:CurlyFalconsWorry" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "Nothing found in Q-SQL!", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 8 - } - }, - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "Retrieval:LazyChefsWatch": { - "downstream": [ - "Generate:CurlyFalconsWorry" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "Nothing found in DB-Description!", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 8 - } - }, - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "Retrieval:TrueCornersJam": { - "downstream": [ - "Generate:CurlyFalconsWorry" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "Nothing found in DDL!", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "rerank_id": "", - "similarity_threshold": 0.02, - "top_k": 1024, - "top_n": 8 - } - }, - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "begin": { - "downstream": [ - "Answer:SocialAdsWonder" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "Hi! I'm your smart assistant. What can I do for you?", - "query": [] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-begin-Answer:SocialAdsWonderc", - "markerEnd": "logo", - "source": "begin", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:SocialAdsWonder", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:SocialAdsWonderb-Retrieval:TrueCornersJamc", - "markerEnd": "logo", - "source": "Answer:SocialAdsWonder", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:TrueCornersJam", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:SocialAdsWonderb-Retrieval:EasyDryersShopc", - "markerEnd": "logo", - "source": "Answer:SocialAdsWonder", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:EasyDryersShop", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:SocialAdsWonderb-Retrieval:LazyChefsWatchc", - "markerEnd": "logo", - "source": "Answer:SocialAdsWonder", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:LazyChefsWatch", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "xy-edge__Retrieval:LazyChefsWatchb-Generate:CurlyFalconsWorryb", - "markerEnd": "logo", - "source": "Retrieval:LazyChefsWatch", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:CurlyFalconsWorry", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:EasyDryersShopb-Generate:CurlyFalconsWorryb", - "markerEnd": "logo", - "source": "Retrieval:EasyDryersShop", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:CurlyFalconsWorry", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:TrueCornersJamb-Generate:CurlyFalconsWorryb", - "markerEnd": "logo", - "source": "Retrieval:TrueCornersJam", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:CurlyFalconsWorry", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Generate:CurlyFalconsWorryc-Answer:SocialAdsWonderc", - "markerEnd": "logo", - "source": "Generate:CurlyFalconsWorry", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:SocialAdsWonder", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "label": "Begin", - "name": "begin" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": -520.486587527275, - "y": 117.87988995940702 - }, - "positionAbsolute": { - "x": -520.486587527275, - "y": 117.87988995940702 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "interface" - }, - "dragging": false, - "height": 44, - "id": "Answer:SocialAdsWonder", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -237.69220760465112, - "y": 119.9282206409824 - }, - "positionAbsolute": { - "x": -284.9289105495367, - "y": 119.9282206409824 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "Nothing found in DDL!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.02, - "top_n": 8 - }, - "label": "Retrieval", - "name": "DDL" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:TrueCornersJam", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 119.61927071085717, - "y": -40.184181873335746 - }, - "positionAbsolute": { - "x": 119.61927071085717, - "y": -40.184181873335746 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "Nothing found in Q-SQL!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "Q->SQL" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:EasyDryersShop", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 80.07777425685605, - "y": 120.03075150115158 - }, - "positionAbsolute": { - "x": 81.2024576603057, - "y": 94.16303322180948 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "Nothing found in DB-Description!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "DB Description" - }, - "dragging": false, - "height": 44, - "id": "Retrieval:LazyChefsWatch", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": 51.228157704293324, - "y": 252.77721891325103 - }, - "positionAbsolute": { - "x": 51.228157704293324, - "y": 252.77721891325103 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "Receives a sentence that the user wants to convert into SQL and displays the result of the large model's SQL conversion." - }, - "label": "Note", - "name": "N: Interface" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 132, - "id": "Note:GentleRabbitsWonder", - "measured": { - "height": 132, - "width": 324 - }, - "position": { - "x": -287.3066094433631, - "y": -30.808189185380513 - }, - "positionAbsolute": { - "x": -287.3066094433631, - "y": -30.808189185380513 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 132, - "width": 324 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 324 - }, - { - "data": { - "form": { - "text": "The large model learns which tables may be available based on the responses from three knowledge bases and converts the user's input into SQL statements." - }, - "label": "Note", - "name": "N: LLM" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 163, - "id": "Note:SixCitiesJoke", - "measured": { - "height": 163, - "width": 334 - }, - "position": { - "x": 19.243366453487255, - "y": 531.9336820600888 - }, - "positionAbsolute": { - "x": 5.12121582244032, - "y": 637.6539219843564 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 147, - "width": 326 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 334 - }, - { - "data": { - "form": { - "text": "Searches for description about meanings of tables and fields." - }, - "label": "Note", - "name": "N: DB description" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:FamousCarpetsTaste", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": 399.9267065852242, - "y": 250.0329701879931 - }, - "positionAbsolute": { - "x": 399.9267065852242, - "y": 250.0329701879931 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "Searches for samples about question to SQL.\nPlease check this dataset: https://huggingface.co/datasets/InfiniFlow/text2sql" - }, - "label": "Note", - "name": "N: Q->SQL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 140, - "id": "Note:PoliteBeesArrive", - "measured": { - "height": 140, - "width": 455 - }, - "position": { - "x": 491.0393427986917, - "y": 96.58232093146341 - }, - "positionAbsolute": { - "x": 489.0393427986917, - "y": 96.58232093146341 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 130, - "width": 451 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 455 - }, - { - "data": { - "form": { - "text": "DDL(Data Definition Language).\n\nSearches for relevant database creation statements.\n\nIt should bind with a KB to which DDL is dumped in.\nYou could use 'General' as parsing method and ';' as delimiter." - }, - "label": "Note", - "name": "N: DDL" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 272, - "id": "Note:SmartWingsDouble", - "measured": { - "height": 272, - "width": 288 - }, - "position": { - "x": 406.6930553966363, - "y": -208.84980249039137 - }, - "positionAbsolute": { - "x": 404.1930553966363, - "y": -208.84980249039137 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 258, - "width": 283 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 288 - }, - { - "data": { - "form": { - "cite": false, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 1, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "##The user provides a question and you provide SQL. You will only respond with SQL code and not with any explanations.\n\n##Respond with only SQL code. Do not answer with any explanations -- just the code.\n\n##You may use the following DDL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:TrueCornersJam}.\n\n##You may use the following documentation as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:LazyChefsWatch}.\n\n##You may use the following SQL statements as a reference for what tables might be available. Use responses to past questions also to guide you: {Retrieval:EasyDryersShop}.\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "GenSQL" - }, - "dragging": false, - "id": "Generate:CurlyFalconsWorry", - "measured": { - "height": 106, - "width": 200 - }, - "position": { - "x": 10.728415797190792, - "y": 410.2569651241076 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} diff --git a/agent/templates/websearch_assistant.json b/agent/templates/websearch_assistant.json deleted file mode 100644 index 1b6308f69..000000000 --- a/agent/templates/websearch_assistant.json +++ /dev/null @@ -1,996 +0,0 @@ -{ - "id": 0, - "title": "WebSearch Assistant", - "description": "A chat assistant template that integrates information extracted from a knowledge base and web searches to respond to queries. Let's begin by setting up your knowledge base in 'Retrieval'!", - "canvas_type": "chatbot", - "dsl": { - "answer": [], - "components": { - "Answer:PoorMapsCover": { - "downstream": [ - "RewriteQuestion:OrangeBottlesSwim" - ], - "obj": { - "component_name": "Answer", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "post_answers": [], - "query": [] - } - }, - "upstream": [ - "begin", - "Generate:ItchyRiversDrum" - ] - }, - "Baidu:OliveAreasCall": { - "downstream": [ - "Generate:ItchyRiversDrum" - ], - "obj": { - "component_name": "Baidu", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:BeigeTipsStand", - "type": "reference" - } - ], - "top_n": 2 - } - }, - "upstream": [ - "KeywordExtract:BeigeTipsStand" - ] - }, - "DuckDuckGo:SoftButtonsRefuse": { - "downstream": [ - "Generate:ItchyRiversDrum" - ], - "obj": { - "component_name": "DuckDuckGo", - "inputs": [], - "output": null, - "params": { - "channel": "text", - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:BeigeTipsStand", - "type": "reference" - } - ], - "top_n": 2 - } - }, - "upstream": [ - "KeywordExtract:BeigeTipsStand" - ] - }, - "Generate:ItchyRiversDrum": { - "downstream": [ - "Answer:PoorMapsCover" - ], - "obj": { - "component_name": "Generate", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 0, - "message_history_window_size": 12, - "output": null, - "output_var_name": "output", - "parameters": [], - "presence_penalty": 0.4, - "prompt": "Role: You are an intelligent assistant. \nTask: Chat with user. Answer the question based on the provided content from: Knowledge Base, Wikipedia, Duckduckgo, Baidu.\nRequirements:\n - Answer should be in markdown format.\n - Answer should include all sources(Knowledge Base, Wikipedia, Duckduckgo, Baidu) as long as they are relevant, and label the sources of the cited content separately.\n - Attach URL links to the content which is quoted from Wikipedia, DuckDuckGo or Baidu.\n - Do not make thing up when there's no relevant information to user's question. \n\n## Knowledge base content\n{Retrieval:SilentCamelsStick}\n\n\n## Wikipedia content\n{Wikipedia:WittyRiceLearn}\n\n\n## Duckduckgo content\n{DuckDuckGo:SoftButtonsRefuse}\n\n\n## Baidu content\n{Baidu:OliveAreasCall}\n\n", - "query": [], - "temperature": 0.1, - "top_p": 0.3 - } - }, - "upstream": [ - "Retrieval:SilentCamelsStick", - "Wikipedia:WittyRiceLearn", - "Baidu:OliveAreasCall", - "DuckDuckGo:SoftButtonsRefuse" - ] - }, - "KeywordExtract:BeigeTipsStand": { - "downstream": [ - "Baidu:OliveAreasCall", - "DuckDuckGo:SoftButtonsRefuse", - "Wikipedia:WittyRiceLearn" - ], - "obj": { - "component_name": "KeywordExtract", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 2, - "top_p": 0.3 - } - }, - "upstream": [ - "RewriteQuestion:OrangeBottlesSwim" - ] - }, - "Retrieval:SilentCamelsStick": { - "downstream": [ - "Generate:ItchyRiversDrum" - ], - "obj": { - "component_name": "Retrieval", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "empty_response": "The answer you want was not found in the knowledge base!", - "inputs": [], - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [], - "rerank_id": "", - "similarity_threshold": 0.2, - "top_k": 1024, - "top_n": 8 - } - }, - "upstream": [ - "RewriteQuestion:OrangeBottlesSwim" - ] - }, - "RewriteQuestion:OrangeBottlesSwim": { - "downstream": [ - "KeywordExtract:BeigeTipsStand", - "Retrieval:SilentCamelsStick" - ], - "obj": { - "component_name": "RewriteQuestion", - "inputs": [], - "output": null, - "params": { - "cite": true, - "debug_inputs": [], - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "inputs": [], - "llm_id": "deepseek-chat@DeepSeek", - "loop": 1, - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "output": null, - "output_var_name": "output", - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "", - "query": [], - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - } - }, - "upstream": [ - "Answer:PoorMapsCover" - ] - }, - "Wikipedia:WittyRiceLearn": { - "downstream": [ - "Generate:ItchyRiversDrum" - ], - "obj": { - "component_name": "Wikipedia", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "language": "en", - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "query": [ - { - "component_id": "KeywordExtract:BeigeTipsStand", - "type": "reference" - } - ], - "top_n": 2 - } - }, - "upstream": [ - "KeywordExtract:BeigeTipsStand" - ] - }, - "begin": { - "downstream": [ - "Answer:PoorMapsCover" - ], - "obj": { - "component_name": "Begin", - "inputs": [], - "output": null, - "params": { - "debug_inputs": [], - "inputs": [], - "message_history_window_size": 22, - "output": null, - "output_var_name": "output", - "prologue": "Hi! I'm your smart assistant. What can I do for you?", - "query": [] - } - }, - "upstream": [] - } - }, - "embed_id": "", - "graph": { - "edges": [ - { - "id": "reactflow__edge-begin-Answer:PoorMapsCoverc", - "markerEnd": "logo", - "source": "begin", - "sourceHandle": null, - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:PoorMapsCover", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Answer:PoorMapsCoverb-RewriteQuestion:OrangeBottlesSwimc", - "markerEnd": "logo", - "source": "Answer:PoorMapsCover", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "RewriteQuestion:OrangeBottlesSwim", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-RewriteQuestion:OrangeBottlesSwimb-KeywordExtract:BeigeTipsStandc", - "markerEnd": "logo", - "source": "RewriteQuestion:OrangeBottlesSwim", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "KeywordExtract:BeigeTipsStand", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:BeigeTipsStandb-Baidu:OliveAreasCallc", - "markerEnd": "logo", - "source": "KeywordExtract:BeigeTipsStand", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Baidu:OliveAreasCall", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:BeigeTipsStandb-DuckDuckGo:SoftButtonsRefusec", - "markerEnd": "logo", - "source": "KeywordExtract:BeigeTipsStand", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "DuckDuckGo:SoftButtonsRefuse", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-KeywordExtract:BeigeTipsStandb-Wikipedia:WittyRiceLearnc", - "markerEnd": "logo", - "source": "KeywordExtract:BeigeTipsStand", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Wikipedia:WittyRiceLearn", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-RewriteQuestion:OrangeBottlesSwimb-Retrieval:SilentCamelsStickc", - "markerEnd": "logo", - "source": "RewriteQuestion:OrangeBottlesSwim", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Retrieval:SilentCamelsStick", - "targetHandle": "c", - "type": "buttonEdge" - }, - { - "id": "xy-edge__Generate:ItchyRiversDrumc-Answer:PoorMapsCoverc", - "markerEnd": "logo", - "source": "Generate:ItchyRiversDrum", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:PoorMapsCover", - "targetHandle": "c", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Retrieval:SilentCamelsStickb-Generate:ItchyRiversDrumb", - "markerEnd": "logo", - "source": "Retrieval:SilentCamelsStick", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ItchyRiversDrum", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Wikipedia:WittyRiceLearnb-Generate:ItchyRiversDrumb", - "markerEnd": "logo", - "source": "Wikipedia:WittyRiceLearn", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ItchyRiversDrum", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__Baidu:OliveAreasCallb-Generate:ItchyRiversDrumb", - "markerEnd": "logo", - "source": "Baidu:OliveAreasCall", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ItchyRiversDrum", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - }, - { - "id": "xy-edge__DuckDuckGo:SoftButtonsRefuseb-Generate:ItchyRiversDrumb", - "markerEnd": "logo", - "source": "DuckDuckGo:SoftButtonsRefuse", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:ItchyRiversDrum", - "targetHandle": "b", - "type": "buttonEdge", - "zIndex": 1001 - } - ], - "nodes": [ - { - "data": { - "label": "Begin", - "name": "opening" - }, - "dragging": false, - "height": 44, - "id": "begin", - "measured": { - "height": 44, - "width": 100 - }, - "position": { - "x": -1469.1118402678153, - "y": -138.55389910599428 - }, - "positionAbsolute": { - "x": -1379.627471412851, - "y": -135.63593055637585 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode" - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "interface" - }, - "dragging": false, - "height": 44, - "id": "Answer:PoorMapsCover", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -1172.8677760724227, - "y": -134.7856818291531 - }, - "positionAbsolute": { - "x": -1172.8677760724227, - "y": -134.7856818291531 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "logicNode", - "width": 200 - }, - { - "data": { - "form": { - "language": "en", - "query": [ - { - "component_id": "KeywordExtract:BeigeTipsStand", - "type": "reference" - } - ], - "top_n": 2 - }, - "label": "Wikipedia", - "name": "Wikipedia" - }, - "dragging": false, - "height": 44, - "id": "Wikipedia:WittyRiceLearn", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -406.9217458441634, - "y": -54.01023495053805 - }, - "positionAbsolute": { - "x": -406.9217458441634, - "y": -54.01023495053805 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "query": [ - { - "component_id": "KeywordExtract:BeigeTipsStand", - "type": "reference" - } - ], - "top_n": 2 - }, - "label": "Baidu", - "name": "Baidu" - }, - "dragging": false, - "height": 44, - "id": "Baidu:OliveAreasCall", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -334.8102520664264, - "y": -142.4206828864257 - }, - "positionAbsolute": { - "x": -334.8102520664264, - "y": -142.4206828864257 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "channel": "text", - "query": [ - { - "component_id": "KeywordExtract:BeigeTipsStand", - "type": "reference" - } - ], - "top_n": 2 - }, - "label": "DuckDuckGo", - "name": "DuckDuckGo" - }, - "dragging": false, - "height": 44, - "id": "DuckDuckGo:SoftButtonsRefuse", - "measured": { - "height": 44, - "width": 200 - }, - "position": { - "x": -241.42135935727495, - "y": -227.69429585279033 - }, - "positionAbsolute": { - "x": -241.42135935727495, - "y": -227.69429585279033 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "ragNode", - "width": 200 - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "loop": 1, - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 6, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "RewriteQuestion", - "name": "Refine Question" - }, - "dragging": false, - "height": 86, - "id": "RewriteQuestion:OrangeBottlesSwim", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -926.3250837910092, - "y": -156.41315582042822 - }, - "positionAbsolute": { - "x": -926.3250837910092, - "y": -156.41315582042822 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "rewriteNode", - "width": 200 - }, - { - "data": { - "form": { - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "parameter": "Precise", - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_n": 2, - "top_p": 0.3 - }, - "label": "KeywordExtract", - "name": "Get keywords" - }, - "dragging": false, - "height": 86, - "id": "KeywordExtract:BeigeTipsStand", - "measured": { - "height": 86, - "width": 200 - }, - "position": { - "x": -643.95039088561, - "y": -160.37167955274685 - }, - "positionAbsolute": { - "x": -643.95039088561, - "y": -160.37167955274685 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "keywordNode", - "width": 200 - }, - { - "data": { - "form": { - "empty_response": "The answer you want was not found in the knowledge base!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_n": 8 - }, - "label": "Retrieval", - "name": "Search KB" - }, - "dragging": false, - "height": 46, - "id": "Retrieval:SilentCamelsStick", - "measured": { - "height": 46, - "width": 200 - }, - "position": { - "x": -641.3113750640641, - "y": -4.669746081545384 - }, - "positionAbsolute": { - "x": -641.3113750640641, - "y": -4.669746081545384 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "retrievalNode", - "width": 200 - }, - { - "data": { - "form": { - "text": "The large model answers the user's query based on the content retrieved from different search engines and knowledge bases, returning an answer to the user's question." - }, - "label": "Note", - "name": "N: LLM" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 144, - "id": "Note:CuteSchoolsWear", - "measured": { - "height": 144, - "width": 443 - }, - "position": { - "x": -628.5256394373041, - "y": 412.60472782016245 - }, - "positionAbsolute": { - "x": -628.5256394373041, - "y": 412.60472782016245 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 144, - "width": 443 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 443 - }, - { - "data": { - "form": { - "text": "Complete questions by conversation history.\nUser: What's RAGFlow?\nAssistant: RAGFlow is xxx.\nUser: How to deloy it?\n\nRefine it: How to deploy RAGFlow?" - }, - "label": "Note", - "name": "N: Refine question" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 209, - "id": "Note:CuteRavensBehave", - "measured": { - "height": 209, - "width": 266 - }, - "position": { - "x": -921.2271023677847, - "y": -381.3182401779728 - }, - "positionAbsolute": { - "x": -921.2271023677847, - "y": -381.3182401779728 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 209, - "width": 266 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 266 - }, - { - "data": { - "form": { - "text": "Based on the user's question, searches the knowledge base and returns the retrieved content." - }, - "label": "Note", - "name": "N: Search KB" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:RudeRulesLeave", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": -917.896611693436, - "y": -3.570404025438563 - }, - "positionAbsolute": { - "x": -917.896611693436, - "y": -3.570404025438563 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "Based on the keywords, searches on Wikipedia and returns the found content." - }, - "label": "Note", - "name": "N: Wikipedia" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:DryActorsTry", - "measured": { - "height": 128, - "width": 281 - }, - "position": { - "x": 49.68127281474659, - "y": -16.899164744846445 - }, - "positionAbsolute": { - "x": 49.68127281474659, - "y": -16.899164744846445 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 281 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 281 - }, - { - "data": { - "form": { - "text": "Based on the keywords, searches on Baidu and returns the found content." - }, - "label": "Note", - "name": "N :Baidu" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 128, - "id": "Note:HonestShirtsNail", - "measured": { - "height": 128, - "width": 269 - }, - "position": { - "x": 43.964372149616565, - "y": -151.26282396084338 - }, - "positionAbsolute": { - "x": 43.964372149616565, - "y": -151.26282396084338 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269 - }, - { - "data": { - "form": { - "text": "Based on the keywords, searches on DuckDuckGo and returns the found content." - }, - "label": "Note", - "name": "N: DuckduckGo" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 145, - "id": "Note:OddBreadsFix", - "measured": { - "height": 145, - "width": 201 - }, - "position": { - "x": -237.54626926201882, - "y": -381.56637252684175 - }, - "positionAbsolute": { - "x": -237.54626926201882, - "y": -381.56637252684175 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 145, - "width": 201 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 201 - }, - { - "data": { - "form": { - "text": "The large model generates keywords based on the user's question for better retrieval." - }, - "label": "Note", - "name": "N: Get keywords" - }, - "dragHandle": ".note-drag-handle", - "dragging": false, - "height": 162, - "id": "Note:GentleWorldsDesign", - "measured": { - "height": 162, - "width": 201 - }, - "position": { - "x": -646.3211655055846, - "y": -334.10598887579624 - }, - "positionAbsolute": { - "x": -646.3211655055846, - "y": -334.10598887579624 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 162, - "width": 201 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 201 - }, - { - "data": { - "form": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": false, - "max_tokens": 256, - "message_history_window_size": 12, - "parameter": "Precise", - "parameters": [], - "presencePenaltyEnabled": true, - "presence_penalty": 0.4, - "prompt": "Role: You are an intelligent assistant. \nTask: Chat with user. Answer the question based on the provided content from: Knowledge Base, Wikipedia, Duckduckgo, Baidu.\nRequirements:\n - Answer should be in markdown format.\n - Answer should include all sources(Knowledge Base, Wikipedia, Duckduckgo, Baidu) as long as they are relevant, and label the sources of the cited content separately.\n - Attach URL links to the content which is quoted from Wikipedia, DuckDuckGo or Baidu.\n - Do not make thing up when there's no relevant information to user's question. \n\n## Knowledge base content\n{Retrieval:SilentCamelsStick}\n\n\n## Wikipedia content\n{Wikipedia:WittyRiceLearn}\n\n\n## Duckduckgo content\n{DuckDuckGo:SoftButtonsRefuse}\n\n\n## Baidu content\n{Baidu:OliveAreasCall}\n\n", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "LLM" - }, - "dragging": false, - "id": "Generate:ItchyRiversDrum", - "measured": { - "height": 108, - "width": 200 - }, - "position": { - "x": -636.2454246475879, - "y": 282.00479262604443 - }, - "selected": true, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} diff --git a/agent/test/client.py b/agent/test/client.py index 1ab4db386..09b685e43 100644 --- a/agent/test/client.py +++ b/agent/test/client.py @@ -15,9 +15,8 @@ # import argparse import os -from functools import partial from agent.canvas import Canvas -from agent.settings import DEBUG +from api import settings if __name__ == '__main__': parser = argparse.ArgumentParser() @@ -31,19 +30,17 @@ if __name__ == '__main__': parser.add_argument('-m', '--stream', default=False, help="Stream output", action='store_true', required=False) args = parser.parse_args() + settings.init_settings() canvas = Canvas(open(args.dsl, "r").read(), args.tenant_id) + if canvas.get_prologue(): + print(f"==================== Bot =====================\n> {canvas.get_prologue()}", end='') + query = "" while True: - ans = canvas.run(stream=args.stream) + canvas.reset(True) + query = input("\n==================== User =====================\n> ") + ans = canvas.run(query=query) print("==================== Bot =====================\n> ", end='') - if args.stream and isinstance(ans, partial): - cont = "" - for an in ans(): - print(an["content"][len(cont):], end='', flush=True) - cont = an["content"] - else: - print(ans["content"]) + for ans in canvas.run(query=query): + print(ans, end='\n', flush=True) - if DEBUG: - print(canvas.path) - question = input("\n==================== User =====================\n> ") - canvas.add_user_input(question) + print(canvas.path) diff --git a/agent/test/dsl_examples/baidu_generate_and_switch.json b/agent/test/dsl_examples/baidu_generate_and_switch.json deleted file mode 100644 index 90069cfaf..000000000 --- a/agent/test/dsl_examples/baidu_generate_and_switch.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["baidu:0"], - "upstream": ["begin", "message:0","message:1"] - }, - "baidu:0": { - "obj": { - "component_name": "Baidu", - "params": {} - }, - "downstream": ["generate:0"], - "upstream": ["answer:0"] - }, - "generate:0": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the user's question based on what Baidu searched. First, please output the user's question and the content searched by Baidu, and then answer yes, no, or i don't know.Here is the user's question:{user_input}The above is the user's question.Here is what Baidu searched for:{baidu}The above is the content searched by Baidu.", - "temperature": 0.2 - }, - "parameters": [ - { - "component_id": "answer:0", - "id": "69415446-49bf-4d4b-8ec9-ac86066f7709", - "key": "user_input" - }, - { - "component_id": "baidu:0", - "id": "83363c2a-00a8-402f-a45c-ddc4097d7d8b", - "key": "baidu" - } - ] - }, - "downstream": ["switch:0"], - "upstream": ["baidu:0"] - }, - "switch:0": { - "obj": { - "component_name": "Switch", - "params": { - "conditions": [ - { - "logical_operator" : "or", - "items" : [ - {"cpn_id": "generate:0", "operator": "contains", "value": "yes"}, - {"cpn_id": "generate:0", "operator": "contains", "value": "yeah"} - ], - "to": "message:0" - }, - { - "logical_operator" : "and", - "items" : [ - {"cpn_id": "generate:0", "operator": "contains", "value": "no"}, - {"cpn_id": "generate:0", "operator": "not contains", "value": "yes"}, - {"cpn_id": "generate:0", "operator": "not contains", "value": "know"} - ], - "to": "message:1" - }, - { - "logical_operator" : "", - "items" : [ - {"cpn_id": "generate:0", "operator": "contains", "value": "know"} - ], - "to": "message:2" - } - ], - "end_cpn_id": "answer:0" - - } - }, - "downstream": ["message:0","message:1"], - "upstream": ["generate:0"] - }, - "message:0": { - "obj": { - "component_name": "Message", - "params": { - "messages": ["YES YES YES YES YES YES YES YES YES YES YES YES"] - } - }, - - "upstream": ["switch:0"], - "downstream": ["answer:0"] - }, - "message:1": { - "obj": { - "component_name": "Message", - "params": { - "messages": ["NO NO NO NO NO NO NO NO NO NO NO NO NO NO"] - } - }, - - "upstream": ["switch:0"], - "downstream": ["answer:0"] - }, - "message:2": { - "obj": { - "component_name": "Message", - "params": { - "messages": ["I DON'T KNOW---------------------------"] - } - }, - - "upstream": ["switch:0"], - "downstream": ["answer:0"] - } - }, - "history": [], - "messages": [], - "reference": {}, - "path": [], - "answer": [] -} diff --git a/agent/test/dsl_examples/categorize.json b/agent/test/dsl_examples/categorize_and_agent_with_tavily.json similarity index 54% rename from agent/test/dsl_examples/categorize.json rename to agent/test/dsl_examples/categorize_and_agent_with_tavily.json index 600c9bc3f..7d9567446 100644 --- a/agent/test/dsl_examples/categorize.json +++ b/agent/test/dsl_examples/categorize_and_agent_with_tavily.json @@ -7,16 +7,8 @@ "prologue": "Hi there!" } }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, "downstream": ["categorize:0"], - "upstream": ["begin"] + "upstream": [] }, "categorize:0": { "obj": { @@ -26,48 +18,68 @@ "category_description": { "product_related": { "description": "The question is about the product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?", - "to": "message:0" + "to": ["agent:0"] }, "others": { "description": "The question is not about the product usage, appearance and how it works.", - "examples": "How are you doing?\nWhat is your name?\nAre you a robot?\nWhat's the weather?\nWill it rain?", - "to": "message:1" + "to": ["message:0"] } } } }, - "downstream": ["message:0","message:1"], - "upstream": ["answer:0"] + "downstream": [], + "upstream": ["begin"] }, "message:0": { - "obj": { + "obj":{ "component_name": "Message", "params": { - "messages": [ - "Message 0!!!!!!!" + "content": [ + "Sorry, I don't know. I'm an AI bot." ] } }, - "downstream": ["answer:0"], + "downstream": [], + "upstream": ["categorize:0"] + }, + "agent:0": { + "obj": { + "component_name": "Agent", + "params": { + "llm_id": "deepseek-chat", + "sys_prompt": "You are a smart researcher. You could generate proper queries to search. According to the search results, you could deside next query if the result is not enough.", + "temperature": 0.2, + "llm_enabled_tools": [ + { + "component_name": "TavilySearch", + "params": { + "api_key": "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" + } + } + ] + } + }, + "downstream": ["message:1"], "upstream": ["categorize:0"] }, "message:1": { "obj": { "component_name": "Message", "params": { - "messages": [ - "Message 1!!!!!!!" - ] + "content": ["{agent:0@content}"] } }, - "downstream": ["answer:0"], - "upstream": ["categorize:0"] + "downstream": [], + "upstream": ["agent:0"] } }, "history": [], - "messages": [], "path": [], - "reference": [], - "answer": [] -} + "retrival": {"chunks": [], "doc_aggs": []}, + "globals": { + "sys.query": "", + "sys.user_id": "", + "sys.conversation_turns": 0, + "sys.files": [] + } +} \ No newline at end of file diff --git a/agent/test/dsl_examples/concentrator_message.json b/agent/test/dsl_examples/concentrator_message.json deleted file mode 100644 index ee875ae02..000000000 --- a/agent/test/dsl_examples/concentrator_message.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["categorize:0"], - "upstream": ["begin"] - }, - "categorize:0": { - "obj": { - "component_name": "Categorize", - "params": { - "llm_id": "deepseek-chat", - "category_description": { - "product_related": { - "description": "The question is about the product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?", - "to": "concentrator:0" - }, - "others": { - "description": "The question is not about the product usage, appearance and how it works.", - "examples": "How are you doing?\nWhat is your name?\nAre you a robot?\nWhat's the weather?\nWill it rain?", - "to": "concentrator:1" - } - } - } - }, - "downstream": ["concentrator:0","concentrator:1"], - "upstream": ["answer:0"] - }, - "concentrator:0": { - "obj": { - "component_name": "Concentrator", - "params": {} - }, - "downstream": ["message:0"], - "upstream": ["categorize:0"] - }, - "concentrator:1": { - "obj": { - "component_name": "Concentrator", - "params": {} - }, - "downstream": ["message:1_0","message:1_1","message:1_2"], - "upstream": ["categorize:0"] - }, - "message:0": { - "obj": { - "component_name": "Message", - "params": { - "messages": [ - "Message 0_0!!!!!!!" - ] - } - }, - "downstream": ["answer:0"], - "upstream": ["concentrator:0"] - }, - "message:1_0": { - "obj": { - "component_name": "Message", - "params": { - "messages": [ - "Message 1_0!!!!!!!" - ] - } - }, - "downstream": ["answer:0"], - "upstream": ["concentrator:1"] - }, - "message:1_1": { - "obj": { - "component_name": "Message", - "params": { - "messages": [ - "Message 1_1!!!!!!!" - ] - } - }, - "downstream": ["answer:0"], - "upstream": ["concentrator:1"] - }, - "message:1_2": { - "obj": { - "component_name": "Message", - "params": { - "messages": [ - "Message 1_2!!!!!!!" - ] - } - }, - "downstream": ["answer:0"], - "upstream": ["concentrator:1"] - } - }, - "history": [], - "messages": [], - "path": [], - "reference": [], - "answer": [] -} \ No newline at end of file diff --git a/agent/test/dsl_examples/customer_service.json b/agent/test/dsl_examples/customer_service.json deleted file mode 100644 index 8421e3a26..000000000 --- a/agent/test/dsl_examples/customer_service.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi! How can I help you?" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["categorize:0"], - "upstream": ["begin", "generate:0", "generate:casual", "generate:answer", "generate:complain", "generate:ask_contact", "message:get_contact"] - }, - "categorize:0": { - "obj": { - "component_name": "Categorize", - "params": { - "llm_id": "deepseek-chat", - "category_description": { - "product_related": { - "description": "The question is about the product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?\nException: Can't connect to ES cluster\nHow to build the RAGFlow image from scratch", - "to": "retrieval:0" - }, - "casual": { - "description": "The question is not about the product usage, appearance and how it works. Just casual chat.", - "examples": "How are you doing?\nWhat is your name?\nAre you a robot?\nWhat's the weather?\nWill it rain?", - "to": "generate:casual" - }, - "complain": { - "description": "Complain even curse about the product or service you provide. But the comment is not specific enough.", - "examples": "How bad is it.\nIt's really sucks.\nDamn, for God's sake, can it be more steady?\nShit, I just can't use this shit.\nI can't stand it anymore.", - "to": "generate:complain" - }, - "answer": { - "description": "This answer provide a specific contact information, like e-mail, phone number, wechat number, line number, twitter, discord, etc,.", - "examples": "My phone number is 203921\nkevinhu.hk@gmail.com\nThis is my discord number: johndowson_29384", - "to": "message:get_contact" - } - }, - "message_history_window_size": 8 - } - }, - "downstream": ["retrieval:0", "generate:casual", "generate:complain", "message:get_contact"], - "upstream": ["answer:0"] - }, - "generate:casual": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are a customer support. But the customer wants to have a casual chat with you instead of consulting about the product. Be nice, funny, enthusiasm and concern.", - "temperature": 0.9, - "message_history_window_size": 12, - "cite": false - } - }, - "downstream": ["answer:0"], - "upstream": ["categorize:0"] - }, - "generate:complain": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are a customer support. the Customers complain even curse about the products but not specific enough. You need to ask him/her what's the specific problem with the product. Be nice, patient and concern to soothe your customers’ emotions at first place.", - "temperature": 0.9, - "message_history_window_size": 12, - "cite": false - } - }, - "downstream": ["answer:0"], - "upstream": ["categorize:0"] - }, - "retrieval:0": { - "obj": { - "component_name": "Retrieval", - "params": { - "similarity_threshold": 0.2, - "keywords_similarity_weight": 0.3, - "top_n": 6, - "top_k": 1024, - "rerank_id": "BAAI/bge-reranker-v2-m3", - "kb_ids": ["869a236818b811ef91dffa163e197198"] - } - }, - "downstream": ["relevant:0"], - "upstream": ["categorize:0"] - }, - "relevant:0": { - "obj": { - "component_name": "Relevant", - "params": { - "llm_id": "deepseek-chat", - "temperature": 0.02, - "yes": "generate:answer", - "no": "generate:ask_contact" - } - }, - "downstream": ["generate:answer", "generate:ask_contact"], - "upstream": ["retrieval:0"] - }, - "generate:answer": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the question based on content of knowledge base. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\". Answers need to consider chat history.\n Knowledge base content is as following:\n {input}\n The above is the content of knowledge base.", - "temperature": 0.02 - } - }, - "downstream": ["answer:0"], - "upstream": ["relevant:0"] - }, - "generate:ask_contact": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are a customer support. But you can't answer to customers' question. You need to request their contact like E-mail, phone number, Wechat number, LINE number, twitter, discord, etc,. Product experts will contact them later. Please do not ask the same question twice.", - "temperature": 0.9, - "message_history_window_size": 12, - "cite": false - } - }, - "downstream": ["answer:0"], - "upstream": ["relevant:0"] - }, - "message:get_contact": { - "obj":{ - "component_name": "Message", - "params": { - "messages": [ - "Okay, I've already write this down. What else I can do for you?", - "Get it. What else I can do for you?", - "Thanks for your trust! Our expert will contact ASAP. So, anything else I can do for you?", - "Thanks! So, anything else I can do for you?" - ] - } - }, - "downstream": ["answer:0"], - "upstream": ["categorize:0"] - } - }, - "history": [], - "messages": [], - "path": [], - "reference": [], - "answer": [] -} \ No newline at end of file diff --git a/agent/test/dsl_examples/intergreper.json b/agent/test/dsl_examples/intergreper.json deleted file mode 100644 index e528b2756..000000000 --- a/agent/test/dsl_examples/intergreper.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there! Please enter the text you want to translate in format like: 'text you want to translate' => target language. For an example: 您好! => English" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["generate:0"], - "upstream": ["begin", "generate:0"] - }, - "generate:0": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an professional interpreter.\n- Role: an professional interpreter.\n- Input format: content need to be translated => target language. \n- Answer format: => translated content in target language. \n- Examples:\n - user: 您好! => English. assistant: => How are you doing!\n - user: You look good today. => Japanese. assistant: => 今日は調子がいいですね 。\n", - "temperature": 0.5 - } - }, - "downstream": ["answer:0"], - "upstream": ["answer:0"] - } - }, - "history": [], - "messages": [], - "reference": {}, - "path": [], - "answer": [] -} \ No newline at end of file diff --git a/agent/test/dsl_examples/interpreter.json b/agent/test/dsl_examples/interpreter.json deleted file mode 100644 index e528b2756..000000000 --- a/agent/test/dsl_examples/interpreter.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there! Please enter the text you want to translate in format like: 'text you want to translate' => target language. For an example: 您好! => English" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["generate:0"], - "upstream": ["begin", "generate:0"] - }, - "generate:0": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an professional interpreter.\n- Role: an professional interpreter.\n- Input format: content need to be translated => target language. \n- Answer format: => translated content in target language. \n- Examples:\n - user: 您好! => English. assistant: => How are you doing!\n - user: You look good today. => Japanese. assistant: => 今日は調子がいいですね 。\n", - "temperature": 0.5 - } - }, - "downstream": ["answer:0"], - "upstream": ["answer:0"] - } - }, - "history": [], - "messages": [], - "reference": {}, - "path": [], - "answer": [] -} \ No newline at end of file diff --git a/agent/test/dsl_examples/iteration.json b/agent/test/dsl_examples/iteration.json new file mode 100644 index 000000000..dd4448423 --- /dev/null +++ b/agent/test/dsl_examples/iteration.json @@ -0,0 +1,92 @@ +{ + "components": { + "begin": { + "obj":{ + "component_name": "Begin", + "params": { + "prologue": "Hi there!" + } + }, + "downstream": ["generate:0"], + "upstream": [] + }, + "generate:0": { + "obj": { + "component_name": "Agent", + "params": { + "llm_id": "deepseek-chat", + "sys_prompt": "You are an helpful research assistant. \nPlease decompose user's topic: '{sys.query}' into several meaningful sub-topics. \nThe output format MUST be an string array like: [\"sub-topic1\", \"sub-topic2\", ...]. Redundant information is forbidden.", + "temperature": 0.2, + "cite":false, + "output_structure": ["sub-topic1", "sub-topic2", "sub-topic3"] + } + }, + "downstream": ["iteration:0"], + "upstream": ["begin"] + }, + "iteration:0": { + "obj": { + "component_name": "Iteration", + "params": { + "items_ref": "generate:0@structured_content" + } + }, + "downstream": ["message:0"], + "upstream": ["generate:0"] + }, + "iterationitem:0": { + "obj": { + "component_name": "IterationItem", + "params": {} + }, + "parent_id": "iteration:0", + "downstream": ["tavily:0"], + "upstream": [] + }, + "tavily:0": { + "obj": { + "component_name": "TavilySearch", + "params": { + "api_key": "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", + "query": "iterationitem:0@result" + } + }, + "parent_id": "iteration:0", + "downstream": ["generate:1"], + "upstream": ["iterationitem:0"] + }, + "generate:1": { + "obj": { + "component_name": "Agent", + "params": { + "llm_id": "deepseek-chat", + "sys_prompt": "Your goal is to provide answers based on information from the internet. \nYou must use the provided search results to find relevant online information. \nYou should never use your own knowledge to answer questions.\nPlease include relevant url sources in the end of your answers.\n\n \"{tavily:0@formalized_content}\" \nUsing the above information, answer the following question or topic: \"{iterationitem:0@result} \"\nin a detailed report — The report should focus on the answer to the question, should be well structured, informative, in depth, with facts and numbers if available, a minimum of 200 words and with markdown syntax and apa format. Write all source urls at the end of the report in apa format. You should write your report only based on the given information and nothing else.", + "temperature": 0.9, + "cite":false + } + }, + "parent_id": "iteration:0", + "downstream": ["iterationitem:0"], + "upstream": ["tavily:0"] + }, + "message:0": { + "obj": { + "component_name": "Message", + "params": { + "content": ["{iteration:0@generate:1}"] + } + }, + "downstream": [], + "upstream": ["iteration:0"] + } + }, + "history": [], + "path": [], + "retrival": {"chunks": [], "doc_aggs": []}, + "globals": { + "sys.query": "", + "sys.user_id": "", + "sys.conversation_turns": 0, + "sys.files": [] + } +} \ No newline at end of file diff --git a/agent/test/dsl_examples/keyword_wikipedia_and_generate.json b/agent/test/dsl_examples/keyword_wikipedia_and_generate.json deleted file mode 100644 index fa1d62194..000000000 --- a/agent/test/dsl_examples/keyword_wikipedia_and_generate.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["keyword:0"], - "upstream": ["begin"] - }, - "keyword:0": { - "obj": { - "component_name": "KeywordExtract", - "params": { - "llm_id": "deepseek-chat", - "prompt": "- Role: You're a question analyzer.\n - Requirements:\n - Summarize user's question, and give top %s important keyword/phrase.\n - Use comma as a delimiter to separate keywords/phrases.\n - Answer format: (in language of user's question)\n - keyword: ", - "temperature": 0.2, - "top_n": 1 - } - }, - "downstream": ["wikipedia:0"], - "upstream": ["answer:0"] - }, - "wikipedia:0": { - "obj":{ - "component_name": "Wikipedia", - "params": { - "top_n": 10 - } - }, - "downstream": ["generate:0"], - "upstream": ["keyword:0"] - }, - "generate:1": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the question based on content from Wikipedia. When the answer from Wikipedia is incomplete, you need to output the URL link of the corresponding content as well. When all the content searched from Wikipedia is irrelevant to the question, your answer must include the sentence, \"The answer you are looking for is not found in the Wikipedia!\". Answers need to consider chat history.\n The content of Wikipedia is as follows:\n {input}\n The above is the content of Wikipedia.", - "temperature": 0.2 - } - }, - "downstream": ["answer:0"], - "upstream": ["wikipedia:0"] - } - }, - "history": [], - "path": [], - "messages": [], - "reference": {}, - "answer": [] -} diff --git a/agent/test/dsl_examples/retrieval_and_generate.json b/agent/test/dsl_examples/retrieval_and_generate.json index fbbf076aa..9f9f9bac4 100644 --- a/agent/test/dsl_examples/retrieval_and_generate.json +++ b/agent/test/dsl_examples/retrieval_and_generate.json @@ -7,16 +7,8 @@ "prologue": "Hi there!" } }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, "downstream": ["retrieval:0"], - "upstream": ["begin", "generate:0"] + "upstream": [] }, "retrieval:0": { "obj": { @@ -26,29 +18,44 @@ "keywords_similarity_weight": 0.3, "top_n": 6, "top_k": 1024, - "rerank_id": "BAAI/bge-reranker-v2-m3", - "kb_ids": ["869a236818b811ef91dffa163e197198"] + "rerank_id": "", + "empty_response": "Nothing found in dataset", + "kb_ids": ["1a3d1d7afb0611ef9866047c16ec874f"] } }, "downstream": ["generate:0"], - "upstream": ["answer:0"] + "upstream": ["begin"] }, "generate:0": { "obj": { - "component_name": "Generate", + "component_name": "LLM", "params": { "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\n Here is the knowledge base:\n {input}\n The above is the knowledge base.", + "sys_prompt": "You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\n Here is the knowledge base:\n {retrieval:0@formalized_content}\n The above is the knowledge base.", "temperature": 0.2 } }, - "downstream": ["answer:0"], + "downstream": ["message:0"], "upstream": ["retrieval:0"] + }, + "message:0": { + "obj": { + "component_name": "Message", + "params": { + "content": ["{generate:0@content}"] + } + }, + "downstream": [], + "upstream": ["generate:0"] } }, "history": [], - "messages": [], - "reference": {}, "path": [], - "answer": [] + "retrival": {"chunks": [], "doc_aggs": []}, + "globals": { + "sys.query": "", + "sys.user_id": "", + "sys.conversation_turns": 0, + "sys.files": [] + } } \ No newline at end of file diff --git a/agent/test/dsl_examples/retrieval_categorize_and_generate.json b/agent/test/dsl_examples/retrieval_categorize_and_generate.json index 4276b3330..c506b9a6b 100644 --- a/agent/test/dsl_examples/retrieval_categorize_and_generate.json +++ b/agent/test/dsl_examples/retrieval_categorize_and_generate.json @@ -7,16 +7,8 @@ "prologue": "Hi there!" } }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, "downstream": ["categorize:0"], - "upstream": ["begin", "generate:0", "switch:0"] + "upstream": [] }, "categorize:0": { "obj": { @@ -26,30 +18,30 @@ "category_description": { "product_related": { "description": "The question is about the product usage, appearance and how it works.", - "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?", - "to": "retrieval:0" + "examples": [], + "to": ["retrieval:0"] }, "others": { "description": "The question is not about the product usage, appearance and how it works.", - "examples": "How are you doing?\nWhat is your name?\nAre you a robot?\nWhat's the weather?\nWill it rain?", - "to": "message:0" + "examples": [], + "to": ["message:0"] } } } }, - "downstream": ["retrieval:0", "message:0"], - "upstream": ["answer:0"] + "downstream": [], + "upstream": ["begin"] }, "message:0": { "obj":{ "component_name": "Message", "params": { - "messages": [ + "content": [ "Sorry, I don't know. I'm an AI bot." ] } }, - "downstream": ["answer:0"], + "downstream": [], "upstream": ["categorize:0"] }, "retrieval:0": { @@ -60,29 +52,44 @@ "keywords_similarity_weight": 0.3, "top_n": 6, "top_k": 1024, - "rerank_id": "BAAI/bge-reranker-v2-m3", - "kb_ids": ["869a236818b811ef91dffa163e197198"] + "rerank_id": "", + "empty_response": "Nothing found in dataset", + "kb_ids": ["1a3d1d7afb0611ef9866047c16ec874f"] } }, "downstream": ["generate:0"], - "upstream": ["switch:0"] + "upstream": ["categorize:0"] }, "generate:0": { "obj": { - "component_name": "Generate", + "component_name": "Agent", "params": { "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\n Here is the knowledge base:\n {input}\n The above is the knowledge base.", + "sys_prompt": "You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\n Here is the knowledge base:\n {retrieval:0@formalized_content}\n The above is the knowledge base.", "temperature": 0.2 } }, - "downstream": ["answer:0"], + "downstream": ["message:1"], "upstream": ["retrieval:0"] + }, + "message:1": { + "obj": { + "component_name": "Message", + "params": { + "content": ["{generate:0@content}"] + } + }, + "downstream": [], + "upstream": ["generate:0"] } }, "history": [], - "messages": [], - "reference": {}, "path": [], - "answer": [] + "retrival": {"chunks": [], "doc_aggs": []}, + "globals": { + "sys.query": "", + "sys.user_id": "", + "sys.conversation_turns": 0, + "sys.files": [] + } } \ No newline at end of file diff --git a/agent/test/dsl_examples/retrieval_relevant_and_generate.json b/agent/test/dsl_examples/retrieval_relevant_and_generate.json deleted file mode 100644 index 8eeb3237d..000000000 --- a/agent/test/dsl_examples/retrieval_relevant_and_generate.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["retrieval:0"], - "upstream": ["begin", "generate:0", "switch:0"] - }, - "retrieval:0": { - "obj": { - "component_name": "Retrieval", - "params": { - "similarity_threshold": 0.2, - "keywords_similarity_weight": 0.3, - "top_n": 6, - "top_k": 1024, - "rerank_id": "BAAI/bge-reranker-v2-m3", - "kb_ids": ["869a236818b811ef91dffa163e197198"], - "empty_response": "Sorry, knowledge base has noting related information." - } - }, - "downstream": ["relevant:0"], - "upstream": ["answer:0"] - }, - "relevant:0": { - "obj": { - "component_name": "Relevant", - "params": { - "llm_id": "deepseek-chat", - "temperature": 0.02, - "yes": "generate:0", - "no": "message:0" - } - }, - "downstream": ["message:0", "generate:0"], - "upstream": ["retrieval:0"] - }, - "generate:0": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the question based on content of knowledge base. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\". Answers need to consider chat history.\n Knowledge base content is as following:\n {input}\n The above is the content of knowledge base.", - "temperature": 0.2 - } - }, - "downstream": ["answer:0"], - "upstream": ["relevant:0"] - }, - "message:0": { - "obj":{ - "component_name": "Message", - "params": { - "messages": [ - "Sorry, I don't know. Please leave your contact, our experts will contact you later. What's your e-mail/phone/wechat?", - "I'm an AI bot and not quite sure about this question. Please leave your contact, our experts will contact you later. What's your e-mail/phone/wechat?", - "Can't find answer in my knowledge base. Please leave your contact, our experts will contact you later. What's your e-mail/phone/wechat?" - ] - } - }, - "downstream": ["answer:0"], - "upstream": ["relevant:0"] - } - }, - "history": [], - "path": [], - "messages": [], - "reference": {}, - "answer": [] -} \ No newline at end of file diff --git a/agent/test/dsl_examples/retrieval_relevant_keyword_baidu_and_generate.json b/agent/test/dsl_examples/retrieval_relevant_keyword_baidu_and_generate.json deleted file mode 100644 index a34b58a36..000000000 --- a/agent/test/dsl_examples/retrieval_relevant_keyword_baidu_and_generate.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["retrieval:0"], - "upstream": ["begin"] - }, - "retrieval:0": { - "obj": { - "component_name": "Retrieval", - "params": { - "similarity_threshold": 0.2, - "keywords_similarity_weight": 0.3, - "top_n": 6, - "top_k": 1024, - "rerank_id": "BAAI/bge-reranker-v2-m3", - "kb_ids": ["21ca4e6a2c8911ef8b1e0242ac120006"], - "empty_response": "Sorry, knowledge base has noting related information." - } - }, - "downstream": ["relevant:0"], - "upstream": ["answer:0"] - }, - "relevant:0": { - "obj": { - "component_name": "Relevant", - "params": { - "llm_id": "deepseek-chat", - "temperature": 0.02, - "yes": "generate:0", - "no": "keyword:0" - } - }, - "downstream": ["keyword:0", "generate:0"], - "upstream": ["retrieval:0"] - }, - "generate:0": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the question based on content of knowledge base. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\". Answers need to consider chat history.\n Knowledge base content is as following:\n {input}\n The above is the content of knowledge base.", - "temperature": 0.2 - } - }, - "downstream": ["answer:0"], - "upstream": ["relevant:0"] - }, - "keyword:0": { - "obj": { - "component_name": "KeywordExtract", - "params": { - "llm_id": "deepseek-chat", - "prompt": "- Role: You're a question analyzer.\n - Requirements:\n - Summarize user's question, and give top %s important keyword/phrase.\n - Use comma as a delimiter to separate keywords/phrases.\n - Answer format: (in language of user's question)\n - keyword: ", - "temperature": 0.2, - "top_n": 1 - } - }, - "downstream": ["baidu:0"], - "upstream": ["relevant:0"] - }, - "baidu:0": { - "obj":{ - "component_name": "Baidu", - "params": { - "top_n": 10 - } - }, - "downstream": ["generate:1"], - "upstream": ["keyword:0"] - }, - "generate:1": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the question based on content searched from Baidu. When the answer from a Baidu search is incomplete, you need to output the URL link of the corresponding content as well. When all the content searched from Baidu is irrelevant to the question, your answer must include the sentence, \"The answer you are looking for is not found in the Baidu search!\". Answers need to consider chat history.\n The content of Baidu search is as follows:\n {input}\n The above is the content of Baidu search.", - "temperature": 0.2 - } - }, - "downstream": ["answer:0"], - "upstream": ["baidu:0"] - } - }, - "history": [], - "path": [], - "messages": [], - "reference": {}, - "answer": [] -} diff --git a/agent/test/dsl_examples/retrieval_relevant_rewrite_and_generate.json b/agent/test/dsl_examples/retrieval_relevant_rewrite_and_generate.json deleted file mode 100644 index fb290a2ec..000000000 --- a/agent/test/dsl_examples/retrieval_relevant_rewrite_and_generate.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "components": { - "begin": { - "obj":{ - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": ["answer:0"], - "upstream": [] - }, - "answer:0": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": ["retrieval:0"], - "upstream": ["begin", "generate:0", "switch:0"] - }, - "retrieval:0": { - "obj": { - "component_name": "Retrieval", - "params": { - "similarity_threshold": 0.2, - "keywords_similarity_weight": 0.3, - "top_n": 6, - "top_k": 1024, - "rerank_id": "BAAI/bge-reranker-v2-m3", - "kb_ids": ["869a236818b811ef91dffa163e197198"], - "empty_response": "Sorry, knowledge base has noting related information." - } - }, - "downstream": ["relevant:0"], - "upstream": ["answer:0", "rewrite:0"] - }, - "relevant:0": { - "obj": { - "component_name": "Relevant", - "params": { - "llm_id": "deepseek-chat", - "temperature": 0.02, - "yes": "generate:0", - "no": "rewrite:0" - } - }, - "downstream": ["generate:0", "rewrite:0"], - "upstream": ["retrieval:0"] - }, - "generate:0": { - "obj": { - "component_name": "Generate", - "params": { - "llm_id": "deepseek-chat", - "prompt": "You are an intelligent assistant. Please answer the question based on content of knowledge base. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\". Answers need to consider chat history.\n Knowledge base content is as following:\n {input}\n The above is the content of knowledge base.", - "temperature": 0.02 - } - }, - "downstream": ["answer:0"], - "upstream": ["relevant:0"] - }, - "rewrite:0": { - "obj":{ - "component_name": "RewriteQuestion", - "params": { - "llm_id": "deepseek-chat", - "temperature": 0.8 - } - }, - "downstream": ["retrieval:0"], - "upstream": ["relevant:0"] - } - }, - "history": [], - "messages": [], - "path": [], - "reference": [], - "answer": [] -} \ No newline at end of file diff --git a/agent/test/dsl_examples/tavily_and_generate.json b/agent/test/dsl_examples/tavily_and_generate.json new file mode 100644 index 000000000..f2f79b4b7 --- /dev/null +++ b/agent/test/dsl_examples/tavily_and_generate.json @@ -0,0 +1,55 @@ +{ + "components": { + "begin": { + "obj":{ + "component_name": "Begin", + "params": { + "prologue": "Hi there!" + } + }, + "downstream": ["tavily:0"], + "upstream": [] + }, + "tavily:0": { + "obj": { + "component_name": "TavilySearch", + "params": { + "api_key": "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" + } + }, + "downstream": ["generate:0"], + "upstream": ["begin"] + }, + "generate:0": { + "obj": { + "component_name": "LLM", + "params": { + "llm_id": "deepseek-chat", + "sys_prompt": "You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence \"The answer you are looking for is not found in the knowledge base!\" Answers need to consider chat history.\n Here is the knowledge base:\n {tavily:0@formalized_content}\n The above is the knowledge base.", + "temperature": 0.2 + } + }, + "downstream": ["message:0"], + "upstream": ["tavily:0"] + }, + "message:0": { + "obj": { + "component_name": "Message", + "params": { + "content": ["{generate:0@content}"] + } + }, + "downstream": [], + "upstream": ["generate:0"] + } + }, + "history": [], + "path": [], + "retrival": {"chunks": [], "doc_aggs": []}, + "globals": { + "sys.query": "", + "sys.user_id": "", + "sys.conversation_turns": 0, + "sys.files": [] + } +} \ No newline at end of file diff --git a/agent/tools/__init__.py b/agent/tools/__init__.py new file mode 100644 index 000000000..dcce4f448 --- /dev/null +++ b/agent/tools/__init__.py @@ -0,0 +1,33 @@ +import os +import importlib +import inspect +from types import ModuleType +from typing import Dict, Type + +_package_path = os.path.dirname(__file__) +__all_classes: Dict[str, Type] = {} + +def _import_submodules() -> None: + for filename in os.listdir(_package_path): # noqa: F821 + if filename.startswith("__") or not filename.endswith(".py") or filename.startswith("base"): + continue + module_name = filename[:-3] + + try: + module = importlib.import_module(f".{module_name}", package=__name__) + _extract_classes_from_module(module) # noqa: F821 + except ImportError as e: + print(f"Warning: Failed to import module {module_name}: {str(e)}") + +def _extract_classes_from_module(module: ModuleType) -> None: + for name, obj in inspect.getmembers(module): + if (inspect.isclass(obj) and + obj.__module__ == module.__name__ and not name.startswith("_")): + __all_classes[name] = obj + globals()[name] = obj + +_import_submodules() + +__all__ = list(__all_classes.keys()) + ["__all_classes"] + +del _package_path, _import_submodules, _extract_classes_from_module \ No newline at end of file diff --git a/agent/component/akshare.py b/agent/tools/akshare.py similarity index 100% rename from agent/component/akshare.py rename to agent/tools/akshare.py diff --git a/agent/tools/arxiv.py b/agent/tools/arxiv.py new file mode 100644 index 000000000..08a3d1c66 --- /dev/null +++ b/agent/tools/arxiv.py @@ -0,0 +1,96 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +import arxiv +from agent.tools.base import ToolParamBase, ToolMeta, ToolBase +from api.utils.api_utils import timeout + + +class ArXivParam(ToolParamBase): + """ + Define the ArXiv component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "arxiv_search", + "description": """arXiv is a free distribution service and an open-access archive for nearly 2.4 million scholarly articles in the fields of physics, mathematics, computer science, quantitative biology, quantitative finance, statistics, electrical engineering and systems science, and economics. Materials on this site are not peer-reviewed by arXiv.""", + "parameters": { + "query": { + "type": "string", + "description": "The search keywords to execute with arXiv. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.top_n = 12 + self.sort_by = 'submittedDate' + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + self.check_valid_value(self.sort_by, "ArXiv Search Sort_by", + ['submittedDate', 'lastUpdatedDate', 'relevance']) + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + + +class ArXiv(ToolBase, ABC): + component_name = "ArXiv" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + sort_choices = {"relevance": arxiv.SortCriterion.Relevance, + "lastUpdatedDate": arxiv.SortCriterion.LastUpdatedDate, + 'submittedDate': arxiv.SortCriterion.SubmittedDate} + arxiv_client = arxiv.Client() + search = arxiv.Search( + query=kwargs["query"], + max_results=self._param.top_n, + sort_by=sort_choices[self._param.sort_by] + ) + self._retrieve_chunks(list(arxiv_client.results(search)), + get_title=lambda r: r.title, + get_url=lambda r: r.pdf_url, + get_content=lambda r: r.summary) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"ArXiv error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"ArXiv error: {last_e}" + + assert False, self.output() diff --git a/agent/tools/base.py b/agent/tools/base.py new file mode 100644 index 000000000..5db9cf573 --- /dev/null +++ b/agent/tools/base.py @@ -0,0 +1,167 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import re +import time +from copy import deepcopy +from functools import partial +from typing import TypedDict, List, Any +from agent.component.base import ComponentParamBase, ComponentBase +from api.utils import hash_str2int +from rag.llm.chat_model import ToolCallSession +from rag.prompts.prompts import kb_prompt +from rag.utils.mcp_tool_call_conn import MCPToolCallSession + + +class ToolParameter(TypedDict): + type: str + description: str + displayDescription: str + enum: List[str] + required: bool + + +class ToolMeta(TypedDict): + name: str + displayName: str + description: str + displayDescription: str + parameters: dict[str, ToolParameter] + + +class LLMToolPluginCallSession(ToolCallSession): + def __init__(self, tools_map: dict[str, object], callback: partial): + self.tools_map = tools_map + self.callback = callback + + def tool_call(self, name: str, arguments: dict[str, Any]) -> Any: + assert name in self.tools_map, f"LLM tool {name} does not exist" + self.callback(name, arguments, " running ...") + if isinstance(self.tools_map[name], MCPToolCallSession): + resp = self.tools_map[name].tool_call(name, arguments, 60) + else: + resp = self.tools_map[name].invoke(**arguments) + return resp + + def get_tool_obj(self, name): + return self.tools_map[name] + + +class ToolParamBase(ComponentParamBase): + def __init__(self): + #self.meta:ToolMeta = None + super().__init__() + self._init_inputs() + self._init_attr_by_meta() + + def _init_inputs(self): + self.inputs = {} + for k,p in self.meta["parameters"].items(): + self.inputs[k] = deepcopy(p) + + def _init_attr_by_meta(self): + for k,p in self.meta["parameters"].items(): + if not hasattr(self, k): + setattr(self, k, p.get("default")) + + def get_meta(self): + params = {} + for k, p in self.meta["parameters"].items(): + params[k] = { + "type": p["type"], + "description": p["description"] + } + if "enum" in p: + params[k]["enum"] = p["enum"] + + desc = self.meta["description"] + if hasattr(self, "description"): + desc = self.description + + function_name = self.meta["name"] + if hasattr(self, "function_name"): + function_name = self.function_name + + return { + "type": "function", + "function": { + "name": function_name, + "description": desc, + "parameters": { + "type": "object", + "properties": params, + "required": [k for k, p in self.meta["parameters"].items() if p["required"]] + } + } + } + + +class ToolBase(ComponentBase): + def __init__(self, canvas, id, param: ComponentParamBase): + from agent.canvas import Canvas # Local import to avoid cyclic dependency + assert isinstance(canvas, Canvas), "canvas must be an instance of Canvas" + self._canvas = canvas + self._id = id + self._param = param + self._param.check() + + def get_meta(self) -> dict[str, Any]: + return self._param.get_meta() + + def invoke(self, **kwargs): + self.set_output("_created_time", time.perf_counter()) + try: + res = self._invoke(**kwargs) + except Exception as e: + self._param.outputs["_ERROR"] = {"value": str(e)} + logging.exception(e) + res = str(e) + self._param.debug_inputs = [] + + self.set_output("_elapsed_time", time.perf_counter() - self.output("_created_time")) + return res + + def _retrieve_chunks(self, res_list: list, get_title, get_url, get_content, get_score=None): + chunks = [] + aggs = [] + for r in res_list: + content = get_content(r) + if not content: + continue + content = re.sub(r"!?\[[a-z]+\]\(data:image/png;base64,[ 0-9A-Za-z/_=+-]+\)", "", content) + content = content[:10000] + if not content: + continue + id = str(hash_str2int(content)) + title = get_title(r) + url = get_url(r) + score = get_score(r) if get_score else 1 + chunks.append({ + "chunk_id": id, + "content": content, + "doc_id": id, + "docnm_kwd": title, + "similarity": score, + "url": url + }) + aggs.append({ + "doc_name": title, + "doc_id": id, + "count": 1, + "url": url + }) + self._canvas.add_refernce(chunks, aggs) + self.set_output("formalized_content", "\n".join(kb_prompt({"chunks": chunks, "doc_aggs": aggs}, 200000, True))) diff --git a/agent/tools/code_exec.py b/agent/tools/code_exec.py new file mode 100644 index 000000000..191ca320e --- /dev/null +++ b/agent/tools/code_exec.py @@ -0,0 +1,192 @@ +# +# Copyright 2025 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import base64 +import logging +import os +from abc import ABC +from enum import StrEnum +from typing import Optional +from pydantic import BaseModel, Field, field_validator +from agent.tools.base import ToolParamBase, ToolBase, ToolMeta +from api import settings +from api.utils.api_utils import timeout + + +class Language(StrEnum): + PYTHON = "python" + NODEJS = "nodejs" + + +class CodeExecutionRequest(BaseModel): + code_b64: str = Field(..., description="Base64 encoded code string") + language: str = Field(default=Language.PYTHON.value, description="Programming language") + arguments: Optional[dict] = Field(default={}, description="Arguments") + + @field_validator("code_b64") + @classmethod + def validate_base64(cls, v: str) -> str: + try: + base64.b64decode(v, validate=True) + return v + except Exception as e: + raise ValueError(f"Invalid base64 encoding: {str(e)}") + + @field_validator("language", mode="before") + @classmethod + def normalize_language(cls, v) -> str: + if isinstance(v, str): + low = v.lower() + if low in ("python", "python3"): + return "python" + elif low in ("javascript", "nodejs"): + return "nodejs" + raise ValueError(f"Unsupported language: {v}") + + +class CodeExecParam(ToolParamBase): + """ + Define the code sandbox component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "execute_code", + "description": """ +This tool has a sandbox that can execute code written in 'Python'/'Javascript'. It recieves a piece of code and return a Json string. +Here's a code example for Python(`main` function MUST be included): +def main(arg1: str, arg2: str) -> dict: + return { + "result": arg1 + arg2, + } + +Here's a code example for Javascript(`main` function MUST be included and exported): +const axios = require('axios'); +async function main(args) { + try { + const response = await axios.get('https://github.com/infiniflow/ragflow'); + console.log('Body:', response.data); + } catch (error) { + console.error('Error:', error.message); + } +} +module.exports = { main }; + """, + "parameters": { + "lang": { + "type": "string", + "description": "The programming language of this piece of code.", + "enum": ["python", "javascript"], + "required": True, + }, + "script": { + "type": "string", + "description": "A piece of code in right format. There MUST be main function.", + "required": True + } + } + } + super().__init__() + self.lang = Language.PYTHON.value + self.script = "def main(arg1: str, arg2: str) -> dict: return {\"result\": arg1 + arg2}" + self.arguments = {} + self.outputs = {"result": {"value": "", "type": "string"}} + + def check(self): + self.check_valid_value(self.lang, "Support languages", ["python", "python3", "nodejs", "javascript"]) + self.check_empty(self.script, "Script") + + def get_input_form(self) -> dict[str, dict]: + res = {} + for k, v in self.arguments.items(): + res[k] = { + "type": "line", + "name": k + } + return res + + +class CodeExec(ToolBase, ABC): + component_name = "CodeExec" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): + lang = kwargs.get("lang", self._param.lang) + script = kwargs.get("script", self._param.script) + arguments = {} + for k, v in self._param.arguments.items(): + if kwargs.get(k): + arguments[k] = kwargs[k] + continue + arguments[k] = self._canvas.get_variable_value(v) if v else None + + self._execute_code( + language=lang, + code=script, + arguments=arguments + ) + + def _execute_code(self, language: str, code: str, arguments: dict): + import requests + + try: + code_b64 = self._encode_code(code) + code_req = CodeExecutionRequest(code_b64=code_b64, language=language, arguments=arguments).model_dump() + except Exception as e: + self.set_output("_ERROR", "construct code request error: " + str(e)) + + try: + resp = requests.post(url=f"http://{settings.SANDBOX_HOST}:9385/run", json=code_req, timeout=10) + logging.info(f"http://{settings.SANDBOX_HOST}:9385/run", code_req, resp.status_code) + if resp.status_code != 200: + resp.raise_for_status() + body = resp.json() + if body: + stderr = body.get("stderr") + if stderr: + self.set_output("_ERROR", stderr) + return + try: + rt = eval(body.get("stdout", "")) + except Exception: + rt = body.get("stdout", "") + logging.info(f"http://{settings.SANDBOX_HOST}:9385/run -> {rt}") + if isinstance(rt, tuple): + for i, (k, o) in enumerate(self._param.outputs.items()): + if k.find("_") == 0: + continue + o["value"] = rt[i] + elif isinstance(rt, dict): + for i, (k, o) in enumerate(self._param.outputs.items()): + if k not in rt or k.find("_") == 0: + continue + o["value"] = rt[k] + else: + for i, (k, o) in enumerate(self._param.outputs.items()): + if k.find("_") == 0: + continue + o["value"] = rt + else: + self.set_output("_ERROR", "There is no response from sandbox") + + except Exception as e: + self.set_output("_ERROR", "Exception executing code: " + str(e)) + + return self.output() + + def _encode_code(self, code: str) -> str: + return base64.b64encode(code.encode("utf-8")).decode("utf-8") + + diff --git a/agent/component/crawler.py b/agent/tools/crawler.py similarity index 93% rename from agent/component/crawler.py rename to agent/tools/crawler.py index d8c5381b1..b4c4f6717 100644 --- a/agent/component/crawler.py +++ b/agent/tools/crawler.py @@ -16,11 +16,12 @@ from abc import ABC import asyncio from crawl4ai import AsyncWebCrawler -from agent.component.base import ComponentBase, ComponentParamBase + +from agent.tools.base import ToolParamBase, ToolBase from api.utils.web_utils import is_valid_url -class CrawlerParam(ComponentParamBase): +class CrawlerParam(ToolParamBase): """ Define the Crawler component parameters. """ @@ -34,7 +35,7 @@ class CrawlerParam(ComponentParamBase): self.check_valid_value(self.extract_type, "Type of content from the crawler", ['html', 'markdown', 'content']) -class Crawler(ComponentBase, ABC): +class Crawler(ToolBase, ABC): component_name = "Crawler" def _run(self, history, **kwargs): diff --git a/agent/component/deepl.py b/agent/tools/deepl.py similarity index 100% rename from agent/component/deepl.py rename to agent/tools/deepl.py diff --git a/agent/tools/duckduckgo.py b/agent/tools/duckduckgo.py new file mode 100644 index 000000000..da903c069 --- /dev/null +++ b/agent/tools/duckduckgo.py @@ -0,0 +1,114 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +from duckduckgo_search import DDGS +from agent.tools.base import ToolMeta, ToolParamBase, ToolBase +from api.utils.api_utils import timeout + + +class DuckDuckGoParam(ToolParamBase): + """ + Define the DuckDuckGo component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "duckduckgo_search", + "description": "DuckDuckGo is a search engine focused on privacy. It offers search capabilities for web pages, images, and provides translation services. DuckDuckGo also features a private AI chat interface, providing users with an AI assistant that prioritizes data protection.", + "parameters": { + "query": { + "type": "string", + "description": "The search keywords to execute with DuckDuckGo. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + }, + "channel": { + "type": "string", + "description": "default:general. The category of the search. `news` is useful for retrieving real-time updates, particularly about politics, sports, and major current events covered by mainstream media sources. `general` is for broader, more general-purpose searches that may include a wide range of sources.", + "enum": ["general", "news"], + "default": "general", + "required": False, + }, + } + } + super().__init__() + self.top_n = 10 + self.channel = "text" + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + self.check_valid_value(self.channel, "Web Search or News", ["text", "news"]) + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + }, + "channel": { + "name": "Channel", + "type": "options", + "value": "general", + "options": ["general", "news"] + } + } + + +class DuckDuckGo(ToolBase, ABC): + component_name = "DuckDuckGo" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + if kwargs.get("topic", "general") == "general": + with DDGS() as ddgs: + # {'title': '', 'href': '', 'body': ''} + duck_res = ddgs.text(kwargs["query"], max_results=self._param.top_n) + self._retrieve_chunks(duck_res, + get_title=lambda r: r["title"], + get_url=lambda r: r.get("href", r.get("url")), + get_content=lambda r: r["body"]) + self.set_output("json", duck_res) + return self.output("formalized_content") + else: + with DDGS() as ddgs: + # {'date': '', 'title': '', 'body': '', 'url': '', 'image': '', 'source': ''} + duck_res = ddgs.news(kwargs["query"], max_results=self._param.top_n) + self._retrieve_chunks(duck_res, + get_title=lambda r: r["title"], + get_url=lambda r: r.get("href", r.get("url")), + get_content=lambda r: r["body"]) + self.set_output("json", duck_res) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"DuckDuckGo error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"DuckDuckGo error: {last_e}" + + assert False, self.output() diff --git a/agent/tools/email.py b/agent/tools/email.py new file mode 100644 index 000000000..89a3113c3 --- /dev/null +++ b/agent/tools/email.py @@ -0,0 +1,207 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import time +from abc import ABC +import json +import smtplib +import logging +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.header import Header +from email.utils import formataddr + +from agent.tools.base import ToolParamBase, ToolBase, ToolMeta +from api.utils.api_utils import timeout + + +class EmailParam(ToolParamBase): + """ + Define the Email component parameters. + """ + def __init__(self): + self.meta:ToolMeta = { + "name": "email", + "description": "The email is a method of electronic communication for sending and receiving information through the Internet. This tool helps users to send emails to one person or to multiple recipients with support for CC, BCC, file attachments, and markdown-to-HTML conversion.", + "parameters": { + "to_email": { + "type": "string", + "description": "The target email address.", + "default": "{sys.query}", + "required": True + }, + "cc_email": { + "type": "string", + "description": "The other email addresses needs to be send to. Comma splited.", + "default": "", + "required": False + }, + "content": { + "type": "string", + "description": "The content of the email.", + "default": "", + "required": False + }, + "subject": { + "type": "string", + "description": "The subject/title of the email.", + "default": "", + "required": False + } + } + } + super().__init__() + # Fixed configuration parameters + self.smtp_server = "" # SMTP server address + self.smtp_port = 465 # SMTP port + self.email = "" # Sender email + self.password = "" # Email authorization code + self.sender_name = "" # Sender name + + def check(self): + # Check required parameters + self.check_empty(self.smtp_server, "SMTP Server") + self.check_empty(self.email, "Email") + self.check_empty(self.password, "Password") + self.check_empty(self.sender_name, "Sender Name") + + def get_input_form(self) -> dict[str, dict]: + return { + "to_email": { + "name": "To ", + "type": "line" + }, + "subject": { + "name": "Subject", + "type": "line", + "optional": True + }, + "cc_email": { + "name": "CC To", + "type": "line", + "optional": True + }, + } + +class Email(ToolBase, ABC): + component_name = "Email" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 60)) + def _invoke(self, **kwargs): + if not kwargs.get("to_email"): + self.set_output("success", False) + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + # Parse JSON string passed from upstream + email_data = kwargs + + # Validate required fields + if "to_email" not in email_data: + return Email.be_output("Missing required field: to_email") + + # Create email object + msg = MIMEMultipart('alternative') + + # Properly handle sender name encoding + msg['From'] = formataddr((str(Header(self._param.sender_name,'utf-8')), self._param.email)) + msg['To'] = email_data["to_email"] + if email_data.get("cc_email"): + msg['Cc'] = email_data["cc_email"] + msg['Subject'] = Header(email_data.get("subject", "No Subject"), 'utf-8').encode() + + # Use content from email_data or default content + email_content = email_data.get("content", "No content provided") + # msg.attach(MIMEText(email_content, 'plain', 'utf-8')) + msg.attach(MIMEText(email_content, 'html', 'utf-8')) + + # Connect to SMTP server and send + logging.info(f"Connecting to SMTP server {self._param.smtp_server}:{self._param.smtp_port}") + + context = smtplib.ssl.create_default_context() + with smtplib.SMTP(self._param.smtp_server, self._param.smtp_port) as server: + server.ehlo() + server.starttls(context=context) + server.ehlo() + # Login + logging.info(f"Attempting to login with email: {self._param.email}") + server.login(self._param.email, self._param.password) + + # Get all recipient list + recipients = [email_data["to_email"]] + if email_data.get("cc_email"): + recipients.extend(email_data["cc_email"].split(',')) + + # Send email + logging.info(f"Sending email to recipients: {recipients}") + try: + server.send_message(msg, self._param.email, recipients) + success = True + except Exception as e: + logging.error(f"Error during send_message: {str(e)}") + # Try alternative method + server.sendmail(self._param.email, recipients, msg.as_string()) + success = True + + try: + server.quit() + except Exception as e: + # Ignore errors when closing connection + logging.warning(f"Non-fatal error during connection close: {str(e)}") + + self.set_output("success", success) + return success + + except json.JSONDecodeError: + error_msg = "Invalid JSON format in input" + logging.error(error_msg) + self.set_output("_ERROR", error_msg) + self.set_output("success", False) + return False + + except smtplib.SMTPAuthenticationError: + error_msg = "SMTP Authentication failed. Please check your email and authorization code." + logging.error(error_msg) + self.set_output("_ERROR", error_msg) + self.set_output("success", False) + return False + + except smtplib.SMTPConnectError: + error_msg = f"Failed to connect to SMTP server {self._param.smtp_server}:{self._param.smtp_port}" + logging.error(error_msg) + last_e = error_msg + time.sleep(self._param.delay_after_error) + + except smtplib.SMTPException as e: + error_msg = f"SMTP error occurred: {str(e)}" + logging.error(error_msg) + last_e = error_msg + time.sleep(self._param.delay_after_error) + + except Exception as e: + error_msg = f"Unexpected error: {str(e)}" + logging.error(error_msg) + self.set_output("_ERROR", error_msg) + self.set_output("success", False) + return False + + if last_e: + self.set_output("_ERROR", str(last_e)) + return False + + assert False, self.output() \ No newline at end of file diff --git a/agent/tools/exesql.py b/agent/tools/exesql.py new file mode 100644 index 000000000..087abcc1d --- /dev/null +++ b/agent/tools/exesql.py @@ -0,0 +1,133 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +from abc import ABC +import pandas as pd +import pymysql +import psycopg2 +import pyodbc +from agent.tools.base import ToolParamBase, ToolBase, ToolMeta +from api.utils.api_utils import timeout + + +class ExeSQLParam(ToolParamBase): + """ + Define the ExeSQL component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "execute_sql", + "description": "This is a tool that can execute SQL.", + "parameters": { + "sql": { + "type": "string", + "description": "The SQL needs to be executed.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.db_type = "mysql" + self.database = "" + self.username = "" + self.host = "" + self.port = 3306 + self.password = "" + self.max_records = 1024 + + def check(self): + self.check_valid_value(self.db_type, "Choose DB type", ['mysql', 'postgresql', 'mariadb', 'mssql']) + self.check_empty(self.database, "Database name") + self.check_empty(self.username, "database username") + self.check_empty(self.host, "IP Address") + self.check_positive_integer(self.port, "IP Port") + self.check_empty(self.password, "Database password") + self.check_positive_integer(self.max_records, "Maximum number of records") + if self.database == "rag_flow": + if self.host == "ragflow-mysql": + raise ValueError("For the security reason, it dose not support database named rag_flow.") + if self.password == "infini_rag_flow": + raise ValueError("For the security reason, it dose not support database named rag_flow.") + + def get_input_form(self) -> dict[str, dict]: + return { + "sql": { + "name": "SQL", + "type": "line" + } + } + + +class ExeSQL(ToolBase, ABC): + component_name = "ExeSQL" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 60)) + def _invoke(self, **kwargs): + sql = kwargs.get("sql") + if not sql: + raise Exception("SQL for `ExeSQL` MUST not be empty.") + sqls = sql.split(";") + + if self._param.db_type in ["mysql", "mariadb"]: + db = pymysql.connect(db=self._param.database, user=self._param.username, host=self._param.host, + port=self._param.port, password=self._param.password) + elif self._param.db_type == 'postgresql': + db = psycopg2.connect(dbname=self._param.database, user=self._param.username, host=self._param.host, + port=self._param.port, password=self._param.password) + elif self._param.db_type == 'mssql': + conn_str = ( + r'DRIVER={ODBC Driver 17 for SQL Server};' + r'SERVER=' + self._param.host + ',' + str(self._param.port) + ';' + r'DATABASE=' + self._param.database + ';' + r'UID=' + self._param.username + ';' + r'PWD=' + self._param.password + ) + db = pyodbc.connect(conn_str) + try: + cursor = db.cursor() + except Exception as e: + raise Exception("Database Connection Failed! \n" + str(e)) + + sql_res = [] + formalized_content = [] + for single_sql in sqls: + single_sql = single_sql.replace('```','') + if not single_sql: + continue + + cursor.execute(single_sql) + if cursor.rowcount == 0: + sql_res.append({"content": "No record in the database!"}) + break + if self._param.db_type == 'mssql': + single_res = pd.DataFrame.from_records(cursor.fetchmany(self._param.max_records), + columns=[desc[0] for desc in cursor.description]) + else: + single_res = pd.DataFrame([i for i in cursor.fetchmany(self._param.max_records)]) + single_res.columns = [i[0] for i in cursor.description] + + sql_res.append(single_res.to_dict(orient='records')) + formalized_content.append(single_res.to_markdown(index=False, floatfmt=".6f")) + + self.set_output("json", sql_res) + self.set_output("formalized_content", "\n\n".join(formalized_content)) + return self.output("formalized_content") + + + def debug(self, **kwargs): + return self._run([], **kwargs) diff --git a/agent/tools/github.py b/agent/tools/github.py new file mode 100644 index 000000000..385b88b02 --- /dev/null +++ b/agent/tools/github.py @@ -0,0 +1,88 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +import requests +from agent.tools.base import ToolParamBase, ToolMeta, ToolBase +from api.utils.api_utils import timeout + + +class GitHubParam(ToolParamBase): + """ + Define the GitHub component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "github_search", + "description": """GitHub repository search is a feature that enables users to find specific repositories on the GitHub platform. This search functionality allows users to locate projects, codebases, and other content hosted on GitHub based on various criteria.""", + "parameters": { + "query": { + "type": "string", + "description": "The search keywords to execute with GitHub. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.top_n = 10 + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class GitHub(ToolBase, ABC): + component_name = "GitHub" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + url = 'https://api.github.com/search/repositories?q=' + kwargs["query"] + '&sort=stars&order=desc&per_page=' + str( + self._param.top_n) + headers = {"Content-Type": "application/vnd.github+json", "X-GitHub-Api-Version": '2022-11-28'} + response = requests.get(url=url, headers=headers).json() + self._retrieve_chunks(response['items'], + get_title=lambda r: r["name"], + get_url=lambda r: r["html_url"], + get_content=lambda r: str(r["description"]) + '\n stars:' + str(r['watchers'])) + self.set_output("json", response['items']) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"GitHub error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"GitHub error: {last_e}" + + assert False, self.output() diff --git a/agent/component/google.py b/agent/tools/google.py similarity index 53% rename from agent/component/google.py rename to agent/tools/google.py index 691dc2397..1d1bd86f7 100644 --- a/agent/component/google.py +++ b/agent/tools/google.py @@ -14,26 +14,52 @@ # limitations under the License. # import logging +import os +import time from abc import ABC from serpapi import GoogleSearch -import pandas as pd -from agent.component.base import ComponentBase, ComponentParamBase +from agent.tools.base import ToolParamBase, ToolMeta, ToolBase +from api.utils.api_utils import timeout -class GoogleParam(ComponentParamBase): +class GoogleParam(ToolParamBase): """ Define the Google component parameters. """ def __init__(self): + self.meta:ToolMeta = { + "name": "google_search", + "description": """Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking ...""", + "parameters": { + "q": { + "type": "string", + "description": "The search keywords to execute with Google. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + }, + "start": { + "type": "integer", + "description": "Parameter defines the result offset. It skips the given number of results. It's used for pagination. (e.g., 0 (default) is the first page of results, 10 is the 2nd page of results, 20 is the 3rd page of results, etc.). Google Local Results only accepts multiples of 20(e.g. 20 for the second page results, 40 for the third page results, etc.) as the `start` value.", + "default": "0", + "required": False, + }, + "num": { + "type": "integer", + "description": "Parameter defines the maximum number of results to return. (e.g., 10 (default) returns 10 results, 40 returns 40 results, and 100 returns 100 results). The use of num may introduce latency, and/or prevent the inclusion of specialized result types. It is better to omit this parameter unless it is strictly necessary to increase the number of results per page. Results are not guaranteed to have the number of results specified in num.", + "default": "6", + "required": False, + } + } + } super().__init__() - self.top_n = 10 - self.api_key = "xxx" + self.start = 0 + self.num = 6 + self.api_key = "" self.country = "cn" self.language = "en" def check(self): - self.check_positive_integer(self.top_n, "Top N") self.check_empty(self.api_key, "SerpApi API key") self.check_valid_value(self.country, "Google Country", ['af', 'al', 'dz', 'as', 'ad', 'ao', 'ai', 'aq', 'ag', 'ar', 'am', 'aw', 'au', 'at', @@ -69,28 +95,60 @@ class GoogleParam(ComponentParamBase): 'ug', 'uk', 'ur', 'uz', 'vu', 'vi', 'cy', 'wo', 'xh', 'yi', 'yo', 'zu'] ) + def get_input_form(self) -> dict[str, dict]: + return { + "q": { + "name": "Query", + "type": "line" + }, + "start": { + "name": "From", + "type": "integer", + "value": 0 + }, + "num": { + "name": "Limit", + "type": "integer", + "value": 12 + } + } -class Google(ComponentBase, ABC): +class Google(ToolBase, ABC): component_name = "Google" - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return Google.be_output("") + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("q"): + self.set_output("formalized_content", "") + return "" - try: - client = GoogleSearch( - {"engine": "google", "q": ans, "api_key": self._param.api_key, "gl": self._param.country, - "hl": self._param.language, "num": self._param.top_n}) - google_res = [{"content": '' + i["title"] + ' ' + i["snippet"]} for i in - client.get_dict()["organic_results"]] - except Exception: - return Google.be_output("**ERROR**: Existing Unavailable Parameters!") + params = { + "api_key": self._param.api_key, + "engine": "google", + "q": kwargs["q"], + "google_domain": "google.com", + "gl": self._param.country, + "hl": self._param.language + } + last_e = "" + for _ in range(self._param.max_retries+1): + try: + search = GoogleSearch(params).get_dict() + self._retrieve_chunks(search["organic_results"], + get_title=lambda r: r["title"], + get_url=lambda r: r["link"], + get_content=lambda r: r.get("about_this_result", {}).get("source", {}).get("description", r["snippet"]) + ) + self.set_output("json", search["organic_results"]) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"Google error: {e}") + time.sleep(self._param.delay_after_error) - if not google_res: - return Google.be_output("") + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"Google error: {last_e}" + + assert False, self.output() - df = pd.DataFrame(google_res) - logging.debug(f"df: {df}") - return df diff --git a/agent/tools/googlescholar.py b/agent/tools/googlescholar.py new file mode 100644 index 000000000..d26a68a9c --- /dev/null +++ b/agent/tools/googlescholar.py @@ -0,0 +1,93 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +from scholarly import scholarly +from agent.tools.base import ToolMeta, ToolParamBase, ToolBase +from api.utils.api_utils import timeout + + +class GoogleScholarParam(ToolParamBase): + """ + Define the GoogleScholar component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "google_scholar_search", + "description": """Google Scholar provides a simple way to broadly search for scholarly literature. From one place, you can search across many disciplines and sources: articles, theses, books, abstracts and court opinions, from academic publishers, professional societies, online repositories, universities and other web sites. Google Scholar helps you find relevant work across the world of scholarly research.""", + "parameters": { + "query": { + "type": "string", + "description": "The search keyword to execute with Google Scholar. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.top_n = 12 + self.sort_by = 'relevance' + self.year_low = None + self.year_high = None + self.patents = True + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + self.check_valid_value(self.sort_by, "GoogleScholar Sort_by", ['date', 'relevance']) + self.check_boolean(self.patents, "Whether or not to include patents, defaults to True") + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class GoogleScholar(ToolBase, ABC): + component_name = "GoogleScholar" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + scholar_client = scholarly.search_pubs(kwargs["query"], patents=self._param.patents, year_low=self._param.year_low, + year_high=self._param.year_high, sort_by=self._param.sort_by) + self._retrieve_chunks(scholar_client, + get_title=lambda r: r['bib']['title'], + get_url=lambda r: r["pub_url"], + get_content=lambda r: "\n author: " + ",".join(r['bib']['author']) + '\n Abstract: ' + r['bib'].get('abstract', 'no abstract') + ) + self.set_output("json", list(scholar_client)) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"GoogleScholar error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"GoogleScholar error: {last_e}" + + assert False, self.output() diff --git a/agent/component/jin10.py b/agent/tools/jin10.py similarity index 100% rename from agent/component/jin10.py rename to agent/tools/jin10.py diff --git a/agent/tools/pubmed.py b/agent/tools/pubmed.py new file mode 100644 index 000000000..8af7c1435 --- /dev/null +++ b/agent/tools/pubmed.py @@ -0,0 +1,105 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +from Bio import Entrez +import re +import xml.etree.ElementTree as ET +from agent.tools.base import ToolParamBase, ToolMeta, ToolBase +from api.utils.api_utils import timeout + + +class PubMedParam(ToolParamBase): + """ + Define the PubMed component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "pubmed_search", + "description": """ +PubMed is an openly accessible, free database which includes primarily the MEDLINE database of references and abstracts on life sciences and biomedical topics. +In addition to MEDLINE, PubMed provides access to: + - older references from the print version of Index Medicus, back to 1951 and earlier + - references to some journals before they were indexed in Index Medicus and MEDLINE, for instance Science, BMJ, and Annals of Surgery + - very recent entries to records for an article before it is indexed with Medical Subject Headings (MeSH) and added to MEDLINE + - a collection of books available full-text and other subsets of NLM records[4] + - PMC citations + - NCBI Bookshelf + """, + "parameters": { + "query": { + "type": "string", + "description": "The search keywords to execute with PubMed. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.top_n = 12 + self.email = "A.N.Other@example.com" + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class PubMed(ToolBase, ABC): + component_name = "PubMed" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + Entrez.email = self._param.email + pubmedids = Entrez.read(Entrez.esearch(db='pubmed', retmax=self._param.top_n, term=kwargs["query"]))['IdList'] + pubmedcnt = ET.fromstring(re.sub(r'<(/?)b>|<(/?)i>', '', Entrez.efetch(db='pubmed', id=",".join(pubmedids), + retmode="xml").read().decode("utf-8"))) + self._retrieve_chunks(pubmedcnt.findall("PubmedArticle"), + get_title=lambda child: child.find("MedlineCitation").find("Article").find("ArticleTitle").text, + get_url=lambda child: "https://pubmed.ncbi.nlm.nih.gov/" + child.find("MedlineCitation").find("PMID").text, + get_content=lambda child: child.find("MedlineCitation") \ + .find("Article") \ + .find("Abstract") \ + .find("AbstractText").text \ + if child.find("MedlineCitation")\ + .find("Article").find("Abstract") \ + else "No abstract available") + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"PubMed error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"PubMed error: {last_e}" + + assert False, self.output() diff --git a/agent/component/qweather.py b/agent/tools/qweather.py similarity index 100% rename from agent/component/qweather.py rename to agent/tools/qweather.py diff --git a/agent/tools/retrieval.py b/agent/tools/retrieval.py new file mode 100644 index 000000000..d25061f60 --- /dev/null +++ b/agent/tools/retrieval.py @@ -0,0 +1,161 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +import re +from abc import ABC +from agent.tools.base import ToolParamBase, ToolBase, ToolMeta +from api.db import LLMType +from api.db.services.knowledgebase_service import KnowledgebaseService +from api.db.services.llm_service import LLMBundle +from api import settings +from api.utils.api_utils import timeout +from rag.app.tag import label_question +from rag.prompts import kb_prompt +from rag.prompts.prompts import cross_languages + + +class RetrievalParam(ToolParamBase): + """ + Define the Retrieval component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "search_my_dateset", + "description": "This tool can be utilized for relevant content searching in the datasets.", + "parameters": { + "query": { + "type": "string", + "description": "The keywords to search the dataset. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "", + "required": True + } + } + } + super().__init__() + self.function_name = "search_my_dateset" + self.description = "This tool can be utilized for relevant content searching in the datasets." + self.similarity_threshold = 0.2 + self.keywords_similarity_weight = 0.5 + self.top_n = 8 + self.top_k = 1024 + self.kb_ids = [] + self.kb_vars = [] + self.rerank_id = "" + self.empty_response = "" + self.use_kg = False + self.cross_languages = [] + + def check(self): + self.check_decimal_float(self.similarity_threshold, "[Retrieval] Similarity threshold") + self.check_decimal_float(self.keywords_similarity_weight, "[Retrieval] Keyword similarity weight") + self.check_positive_number(self.top_n, "[Retrieval] Top N") + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class Retrieval(ToolBase, ABC): + component_name = "Retrieval" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", self._param.empty_response) + + kb_ids: list[str] = [] + for id in self._param.kb_ids: + if id.find("@") < 0: + kb_ids.append(id) + continue + kb_nm = self._canvas.get_variable_value(id) + e, kb = KnowledgebaseService.get_by_name(kb_nm) + if not e: + raise Exception(f"Dataset({kb_nm}) does not exist.") + kb_ids.append(kb.id) + + filtered_kb_ids: list[str] = list(set([kb_id for kb_id in kb_ids if kb_id])) + + kbs = KnowledgebaseService.get_by_ids(filtered_kb_ids) + if not kbs: + raise Exception("No dataset is selected.") + + embd_nms = list(set([kb.embd_id for kb in kbs])) + assert len(embd_nms) == 1, "Knowledge bases use different embedding models." + + embd_mdl = None + if embd_nms: + embd_mdl = LLMBundle(self._canvas.get_tenant_id(), LLMType.EMBEDDING, embd_nms[0]) + + rerank_mdl = None + if self._param.rerank_id: + rerank_mdl = LLMBundle(kbs[0].tenant_id, LLMType.RERANK, self._param.rerank_id) + + query = kwargs["query"] + if self._param.cross_languages: + query = cross_languages(kbs[0].tenant_id, None, query, self._param.cross_languages) + + if kbs: + query = re.sub(r"^user[::\s]*", "", query, flags=re.IGNORECASE) + kbinfos = settings.retrievaler.retrieval( + query, + embd_mdl, + [kb.tenant_id for kb in kbs], + filtered_kb_ids, + 1, + self._param.top_n, + self._param.similarity_threshold, + 1 - self._param.keywords_similarity_weight, + aggs=False, + rerank_mdl=rerank_mdl, + rank_feature=label_question(query, kbs), + ) + if self._param.use_kg: + ck = settings.kg_retrievaler.retrieval(query, + [kb.tenant_id for kb in kbs], + kb_ids, + embd_mdl, + LLMBundle(self._canvas.get_tenant_id(), LLMType.CHAT)) + if ck["content_with_weight"]: + kbinfos["chunks"].insert(0, ck) + else: + kbinfos = {"chunks": [], "doc_aggs": []} + + if self._param.use_kg and kbs: + ck = settings.kg_retrievaler.retrieval(query, [kb.tenant_id for kb in kbs], filtered_kb_ids, embd_mdl, LLMBundle(kbs[0].tenant_id, LLMType.CHAT)) + if ck["content_with_weight"]: + ck["content"] = ck["content_with_weight"] + del ck["content_with_weight"] + kbinfos["chunks"].insert(0, ck) + + for ck in kbinfos["chunks"]: + if "vector" in ck: + del ck["vector"] + if "content_ltks" in ck: + del ck["content_ltks"] + + if not kbinfos["chunks"]: + self.set_output("formalized_content", self._param.empty_response) + return + + self._canvas.add_refernce(kbinfos["chunks"], kbinfos["doc_aggs"]) + form_cnt = "\n".join(kb_prompt(kbinfos, 200000, True)) + self.set_output("formalized_content", form_cnt) + return form_cnt diff --git a/agent/tools/tavily.py b/agent/tools/tavily.py new file mode 100644 index 000000000..8072d3eb3 --- /dev/null +++ b/agent/tools/tavily.py @@ -0,0 +1,218 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +from tavily import TavilyClient +from agent.tools.base import ToolParamBase, ToolBase, ToolMeta +from api.utils.api_utils import timeout + + +class TavilySearchParam(ToolParamBase): + """ + Define the Retrieval component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "tavily_search", + "description": """ +Tavily is a search engine optimized for LLMs, aimed at efficient, quick and persistent search results. +When searching: + - Start with specific query which should focus on just a single aspect. + - Number of keywords in query should be less than 5. + - Broaden search terms if needed + - Cross-reference information from multiple sources + """, + "parameters": { + "query": { + "type": "string", + "description": "The search keywords to execute with Tavily. The keywords should be the most important words/terms(includes synonyms) from the original request.", + "default": "{sys.query}", + "required": True + }, + "topic": { + "type": "string", + "description": "default:general. The category of the search.news is useful for retrieving real-time updates, particularly about politics, sports, and major current events covered by mainstream media sources. general is for broader, more general-purpose searches that may include a wide range of sources.", + "enum": ["general", "news"], + "default": "general", + "required": False, + }, + "include_domains": { + "type": "array", + "description": "default:[]. A list of domains only from which the search results can be included.", + "default": [], + "items": { + "type": "string", + "description": "Domain name that must be included, e.g. www.yahoo.com" + }, + "required": False + }, + "exclude_domains": { + "type": "array", + "description": "default:[]. A list of domains from which the search results can not be included", + "default": [], + "items": { + "type": "string", + "description": "Domain name that must be excluded, e.g. www.yahoo.com" + }, + "required": False + }, + } + } + super().__init__() + self.api_key = "" + self.search_depth = "basic" # basic/advanced + self.max_results = 6 + self.days = 14 + self.include_answer = False + self.include_raw_content = False + self.include_images = False + self.include_image_descriptions = False + + def check(self): + self.check_valid_value(self.topic, "Tavily topic: should be in 'general/news'", ["general", "news"]) + self.check_valid_value(self.search_depth, "Tavily search depth should be in 'basic/advanced'", ["basic", "advanced"]) + self.check_positive_integer(self.max_results, "Tavily max result number should be within [1, 20]") + self.check_positive_integer(self.days, "Tavily days should be greater than 1") + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class TavilySearch(ToolBase, ABC): + component_name = "TavilySearch" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + self.tavily_client = TavilyClient(api_key=self._param.api_key) + last_e = None + for fld in ["search_depth", "topic", "max_results", "days", "include_answer", "include_raw_content", "include_images", "include_image_descriptions", "include_domains", "exclude_domains"]: + if fld not in kwargs: + kwargs[fld] = getattr(self._param, fld) + for _ in range(self._param.max_retries+1): + try: + kwargs["include_images"] = False + kwargs["include_raw_content"] = False + res = self.tavily_client.search(**kwargs) + self._retrieve_chunks(res["results"], + get_title=lambda r: r["title"], + get_url=lambda r: r["url"], + get_content=lambda r: r["raw_content"] if r["raw_content"] else r["content"], + get_score=lambda r: r["score"]) + self.set_output("json", res["results"]) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"Tavily error: {e}") + time.sleep(self._param.delay_after_error) + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"Tavily error: {last_e}" + + assert False, self.output() + + +class TavilyExtractParam(ToolParamBase): + """ + Define the Retrieval component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "tavily_extract", + "description": "Extract web page content from one or more specified URLs using Tavily Extract.", + "parameters": { + "urls": { + "type": "array", + "description": "The URLs to extract content from.", + "default": "", + "items": { + "type": "string", + "description": "The URL to extract content from, e.g. www.yahoo.com" + }, + "required": True + }, + "extract_depth": { + "type": "string", + "description": "The depth of the extraction process. advanced extraction retrieves more data, including tables and embedded content, with higher success but may increase latency.basic extraction costs 1 credit per 5 successful URL extractions, while advanced extraction costs 2 credits per 5 successful URL extractions.", + "enum": ["basic", "advanced"], + "default": "basic", + "required": False, + }, + "format": { + "type": "string", + "description": "The format of the extracted web page content. markdown returns content in markdown format. text returns plain text and may increase latency.", + "enum": ["markdown", "text"], + "default": "markdown", + "required": False, + } + } + } + super().__init__() + self.api_key = "" + self.extract_depth = "basic" # basic/advanced + self.urls = [] + self.format = "markdown" + self.include_images = False + + def check(self): + self.check_valid_value(self.extract_depth, "Tavily extract depth should be in 'basic/advanced'", ["basic", "advanced"]) + self.check_valid_value(self.format, "Tavily extract format should be in 'markdown/text'", ["markdown", "text"]) + + def get_input_form(self) -> dict[str, dict]: + return { + "urls": { + "name": "URLs", + "type": "line" + } + } + +class TavilyExtract(ToolBase, ABC): + component_name = "TavilyExtract" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 10*60)) + def _invoke(self, **kwargs): + self.tavily_client = TavilyClient(api_key=self._param.api_key) + last_e = None + for fld in ["urls", "extract_depth", "format"]: + if fld not in kwargs: + kwargs[fld] = getattr(self._param, fld) + if kwargs.get("urls") and isinstance(kwargs["urls"], str): + kwargs["urls"] = kwargs["urls"].split(",") + for _ in range(self._param.max_retries+1): + try: + kwargs["include_images"] = False + res = self.tavily_client.extract(**kwargs) + self.set_output("json", res["results"]) + return self.output("json") + except Exception as e: + last_e = e + logging.exception(f"Tavily error: {e}") + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"Tavily error: {last_e}" + + assert False, self.output() diff --git a/agent/component/tushare.py b/agent/tools/tushare.py similarity index 100% rename from agent/component/tushare.py rename to agent/tools/tushare.py diff --git a/agent/tools/wencai.py b/agent/tools/wencai.py new file mode 100644 index 000000000..b751b92d9 --- /dev/null +++ b/agent/tools/wencai.py @@ -0,0 +1,111 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +import pandas as pd +import pywencai + +from agent.tools.base import ToolParamBase, ToolMeta, ToolBase +from api.utils.api_utils import timeout + + +class WenCaiParam(ToolParamBase): + """ + Define the WenCai component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "iwencai", + "description": """ +iwencai search: search platform is committed to providing hundreds of millions of investors with the most timely, accurate and comprehensive information, covering news, announcements, research reports, blogs, forums, Weibo, characters, etc. +robo-advisor intelligent stock selection platform: through AI technology, is committed to providing investors with intelligent stock selection, quantitative investment, main force tracking, value investment, technical analysis and other types of stock selection technologies. +fund selection platform: through AI technology, is committed to providing excellent fund, value investment, quantitative analysis and other fund selection technologies for foundation citizens. +""", + "parameters": { + "query": { + "type": "string", + "description": "The question/conditions to select stocks.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.top_n = 10 + self.query_type = "stock" + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + self.check_valid_value(self.query_type, "Query type", + ['stock', 'zhishu', 'fund', 'hkstock', 'usstock', 'threeboard', 'conbond', 'insurance', + 'futures', 'lccp', + 'foreign_exchange']) + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class WenCai(ToolBase, ABC): + component_name = "WenCai" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("report", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + wencai_res = [] + res = pywencai.get(query=kwargs["query"], query_type=self._param.query_type, perpage=self._param.top_n) + if isinstance(res, pd.DataFrame): + wencai_res.append(res.to_markdown()) + elif isinstance(res, dict): + for item in res.items(): + if isinstance(item[1], list): + wencai_res.append(item[0] + "\n" + pd.DataFrame(item[1]).to_markdown()) + elif isinstance(item[1], str): + wencai_res.append(item[0] + "\n" + item[1]) + elif isinstance(item[1], dict): + if "meta" in item[1].keys(): + continue + wencai_res.append(pd.DataFrame.from_dict(item[1], orient='index').to_markdown()) + elif isinstance(item[1], pd.DataFrame): + if "image_url" in item[1].columns: + continue + wencai_res.append(item[1].to_markdown()) + else: + wencai_res.append(item[0] + "\n" + str(item[1])) + self.set_output("report", "\n\n".join(wencai_res)) + return self.output("report") + except Exception as e: + last_e = e + logging.exception(f"WenCai error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"WenCai error: {last_e}" + + assert False, self.output() diff --git a/agent/tools/wikipedia.py b/agent/tools/wikipedia.py new file mode 100644 index 000000000..d073fb7d8 --- /dev/null +++ b/agent/tools/wikipedia.py @@ -0,0 +1,98 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +import wikipedia +from agent.tools.base import ToolMeta, ToolParamBase, ToolBase +from api.utils.api_utils import timeout + + +class WikipediaParam(ToolParamBase): + """ + Define the Wikipedia component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "wikipedia_search", + "description": """A wide range of how-to and information pages are made available in wikipedia. Since 2001, it has grown rapidly to become the world's largest reference website. From Wikipedia, the free encyclopedia.""", + "parameters": { + "query": { + "type": "string", + "description": "The search keyword to execute with wikipedia. The keyword MUST be a specific subject that can match the title.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.top_n = 10 + self.language = "en" + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + self.check_valid_value(self.language, "Wikipedia languages", + ['af', 'pl', 'ar', 'ast', 'az', 'bg', 'nan', 'bn', 'be', 'ca', 'cs', 'cy', 'da', 'de', + 'et', 'el', 'en', 'es', 'eo', 'eu', 'fa', 'fr', 'gl', 'ko', 'hy', 'hi', 'hr', 'id', + 'it', 'he', 'ka', 'lld', 'la', 'lv', 'lt', 'hu', 'mk', 'arz', 'ms', 'min', 'my', 'nl', + 'ja', 'nb', 'nn', 'ce', 'uz', 'pt', 'kk', 'ro', 'ru', 'ceb', 'sk', 'sl', 'sr', 'sh', + 'fi', 'sv', 'ta', 'tt', 'th', 'tg', 'azb', 'tr', 'uk', 'ur', 'vi', 'war', 'zh', 'yue']) + + def get_input_form(self) -> dict[str, dict]: + return { + "query": { + "name": "Query", + "type": "line" + } + } + +class Wikipedia(ToolBase, ABC): + component_name = "Wikipedia" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 60)) + def _invoke(self, **kwargs): + if not kwargs.get("query"): + self.set_output("formalized_content", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + try: + wikipedia.set_lang(self._param.language) + wiki_engine = wikipedia + pages = [] + for p in wiki_engine.search(kwargs["query"], results=self._param.top_n): + try: + pages.append(wikipedia.page(p)) + except Exception: + pass + self._retrieve_chunks(pages, + get_title=lambda r: r.title, + get_url=lambda r: r.url, + get_content=lambda r: r.summary) + return self.output("formalized_content") + except Exception as e: + last_e = e + logging.exception(f"Wikipedia error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"Wikipedia error: {last_e}" + + assert False, self.output() diff --git a/agent/tools/yahoofinance.py b/agent/tools/yahoofinance.py new file mode 100644 index 000000000..2b70f9616 --- /dev/null +++ b/agent/tools/yahoofinance.py @@ -0,0 +1,111 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging +import os +import time +from abc import ABC +import pandas as pd +import yfinance as yf +from agent.tools.base import ToolMeta, ToolParamBase, ToolBase +from api.utils.api_utils import timeout + + +class YahooFinanceParam(ToolParamBase): + """ + Define the YahooFinance component parameters. + """ + + def __init__(self): + self.meta:ToolMeta = { + "name": "yahoo_finance", + "description": "The Yahoo Finance is a service that provides access to real-time and historical stock market data. It enables users to fetch various types of stock information, such as price quotes, historical prices, company profiles, and financial news. The API offers structured data, allowing developers to integrate market data into their applications and analysis tools.", + "parameters": { + "stock_code": { + "type": "string", + "description": "The stock code or company name.", + "default": "{sys.query}", + "required": True + } + } + } + super().__init__() + self.info = True + self.history = False + self.count = False + self.financials = False + self.income_stmt = False + self.balance_sheet = False + self.cash_flow_statement = False + self.news = True + + def check(self): + self.check_boolean(self.info, "get all stock info") + self.check_boolean(self.history, "get historical market data") + self.check_boolean(self.count, "show share count") + self.check_boolean(self.financials, "show financials") + self.check_boolean(self.income_stmt, "income statement") + self.check_boolean(self.balance_sheet, "balance sheet") + self.check_boolean(self.cash_flow_statement, "cash flow statement") + self.check_boolean(self.news, "show news") + + def get_input_form(self) -> dict[str, dict]: + return { + "stock_code": { + "name": "Stock code/Company name", + "type": "line" + } + } + +class YahooFinance(ToolBase, ABC): + component_name = "YahooFinance" + + @timeout(os.environ.get("COMPONENT_EXEC_TIMEOUT", 60)) + def _invoke(self, **kwargs): + if not kwargs.get("stock_code"): + self.set_output("report", "") + return "" + + last_e = "" + for _ in range(self._param.max_retries+1): + yohoo_res = [] + try: + msft = yf.Ticker(kwargs["stock_code"]) + if self._param.info: + yohoo_res.append("# Information:\n" + pd.Series(msft.info).to_markdown() + "\n") + if self._param.history: + yohoo_res.append("# History:\n" + msft.history().to_markdown() + "\n") + if self._param.financials: + yohoo_res.append("# Calendar:\n" + pd.DataFrame(msft.calendar).to_markdown() + "\n") + if self._param.balance_sheet: + yohoo_res.append("# Balance sheet:\n" + msft.balance_sheet.to_markdown() + "\n") + yohoo_res.append("# Quarterly balance sheet:\n" + msft.quarterly_balance_sheet.to_markdown() + "\n") + if self._param.cash_flow_statement: + yohoo_res.append("# Cash flow statement:\n" + msft.cashflow.to_markdown() + "\n") + yohoo_res.append("# Quarterly cash flow statement:\n" + msft.quarterly_cashflow.to_markdown() + "\n") + if self._param.news: + yohoo_res.append("# News:\n" + pd.DataFrame(msft.news).to_markdown() + "\n") + self.set_output("report", "\n\n".join(yohoo_res)) + return self.output("report") + except Exception as e: + last_e = e + logging.exception(f"YahooFinance error: {e}") + time.sleep(self._param.delay_after_error) + + if last_e: + self.set_output("_ERROR", str(last_e)) + return f"YahooFinance error: {last_e}" + + assert False, self.output() diff --git a/api/apps/canvas_app.py b/api/apps/canvas_app.py index b500d19f1..26ea74888 100644 --- a/api/apps/canvas_app.py +++ b/api/apps/canvas_app.py @@ -14,20 +14,35 @@ # limitations under the License. # import json -import traceback +import logging +import re +import sys +from functools import partial + +import trio from flask import request, Response from flask_login import login_required, current_user -from api.db.services.canvas_service import CanvasTemplateService, UserCanvasService + +from agent.component import LLM +from api.db import FileType +from api.db.services.canvas_service import CanvasTemplateService, UserCanvasService, API4ConversationService +from api.db.services.document_service import DocumentService +from api.db.services.file_service import FileService from api.db.services.user_service import TenantService from api.db.services.user_canvas_version import UserCanvasVersionService from api.settings import RetCode from api.utils import get_uuid -from api.utils.api_utils import get_json_result, server_error_response, validate_request, get_data_error_result +from api.utils.api_utils import get_json_result, server_error_response, validate_request, get_data_error_result, \ + get_error_data_result from agent.canvas import Canvas from peewee import MySQLDatabase, PostgresqlDatabase from api.db.db_models import APIToken import time +from api.utils.file_utils import filename_type, read_potential_broken_pdf +from rag.utils.redis_conn import REDIS_CONN + + @manager.route('/templates', methods=['GET']) # noqa: F821 @login_required def templates(): @@ -112,8 +127,10 @@ def getsse(canvas_id): @login_required def run(): req = request.json - stream = req.get("stream", True) - running_hint_text = req.get("running_hint_text", "") + query = req.get("query", "") + files = req.get("files", []) + inputs = req.get("inputs", {}) + user_id = req.get("user_id", current_user.id) e, cvs = UserCanvasService.get_by_id(req["id"]) if not e: return get_data_error_result(message="canvas not found.") @@ -125,68 +142,29 @@ def run(): if not isinstance(cvs.dsl, str): cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) - final_ans = {"reference": [], "content": ""} - message_id = req.get("message_id", get_uuid()) try: - canvas = Canvas(cvs.dsl, current_user.id) - if "message" in req: - canvas.messages.append({"role": "user", "content": req["message"], "id": message_id}) - canvas.add_user_input(req["message"]) + canvas = Canvas(cvs.dsl, current_user.id, req["id"]) except Exception as e: return server_error_response(e) - if stream: - def sse(): - nonlocal answer, cvs - try: - for ans in canvas.run(running_hint_text = running_hint_text, stream=True): - if ans.get("running_status"): - yield "data:" + json.dumps({"code": 0, "message": "", - "data": {"answer": ans["content"], - "running_status": True}}, - ensure_ascii=False) + "\n\n" - continue - for k in ans.keys(): - final_ans[k] = ans[k] - ans = {"answer": ans["content"], "reference": ans.get("reference", [])} - yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n" + def sse(): + nonlocal canvas, user_id + try: + for ans in canvas.run(query=query, files=files, user_id=user_id, inputs=inputs): + yield "data:" + json.dumps(ans, ensure_ascii=False) + "\n\n" - canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) - canvas.history.append(("assistant", final_ans["content"])) - if not canvas.path[-1]: - canvas.path.pop(-1) - if final_ans.get("reference"): - canvas.reference.append(final_ans["reference"]) - cvs.dsl = json.loads(str(canvas)) - UserCanvasService.update_by_id(req["id"], cvs.to_dict()) - except Exception as e: - cvs.dsl = json.loads(str(canvas)) - if not canvas.path[-1]: - canvas.path.pop(-1) - UserCanvasService.update_by_id(req["id"], cvs.to_dict()) - traceback.print_exc() - yield "data:" + json.dumps({"code": 500, "message": str(e), - "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, - ensure_ascii=False) + "\n\n" - yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" + cvs.dsl = json.loads(str(canvas)) + UserCanvasService.update_by_id(req["id"], cvs.to_dict()) + except Exception as e: + logging.exception(e) + yield "data:" + json.dumps({"code": 500, "message": str(e), "data": False}, ensure_ascii=False) + "\n\n" - resp = Response(sse(), mimetype="text/event-stream") - resp.headers.add_header("Cache-control", "no-cache") - resp.headers.add_header("Connection", "keep-alive") - resp.headers.add_header("X-Accel-Buffering", "no") - resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") - return resp - - for answer in canvas.run(running_hint_text = running_hint_text, stream=False): - if answer.get("running_status"): - continue - final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else "" - canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) - if final_ans.get("reference"): - canvas.reference.append(final_ans["reference"]) - cvs.dsl = json.loads(str(canvas)) - UserCanvasService.update_by_id(req["id"], cvs.to_dict()) - return get_json_result(data={"answer": final_ans["content"], "reference": final_ans.get("reference", [])}) + resp = Response(sse(), mimetype="text/event-stream") + resp.headers.add_header("Cache-control", "no-cache") + resp.headers.add_header("Connection", "keep-alive") + resp.headers.add_header("X-Accel-Buffering", "no") + resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") + return resp @manager.route('/reset', methods=['POST']) # noqa: F821 @@ -212,9 +190,84 @@ def reset(): return server_error_response(e) -@manager.route('/input_elements', methods=['GET']) # noqa: F821 +@manager.route("/upload/", methods=["POST"]) # noqa: F821 +def upload(canvas_id): + e, cvs = UserCanvasService.get_by_tenant_id(canvas_id) + if not e: + return get_data_error_result(message="canvas not found.") + + user_id = cvs["user_id"] + def structured(filename, filetype, blob, content_type): + nonlocal user_id + if filetype == FileType.PDF.value: + blob = read_potential_broken_pdf(blob) + + location = get_uuid() + FileService.put_blob(user_id, location, blob) + + return { + "id": location, + "name": filename, + "size": sys.getsizeof(blob), + "extension": filename.split(".")[-1].lower(), + "mime_type": content_type, + "created_by": user_id, + "created_at": time.time(), + "preview_url": None + } + + if request.args.get("url"): + from crawl4ai import ( + AsyncWebCrawler, + BrowserConfig, + CrawlerRunConfig, + DefaultMarkdownGenerator, + PruningContentFilter, + CrawlResult + ) + try: + url = request.args.get("url") + filename = re.sub(r"\?.*", "", url.split("/")[-1]) + async def adownload(): + browser_config = BrowserConfig( + headless=True, + verbose=False, + ) + async with AsyncWebCrawler(config=browser_config) as crawler: + crawler_config = CrawlerRunConfig( + markdown_generator=DefaultMarkdownGenerator( + content_filter=PruningContentFilter() + ), + pdf=True, + screenshot=False + ) + result: CrawlResult = await crawler.arun( + url=url, + config=crawler_config + ) + return result + page = trio.run(adownload()) + if page.pdf: + if filename.split(".")[-1].lower() != "pdf": + filename += ".pdf" + return get_json_result(data=structured(filename, "pdf", page.pdf, page.response_headers["content-type"])) + + return get_json_result(data=structured(filename, "html", str(page.markdown).encode("utf-8"), page.response_headers["content-type"], user_id)) + + except Exception as e: + return server_error_response(e) + + file = request.files['file'] + try: + DocumentService.check_doc_health(user_id, file.filename) + return get_json_result(data=structured(file.filename, filename_type(file.filename), file.read(), file.content_type)) + except Exception as e: + return server_error_response(e) + + +@manager.route('/input_form', methods=['GET']) # noqa: F821 @login_required -def input_elements(): +def input_form(): cvs_id = request.args.get("id") cpn_id = request.args.get("component_id") try: @@ -227,7 +280,7 @@ def input_elements(): code=RetCode.OPERATING_ERROR) canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id) - return get_json_result(data=canvas.get_component_input_elements(cpn_id)) + return get_json_result(data=canvas.get_component_input_form(cpn_id)) except Exception as e: return server_error_response(e) @@ -237,8 +290,6 @@ def input_elements(): @login_required def debug(): req = request.json - for p in req["params"]: - assert p.get("key") try: e, user_canvas = UserCanvasService.get_by_id(req["id"]) if not e: @@ -249,11 +300,22 @@ def debug(): code=RetCode.OPERATING_ERROR) canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id) - componant = canvas.get_component(req["component_id"])["obj"] - componant.reset() - componant._param.debug_inputs = req["params"] - df = canvas.get_component(req["component_id"])["obj"].debug() - return get_json_result(data=df.to_dict(orient="records")) + canvas.reset() + canvas.message_id = get_uuid() + component = canvas.get_component(req["component_id"])["obj"] + component.reset() + + if isinstance(component, LLM): + component.set_debug_inputs(req["params"]) + component.invoke(**{k: o["value"] for k,o in req["params"].items()}) + outputs = component.output() + for k in outputs.keys(): + if isinstance(outputs[k], partial): + txt = "" + for c in outputs[k](): + txt += c + outputs[k] = txt + return get_json_result(data=outputs) except Exception as e: return server_error_response(e) @@ -292,6 +354,8 @@ def test_db_connect(): return get_json_result(data="Database Connection Successful!") except Exception as e: return server_error_response(e) + + #api get list version dsl of canvas @manager.route('/getlistversion/', methods=['GET']) # noqa: F821 @login_required @@ -301,6 +365,8 @@ def getlistversion(canvas_id): return get_json_result(data=list) except Exception as e: return get_data_error_result(message=f"Error getting history files: {e}") + + #api get version dsl of canvas @manager.route('/getversion/', methods=['GET']) # noqa: F821 @login_required @@ -312,6 +378,8 @@ def getversion( version_id): return get_json_result(data=version.to_dict()) except Exception as e: return get_json_result(data=f"Error getting history file: {e}") + + @manager.route('/listteam', methods=['GET']) # noqa: F821 @login_required def list_kbs(): @@ -328,6 +396,8 @@ def list_kbs(): return get_json_result(data={"kbs": kbs, "total": total}) except Exception as e: return server_error_response(e) + + @manager.route('/setting', methods=['POST']) # noqa: F821 @validate_request("id", "title", "permission") @login_required @@ -351,3 +421,46 @@ def setting(): code=RetCode.OPERATING_ERROR) num= UserCanvasService.update_by_id(req["id"], flow) return get_json_result(data=num) + + +@manager.route('/trace', methods=['GET']) # noqa: F821 +def trace(): + cvs_id = request.args.get("canvas_id") + msg_id = request.args.get("message_id") + try: + bin = REDIS_CONN.get(f"{cvs_id}-{msg_id}-logs") + if not bin: + return get_json_result(data={}) + + return get_json_result(data=json.loads(bin.encode("utf-8"))) + except Exception as e: + logging.exception(e) + + +@manager.route('//sessions', methods=['GET']) # noqa: F821 +@login_required +def sessions(canvas_id): + tenant_id = current_user.id + if not UserCanvasService.query(user_id=tenant_id, id=canvas_id): + return get_error_data_result(message=f"You don't own the agent {canvas_id}.") + + user_id = request.args.get("user_id") + page_number = int(request.args.get("page", 1)) + items_per_page = int(request.args.get("page_size", 30)) + keywords = request.args.get("keywords") + from_date = request.args.get("from_date") + to_date = request.args.get("to_date") + orderby = request.args.get("orderby", "update_time") + if request.args.get("desc") == "False" or request.args.get("desc") == "false": + desc = False + else: + desc = True + # dsl defaults to True in all cases except for False and false + include_dsl = request.args.get("dsl") != "False" and request.args.get("dsl") != "false" + total, sess = API4ConversationService.get_list(canvas_id, tenant_id, page_number, items_per_page, orderby, desc, + None, user_id, include_dsl, keywords, from_date, to_date) + try: + return get_json_result(data={"total": total, "sessions": sess}) + except Exception as e: + return server_error_response(e) + diff --git a/api/apps/conversation_app.py b/api/apps/conversation_app.py index 16d67bc57..3799d01bc 100644 --- a/api/apps/conversation_app.py +++ b/api/apps/conversation_app.py @@ -33,6 +33,7 @@ from api.db.services.user_service import UserTenantService from api.utils.api_utils import get_data_error_result, get_json_result, server_error_response, validate_request from graphrag.general.mind_map_extractor import MindMapExtractor from rag.app.tag import label_question +from rag.prompts.prompts import chunks_format @manager.route("/set", methods=["POST"]) # noqa: F821 @@ -90,25 +91,10 @@ def get(): else: return get_json_result(data=False, message="Only owner of conversation authorized for this operation.", code=settings.RetCode.OPERATING_ERROR) - def get_value(d, k1, k2): - return d.get(k1, d.get(k2)) - for ref in conv.reference: if isinstance(ref, list): continue - ref["chunks"] = [ - { - "id": get_value(ck, "chunk_id", "id"), - "content": get_value(ck, "content", "content_with_weight"), - "document_id": get_value(ck, "doc_id", "document_id"), - "document_name": get_value(ck, "docnm_kwd", "document_name"), - "dataset_id": get_value(ck, "kb_id", "dataset_id"), - "image_id": get_value(ck, "image_id", "img_id"), - "positions": get_value(ck, "positions", "position_int"), - "doc_type": get_value(ck, "doc_type", "doc_type_kwd"), - } - for ck in ref.get("chunks", []) - ] + ref["chunks"] = chunks_format(ref) conv = conv.to_dict() conv["avatar"] = avatar @@ -201,26 +187,10 @@ def completion(): if not conv.reference: conv.reference = [] else: - - def get_value(d, k1, k2): - return d.get(k1, d.get(k2)) - for ref in conv.reference: if isinstance(ref, list): continue - ref["chunks"] = [ - { - "id": get_value(ck, "chunk_id", "id"), - "content": get_value(ck, "content", "content_with_weight"), - "document_id": get_value(ck, "doc_id", "document_id"), - "document_name": get_value(ck, "docnm_kwd", "document_name"), - "dataset_id": get_value(ck, "kb_id", "dataset_id"), - "image_id": get_value(ck, "image_id", "img_id"), - "positions": get_value(ck, "positions", "position_int"), - "doc_type": get_value(ck, "doc_type_kwd", "doc_type_kwd"), - } - for ck in ref.get("chunks", []) - ] + ref["chunks"] = chunks_format(ref) if not conv.reference: conv.reference = [] diff --git a/api/apps/dialog_app.py b/api/apps/dialog_app.py index 42f496c72..add9f595e 100644 --- a/api/apps/dialog_app.py +++ b/api/apps/dialog_app.py @@ -51,7 +51,7 @@ def set_dialog(): vector_similarity_weight = req.get("vector_similarity_weight", 0.3) llm_setting = req.get("llm_setting", {}) prompt_config = req["prompt_config"] - + if not req.get("kb_ids", []) and not prompt_config.get("tavily_api_key") and "{knowledge}" in prompt_config['system']: return get_data_error_result(message="Please remove `{knowledge}` in system prompt since no knowledge base/Tavily used here.") diff --git a/api/apps/sdk/session.py b/api/apps/sdk/session.py index dd2722552..06e86bb86 100644 --- a/api/apps/sdk/session.py +++ b/api/apps/sdk/session.py @@ -556,7 +556,7 @@ def list_agent_session(tenant_id, agent_id): desc = True # dsl defaults to True in all cases except for False and false include_dsl = request.args.get("dsl") != "False" and request.args.get("dsl") != "false" - convs = API4ConversationService.get_list(agent_id, tenant_id, page_number, items_per_page, orderby, desc, id, user_id, include_dsl) + total, convs = API4ConversationService.get_list(agent_id, tenant_id, page_number, items_per_page, orderby, desc, id, user_id, include_dsl) if not convs: return get_result(data=[]) for conv in convs: @@ -817,9 +817,6 @@ def agent_bot_completions(agent_id): if not objs: return get_error_data_result(message='Authentication error: API key is invalid!"') - if "quote" not in req: - req["quote"] = False - if req.get("stream", True): resp = Response(agent_completion(objs[0].tenant_id, agent_id, **req), mimetype="text/event-stream") resp.headers.add_header("Cache-control", "no-cache") @@ -830,3 +827,23 @@ def agent_bot_completions(agent_id): for answer in agent_completion(objs[0].tenant_id, agent_id, **req): return get_result(data=answer) + + +@manager.route("/agentbots//inputs", methods=["GET"]) # noqa: F821 +def begin_inputs(agent_id): + token = request.headers.get("Authorization").split() + if len(token) != 2: + return get_error_data_result(message='Authorization is not valid!"') + token = token[1] + objs = APIToken.query(beta=token) + if not objs: + return get_error_data_result(message='Authentication error: API key is invalid!"') + + e, cvs = UserCanvasService.get_by_id(agent_id) + if not e: + return get_error_data_result(f"Can't find agent by ID: {agent_id}") + + canvas = Canvas(json.dumps(cvs.dsl), objs[0].tenant_id) + return get_result(data=canvas.get_component_input_form("begin")) + + diff --git a/api/db/db_models.py b/api/db/db_models.py index 1acf6bbca..038fc8406 100644 --- a/api/db/db_models.py +++ b/api/db/db_models.py @@ -463,6 +463,7 @@ class DataBaseModel(BaseModel): @DB.connection_context() +@DB.lock("init_database_tables", 60) def init_database_tables(alter_fields=[]): members = inspect.getmembers(sys.modules[__name__], inspect.isclass) table_objs = [] @@ -474,7 +475,7 @@ def init_database_tables(alter_fields=[]): if not obj.table_exists(): logging.debug(f"start create table {obj.__name__}") try: - obj.create_table() + obj.create_table(safe=True) logging.debug(f"create table success: {obj.__name__}") except Exception as e: logging.exception(e) @@ -798,6 +799,7 @@ class API4Conversation(DataBaseModel): duration = FloatField(default=0, index=True) round = IntegerField(default=0, index=True) thumb_up = IntegerField(default=0, index=True) + errors = TextField(null=True, help_text="errors") class Meta: db_table = "api_4_conversation" @@ -1009,4 +1011,8 @@ def migrate_db(): migrate(migrator.add_column("document", "suffix", CharField(max_length=32, null=False, default="", help_text="The real file extension suffix", index=True))) except Exception: pass - logging.disable(logging.NOTSET) + try: + migrate(migrator.add_column("api_4_conversation", "errors", TextField(null=True, help_text="errors"))) + except Exception: + pass + logging.disable(logging.NOTSET) \ No newline at end of file diff --git a/api/db/init_data.py b/api/db/init_data.py index b46b27ce6..390bce48e 100644 --- a/api/db/init_data.py +++ b/api/db/init_data.py @@ -154,6 +154,11 @@ def init_llm_factory(): def add_graph_templates(): dir = os.path.join(get_project_base_directory(), "agent", "templates") + CanvasTemplateService.filter_delete([1 == 1]) + if not os.path.exists(dir): + logging.warning("Missing agent templates!") + return + for fnm in os.listdir(dir): try: cnvs = json.load(open(os.path.join(dir, fnm), "r",encoding="utf-8")) @@ -162,7 +167,7 @@ def add_graph_templates(): except Exception: CanvasTemplateService.update_by_id(cnvs["id"], cnvs) except Exception: - logging.exception("Add graph templates error: ") + logging.exception("Add agent templates error: ") def init_web_data(): diff --git a/api/db/services/api_service.py b/api/db/services/api_service.py index b393812e9..2fcbe0329 100644 --- a/api/db/services/api_service.py +++ b/api/db/services/api_service.py @@ -43,7 +43,9 @@ class API4ConversationService(CommonService): @DB.connection_context() def get_list(cls, dialog_id, tenant_id, page_number, items_per_page, - orderby, desc, id, user_id=None, include_dsl=True): + orderby, desc, id, user_id=None, include_dsl=True, keywords="", + from_date=None, to_date=None + ): if include_dsl: sessions = cls.model.select().where(cls.model.dialog_id == dialog_id) else: @@ -53,13 +55,20 @@ class API4ConversationService(CommonService): sessions = sessions.where(cls.model.id == id) if user_id: sessions = sessions.where(cls.model.user_id == user_id) + if keywords: + sessions = sessions.where(peewee.fn.LOWER(cls.model.message).contains(keywords.lower())) + if from_date: + sessions = sessions.where(cls.model.create_date >= from_date) + if to_date: + sessions = sessions.where(cls.model.create_date <= to_date) if desc: sessions = sessions.order_by(cls.model.getter_by(orderby).desc()) else: sessions = sessions.order_by(cls.model.getter_by(orderby).asc()) + count = sessions.count() sessions = sessions.paginate(page_number, items_per_page) - return list(sessions.dicts()) + return count, list(sessions.dicts()) @classmethod @DB.connection_context() diff --git a/api/db/services/canvas_service.py b/api/db/services/canvas_service.py index 8bcb7b1bc..832ffb4f6 100644 --- a/api/db/services/canvas_service.py +++ b/api/db/services/canvas_service.py @@ -14,6 +14,7 @@ # limitations under the License. # import json +import logging import time import traceback from uuid import uuid4 @@ -22,11 +23,12 @@ from api.db import TenantPermission from api.db.db_models import DB, CanvasTemplate, User, UserCanvas, API4Conversation from api.db.services.api_service import API4ConversationService from api.db.services.common_service import CommonService -from api.db.services.conversation_service import structure_answer from api.utils import get_uuid from api.utils.api_utils import get_data_openai import tiktoken from peewee import fn + + class CanvasTemplateService(CommonService): model = CanvasTemplate @@ -79,7 +81,7 @@ class UserCanvasService(CommonService): # obj = cls.model.query(id=pid)[0] return True, agents.dicts()[0] except Exception as e: - print(e) + logging.exception(e) return False, None @classmethod @@ -119,120 +121,58 @@ class UserCanvasService(CommonService): count = agents.count() agents = agents.paginate(page_number, items_per_page) return list(agents.dicts()), count - -def completion(tenant_id, agent_id, question, session_id=None, stream=True, **kwargs): - e, cvs = UserCanvasService.get_by_id(agent_id) - assert e, "Agent not found." - assert cvs.user_id == tenant_id, "You do not own the agent." - if not isinstance(cvs.dsl,str): - cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) - canvas = Canvas(cvs.dsl, tenant_id) - canvas.reset() - message_id = str(uuid4()) - if not session_id: - query = canvas.get_preset_param() - if query: - for ele in query: - if not ele["optional"]: - if not kwargs.get(ele["key"]): - assert False, f"`{ele['key']}` is required" - ele["value"] = kwargs[ele["key"]] - if ele["optional"]: - if kwargs.get(ele["key"]): - ele["value"] = kwargs[ele['key']] - else: - if "value" in ele: - ele.pop("value") - cvs.dsl = json.loads(str(canvas)) + +def completion(tenant_id, agent_id, session_id=None, **kwargs): + query = kwargs.get("query", "") + files = kwargs.get("files", []) + inputs = kwargs.get("inputs", {}) + user_id = kwargs.get("user_id", "") + + if session_id: + e, conv = API4ConversationService.get_by_id(session_id) + assert e, "Session not found!" + if not conv.message: + conv.message = [] + canvas = Canvas(json.dumps(conv.dsl), tenant_id, session_id) + else: + e, cvs = UserCanvasService.get_by_id(agent_id) + assert e, "Agent not found." + assert cvs.user_id == tenant_id, "You do not own the agent." + if not isinstance(cvs.dsl, str): + cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) session_id=get_uuid() + canvas = Canvas(cvs.dsl, tenant_id, session_id) conv = { "id": session_id, "dialog_id": cvs.id, - "user_id": kwargs.get("user_id", "") if isinstance(kwargs, dict) else "", - "message": [{"role": "assistant", "content": canvas.get_prologue(), "created_at": time.time()}], + "user_id": user_id, + "message": [], "source": "agent", "dsl": cvs.dsl } API4ConversationService.save(**conv) conv = API4Conversation(**conv) - else: - e, conv = API4ConversationService.get_by_id(session_id) - assert e, "Session not found!" - canvas = Canvas(json.dumps(conv.dsl), tenant_id) - canvas.messages.append({"role": "user", "content": question, "id": message_id}) - canvas.add_user_input(question) - if not conv.message: - conv.message = [] - conv.message.append({ - "role": "user", - "content": question, - "id": message_id - }) - if not conv.reference: - conv.reference = [] - conv.reference.append({"chunks": [], "doc_aggs": []}) - kwargs_changed = False - if kwargs: - query = canvas.get_preset_param() - if query: - for ele in query: - if ele["key"] in kwargs: - if ele["value"] != kwargs[ele["key"]]: - ele["value"] = kwargs[ele["key"]] - kwargs_changed = True - if kwargs_changed: - conv.dsl = json.loads(str(canvas)) - API4ConversationService.update_by_id(session_id, {"dsl": conv.dsl}) + message_id = str(uuid4()) + conv.message.append({ + "role": "user", + "content": query, + "id": message_id + }) + txt = "" + for ans in canvas.run(query=query, files=files, user_id=user_id, inputs=inputs): + ans["session_id"] = session_id + if ans["event"] == "message": + txt += ans["data"]["content"] + yield "data:" + json.dumps(ans, ensure_ascii=False) + "\n\n" - final_ans = {"reference": [], "content": ""} - if stream: - try: - for ans in canvas.run(stream=stream): - if ans.get("running_status"): - yield "data:" + json.dumps({"code": 0, "message": "", - "data": {"answer": ans["content"], - "running_status": True}}, - ensure_ascii=False) + "\n\n" - continue - for k in ans.keys(): - final_ans[k] = ans[k] - ans = {"answer": ans["content"], "reference": ans.get("reference", []), "param": canvas.get_preset_param()} - ans = structure_answer(conv, ans, message_id, session_id) - yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, - ensure_ascii=False) + "\n\n" + conv.message.append({"role": "assistant", "content": txt, "created_at": time.time(), "id": message_id}) + conv.reference = canvas.get_reference() + conv.errors = canvas.error + API4ConversationService.append_message(conv.id, conv.to_dict()) - canvas.messages.append({"role": "assistant", "content": final_ans["content"], "created_at": time.time(), "id": message_id}) - canvas.history.append(("assistant", final_ans["content"])) - if final_ans.get("reference"): - canvas.reference.append(final_ans["reference"]) - conv.dsl = json.loads(str(canvas)) - API4ConversationService.append_message(conv.id, conv.to_dict()) - except Exception as e: - traceback.print_exc() - conv.dsl = json.loads(str(canvas)) - API4ConversationService.append_message(conv.id, conv.to_dict()) - yield "data:" + json.dumps({"code": 500, "message": str(e), - "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, - ensure_ascii=False) + "\n\n" - yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" - else: - for answer in canvas.run(stream=False): - if answer.get("running_status"): - continue - final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else "" - canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) - if final_ans.get("reference"): - canvas.reference.append(final_ans["reference"]) - conv.dsl = json.loads(str(canvas)) - - result = {"answer": final_ans["content"], "reference": final_ans.get("reference", []) , "param": canvas.get_preset_param()} - result = structure_answer(conv, result, message_id, session_id) - API4ConversationService.append_message(conv.id, conv.to_dict()) - yield result - break def completionOpenAI(tenant_id, agent_id, question, session_id=None, stream=True, **kwargs): """Main function for OpenAI-compatible completions, structured similarly to the completion function.""" tiktokenenc = tiktoken.get_encoding("cl100k_base") diff --git a/api/db/services/document_service.py b/api/db/services/document_service.py index ec8e5f64a..4b60275d3 100644 --- a/api/db/services/document_service.py +++ b/api/db/services/document_service.py @@ -27,7 +27,7 @@ import xxhash from peewee import fn from api import settings -from api.constants import IMG_BASE64_PREFIX +from api.constants import IMG_BASE64_PREFIX, FILE_NAME_LEN_LIMIT from api.db import FileType, LLMType, ParserType, StatusEnum, TaskStatus, UserTenantRole from api.db.db_models import DB, Document, Knowledgebase, Task, Tenant, UserTenant, File2Document, File from api.db.db_utils import bulk_insert_into_db @@ -100,6 +100,17 @@ class DocumentService(CommonService): docs = docs.paginate(page_number, items_per_page) return list(docs.dicts()), count + @classmethod + @DB.connection_context() + def check_doc_health(cls, tenant_id: str, filename): + import os + MAX_FILE_NUM_PER_USER = int(os.environ.get("MAX_FILE_NUM_PER_USER", 0)) + if MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(tenant_id) >= MAX_FILE_NUM_PER_USER: + raise RuntimeError("Exceed the maximum file number of a free user!") + if len(filename.encode("utf-8")) > FILE_NAME_LEN_LIMIT: + raise RuntimeError("Exceed the maximum length of file name!") + return True + @classmethod @DB.connection_context() def get_by_kb_id(cls, kb_id, page_number, items_per_page, @@ -258,13 +269,13 @@ class DocumentService(CommonService): ) if len(graph_source) > 0 and doc.id in list(graph_source.values())[0]["source_id"]: settings.docStoreConn.update({"kb_id": doc.kb_id, "knowledge_graph_kwd": ["entity", "relation", "graph", "subgraph", "community_report"], "source_id": doc.id}, - {"remove": {"source_id": doc.id}}, - search.index_name(tenant_id), doc.kb_id) + {"remove": {"source_id": doc.id}}, + search.index_name(tenant_id), doc.kb_id) settings.docStoreConn.update({"kb_id": doc.kb_id, "knowledge_graph_kwd": ["graph"]}, - {"removed_kwd": "Y"}, - search.index_name(tenant_id), doc.kb_id) + {"removed_kwd": "Y"}, + search.index_name(tenant_id), doc.kb_id) settings.docStoreConn.delete({"kb_id": doc.kb_id, "knowledge_graph_kwd": ["entity", "relation", "graph", "subgraph", "community_report"], "must_not": {"exists": "source_id"}}, - search.index_name(tenant_id), doc.kb_id) + search.index_name(tenant_id), doc.kb_id) except Exception: pass return cls.delete_by_id(doc.id) @@ -323,9 +334,9 @@ class DocumentService(CommonService): "Document not found which is supposed to be there") num = Knowledgebase.update( token_num=Knowledgebase.token_num + - token_num, + token_num, chunk_num=Knowledgebase.chunk_num + - chunk_num).where( + chunk_num).where( Knowledgebase.id == kb_id).execute() return num @@ -341,9 +352,9 @@ class DocumentService(CommonService): "Document not found which is supposed to be there") num = Knowledgebase.update( token_num=Knowledgebase.token_num - - token_num, + token_num, chunk_num=Knowledgebase.chunk_num - - chunk_num + chunk_num ).where( Knowledgebase.id == kb_id).execute() return num @@ -356,9 +367,9 @@ class DocumentService(CommonService): num = Knowledgebase.update( token_num=Knowledgebase.token_num - - doc.token_num, + doc.token_num, chunk_num=Knowledgebase.chunk_num - - doc.chunk_num, + doc.chunk_num, doc_num=Knowledgebase.doc_num - 1 ).where( Knowledgebase.id == doc.kb_id).execute() @@ -388,7 +399,7 @@ class DocumentService(CommonService): docs = cls.model.select( Knowledgebase.tenant_id).join( Knowledgebase, on=( - Knowledgebase.id == cls.model.kb_id)).where( + Knowledgebase.id == cls.model.kb_id)).where( cls.model.id == doc_id, Knowledgebase.status == StatusEnum.VALID.value) docs = docs.dicts() if not docs: @@ -410,7 +421,7 @@ class DocumentService(CommonService): docs = cls.model.select( Knowledgebase.tenant_id).join( Knowledgebase, on=( - Knowledgebase.id == cls.model.kb_id)).where( + Knowledgebase.id == cls.model.kb_id)).where( cls.model.name == name, Knowledgebase.status == StatusEnum.VALID.value) docs = docs.dicts() if not docs: @@ -423,7 +434,7 @@ class DocumentService(CommonService): docs = cls.model.select( cls.model.id).join( Knowledgebase, on=( - Knowledgebase.id == cls.model.kb_id) + Knowledgebase.id == cls.model.kb_id) ).join(UserTenant, on=(UserTenant.tenant_id == Knowledgebase.tenant_id) ).where(cls.model.id == doc_id, UserTenant.user_id == user_id).paginate(0, 1) docs = docs.dicts() @@ -435,12 +446,12 @@ class DocumentService(CommonService): @DB.connection_context() def accessible4deletion(cls, doc_id, user_id): docs = cls.model.select(cls.model.id - ).join( + ).join( Knowledgebase, on=( - Knowledgebase.id == cls.model.kb_id) + Knowledgebase.id == cls.model.kb_id) ).join( UserTenant, on=( - (UserTenant.tenant_id == Knowledgebase.created_by) & (UserTenant.user_id == user_id)) + (UserTenant.tenant_id == Knowledgebase.created_by) & (UserTenant.user_id == user_id)) ).where( cls.model.id == doc_id, UserTenant.status == StatusEnum.VALID.value, @@ -457,7 +468,7 @@ class DocumentService(CommonService): docs = cls.model.select( Knowledgebase.embd_id).join( Knowledgebase, on=( - Knowledgebase.id == cls.model.kb_id)).where( + Knowledgebase.id == cls.model.kb_id)).where( cls.model.id == doc_id, Knowledgebase.status == StatusEnum.VALID.value) docs = docs.dicts() if not docs: @@ -499,7 +510,7 @@ class DocumentService(CommonService): if not doc_id: return return doc_id[0]["id"] - + @classmethod @DB.connection_context() def get_doc_ids_by_doc_names(cls, doc_names): @@ -612,7 +623,7 @@ class DocumentService(CommonService): info = { "process_duration": datetime.timestamp( datetime.now()) - - d["process_begin_at"].timestamp(), + d["process_begin_at"].timestamp(), "run": status} if prg != 0: info["progress"] = prg diff --git a/api/db/services/file_service.py b/api/db/services/file_service.py index 34033771f..767b389e9 100644 --- a/api/db/services/file_service.py +++ b/api/db/services/file_service.py @@ -14,7 +14,6 @@ # limitations under the License. # import logging -import os import re from concurrent.futures import ThreadPoolExecutor from pathlib import Path @@ -22,7 +21,6 @@ from pathlib import Path from flask_login import current_user from peewee import fn -from api.constants import FILE_NAME_LEN_LIMIT from api.db import KNOWLEDGEBASE_FOLDER_NAME, FileSource, FileType, ParserType from api.db.db_models import DB, Document, File, File2Document, Knowledgebase from api.db.services import duplicate_name @@ -31,6 +29,7 @@ from api.db.services.document_service import DocumentService from api.db.services.file2document_service import File2DocumentService from api.utils import get_uuid from api.utils.file_utils import filename_type, read_potential_broken_pdf, thumbnail_img +from rag.llm.cv_model import GptV4 from rag.utils.storage_factory import STORAGE_IMPL @@ -411,12 +410,7 @@ class FileService(CommonService): err, files = [], [] for file in file_objs: try: - MAX_FILE_NUM_PER_USER = int(os.environ.get("MAX_FILE_NUM_PER_USER", 0)) - if MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(kb.tenant_id) >= MAX_FILE_NUM_PER_USER: - raise RuntimeError("Exceed the maximum file number of a free user!") - if len(file.filename.encode("utf-8")) > FILE_NAME_LEN_LIMIT: - raise RuntimeError(f"File name must be {FILE_NAME_LEN_LIMIT} bytes or less.") - + DocumentService.check_doc_health(kb.tenant_id, file.filename) filename = duplicate_name(DocumentService.query, name=file.filename, kb_id=kb.id) filetype = filename_type(filename) if filetype == FileType.OTHER.value: @@ -463,6 +457,19 @@ class FileService(CommonService): @staticmethod def parse_docs(file_objs, user_id): + exe = ThreadPoolExecutor(max_workers=12) + threads = [] + for file in file_objs: + threads.append(exe.submit(FileService.parse, file.filename, file.read(), False)) + + res = [] + for th in threads: + res.append(th.result()) + + return "\n\n".join(res) + + @staticmethod + def parse(filename, blob, img_base64=True, tenant_id=None): from rag.app import audio, email, naive, picture, presentation def dummy(prog=None, msg=""): @@ -470,19 +477,12 @@ class FileService(CommonService): FACTORY = {ParserType.PRESENTATION.value: presentation, ParserType.PICTURE.value: picture, ParserType.AUDIO.value: audio, ParserType.EMAIL.value: email} parser_config = {"chunk_token_num": 16096, "delimiter": "\n!?;。;!?", "layout_recognize": "Plain Text"} - exe = ThreadPoolExecutor(max_workers=12) - threads = [] - for file in file_objs: - kwargs = {"lang": "English", "callback": dummy, "parser_config": parser_config, "from_page": 0, "to_page": 100000, "tenant_id": user_id} - filetype = filename_type(file.filename) - blob = file.read() - threads.append(exe.submit(FACTORY.get(FileService.get_parser(filetype, file.filename, ""), naive).chunk, file.filename, blob, **kwargs)) - - res = [] - for th in threads: - res.append("\n".join([ck["content_with_weight"] for ck in th.result()])) - - return "\n\n".join(res) + kwargs = {"lang": "English", "callback": dummy, "parser_config": parser_config, "from_page": 0, "to_page": 100000, "tenant_id": current_user.id if current_user else tenant_id} + file_type = filename_type(filename) + if img_base64 and file_type == FileType.VISUAL.value: + return GptV4.image2base64(blob) + cks = FACTORY.get(FileService.get_parser(filename_type(filename), filename, ""), naive).chunk(filename, blob, **kwargs) + return "\n".join([ck["content_with_weight"] for ck in cks]) @staticmethod def get_parser(doc_type, filename, default): @@ -495,3 +495,14 @@ class FileService(CommonService): if re.search(r"\.(eml)$", filename): return ParserType.EMAIL.value return default + + @staticmethod + def get_blob(user_id, location): + bname = f"{user_id}-downloads" + return STORAGE_IMPL.get(bname, location) + + @staticmethod + def put_blob(user_id, location, blob): + bname = f"{user_id}-downloads" + return STORAGE_IMPL.put(bname, location, blob) + diff --git a/api/db/services/llm_service.py b/api/db/services/llm_service.py index 92655abfd..258a4bf92 100644 --- a/api/db/services/llm_service.py +++ b/api/db/services/llm_service.py @@ -14,6 +14,8 @@ # limitations under the License. # import logging +import re +from functools import partial from langfuse import Langfuse @@ -137,7 +139,7 @@ class TenantLLMService(CommonService): @classmethod @DB.connection_context() - def model_instance(cls, tenant_id, llm_type, llm_name=None, lang="Chinese"): + def model_instance(cls, tenant_id, llm_type, llm_name=None, lang="Chinese", **kwargs): model_config = TenantLLMService.get_model_config(tenant_id, llm_type, llm_name) if llm_type == LLMType.EMBEDDING.value: if model_config["llm_factory"] not in EmbeddingModel: @@ -152,12 +154,12 @@ class TenantLLMService(CommonService): if llm_type == LLMType.IMAGE2TEXT.value: if model_config["llm_factory"] not in CvModel: return - return CvModel[model_config["llm_factory"]](model_config["api_key"], model_config["llm_name"], lang, base_url=model_config["api_base"]) + return CvModel[model_config["llm_factory"]](model_config["api_key"], model_config["llm_name"], lang, base_url=model_config["api_base"], **kwargs) if llm_type == LLMType.CHAT.value: if model_config["llm_factory"] not in ChatModel: return - return ChatModel[model_config["llm_factory"]](model_config["api_key"], model_config["llm_name"], base_url=model_config["api_base"]) + return ChatModel[model_config["llm_factory"]](model_config["api_key"], model_config["llm_name"], base_url=model_config["api_base"], **kwargs) if llm_type == LLMType.SPEECH2TEXT: if model_config["llm_factory"] not in Seq2txtModel: @@ -221,20 +223,21 @@ class TenantLLMService(CommonService): for llm_factory in llm_factories: for llm in llm_factory["llm"]: if llm_id == llm["llm_name"]: - return llm["model_type"].strip(",")[-1] + return llm["model_type"].split(",")[-1] class LLMBundle: - def __init__(self, tenant_id, llm_type, llm_name=None, lang="Chinese"): + def __init__(self, tenant_id, llm_type, llm_name=None, lang="Chinese", **kwargs): self.tenant_id = tenant_id self.llm_type = llm_type self.llm_name = llm_name - self.mdl = TenantLLMService.model_instance(tenant_id, llm_type, llm_name, lang=lang) + self.mdl = TenantLLMService.model_instance(tenant_id, llm_type, llm_name, lang=lang, **kwargs) assert self.mdl, "Can't find model for {}/{}/{}".format(tenant_id, llm_type, llm_name) model_config = TenantLLMService.get_model_config(tenant_id, llm_type, llm_name) self.max_length = model_config.get("max_tokens", 8192) self.is_tools = model_config.get("is_tools", False) + self.verbose_tool_use = kwargs.get("verbose_tool_use") langfuse_keys = TenantLangfuseService.filter_by_tenant(tenant_id=tenant_id) if langfuse_keys: @@ -331,7 +334,7 @@ class LLMBundle: return txt - def tts(self, text): + def tts(self, text: str) -> None: if self.langfuse: span = self.trace.span(name="tts", input={"text": text}) @@ -359,17 +362,20 @@ class LLMBundle: return txt[last_think_end + len("") :] - def chat(self, system, history, gen_conf): + def chat(self, system: str, history: list, gen_conf: dict={}, **kwargs) -> str: if self.langfuse: generation = self.trace.generation(name="chat", model=self.llm_name, input={"system": system, "history": history}) - chat = self.mdl.chat + chat_partial = partial(self.mdl.chat, system, history, gen_conf) if self.is_tools and self.mdl.is_tools: - chat = self.mdl.chat_with_tools + chat_partial = partial(self.mdl.chat_with_tools, system, history, gen_conf) - txt, used_tokens = chat(system, history, gen_conf) + txt, used_tokens = chat_partial(**kwargs) txt = self._remove_reasoning_content(txt) + if not self.verbose_tool_use: + txt = re.sub(r".*?", "", txt, flags=re.DOTALL) + if isinstance(txt, int) and not TenantLLMService.increase_usage(self.tenant_id, self.llm_type, used_tokens, self.llm_name): logging.error("LLMBundle.chat can't update token usage for {}/CHAT llm_name: {}, used_tokens: {}".format(self.tenant_id, self.llm_name, used_tokens)) @@ -378,17 +384,17 @@ class LLMBundle: return txt - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system: str, history: list, gen_conf: dict={}, **kwargs): if self.langfuse: generation = self.trace.generation(name="chat_streamly", model=self.llm_name, input={"system": system, "history": history}) ans = "" - chat_streamly = self.mdl.chat_streamly + chat_partial = partial(self.mdl.chat_streamly, system, history, gen_conf) total_tokens = 0 if self.is_tools and self.mdl.is_tools: - chat_streamly = self.mdl.chat_streamly_with_tools + chat_partial = partial(self.mdl.chat_streamly_with_tools, system, history, gen_conf) - for txt in chat_streamly(system, history, gen_conf): + for txt in chat_partial(**kwargs): if isinstance(txt, int): total_tokens = txt if self.langfuse: @@ -398,8 +404,12 @@ class LLMBundle: if txt.endswith(""): ans = ans.rstrip("") + if not self.verbose_tool_use: + txt = re.sub(r".*?", "", txt, flags=re.DOTALL) + ans += txt yield ans + if total_tokens > 0: if not TenantLLMService.increase_usage(self.tenant_id, self.llm_type, txt, self.llm_name): logging.error("LLMBundle.chat_streamly can't update token usage for {}/CHAT llm_name: {}, content: {}".format(self.tenant_id, self.llm_name, txt)) diff --git a/api/utils/__init__.py b/api/utils/__init__.py index a6152d5fb..461340b63 100644 --- a/api/utils/__init__.py +++ b/api/utils/__init__.py @@ -15,6 +15,7 @@ # import base64 import datetime +import hashlib import io import json import os @@ -405,3 +406,7 @@ def download_img(url): def delta_seconds(date_string: str): dt = datetime.datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S") return (datetime.datetime.now() - dt).total_seconds() + + +def hash_str2int(line:str, mod: int=10 ** 8) -> int: + return int(hashlib.sha1(line.encode("utf-8")).hexdigest(), 16) % mod \ No newline at end of file diff --git a/graphrag/search.py b/graphrag/search.py index 38ce19712..d39f482d0 100644 --- a/graphrag/search.py +++ b/graphrag/search.py @@ -274,7 +274,7 @@ class KGSearch(Dealer): return { "chunk_id": get_uuid(), "content_ltks": "", - "content_with_weight": ents + relas + self._community_retrival_([n for n, _ in ents_from_query], filters, kb_ids, idxnms, + "content_with_weight": ents + relas + self._community_retrieval_([n for n, _ in ents_from_query], filters, kb_ids, idxnms, comm_topn, max_token), "doc_id": "", "docnm_kwd": "Related content in Knowledge Graph", @@ -288,7 +288,7 @@ class KGSearch(Dealer): "positions": [], } - def _community_retrival_(self, entities, condition, kb_ids, idxnms, topn, max_token): + def _community_retrieval_(self, entities, condition, kb_ids, idxnms, topn, max_token): ## Community retrieval fields = ["docnm_kwd", "content_with_weight"] odr = OrderByExpr() diff --git a/pyproject.toml b/pyproject.toml index 65297affc..be88a1247 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -102,7 +102,7 @@ dependencies = [ "tiktoken==0.7.0", "umap_learn==0.5.6", "vertexai==1.64.0", - "volcengine==1.0.146", + "volcengine==1.0.194", "voyageai==0.2.3", "webdriver-manager==4.0.1", "werkzeug==3.0.6", @@ -110,7 +110,7 @@ dependencies = [ "word2number==1.1", "xgboost==1.6.0", "xpinyin==0.7.6", - "yfinance==0.1.96", + "yfinance==0.2.65", "zhipuai==2.0.1", "google-generativeai>=0.8.1,<0.9.0", "python-docx>=1.1.2,<2.0.0", diff --git a/rag/app/book.py b/rag/app/book.py index 18357dbc0..e3954341d 100644 --- a/rag/app/book.py +++ b/rag/app/book.py @@ -69,6 +69,9 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, Since a book is long and not all the parts are useful, if it's a PDF, please setup the page ranges for every book in order eliminate negative effects and save elapsed computing time. """ + parser_config = kwargs.get( + "parser_config", { + "chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) doc = { "docnm_kwd": filename, "title_tks": rag_tokenizer.tokenize(re.sub(r"\.[a-zA-Z]+$", "", filename)) @@ -89,7 +92,7 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, elif re.search(r"\.pdf$", filename, re.IGNORECASE): pdf_parser = Pdf() - if kwargs.get("layout_recognize", "DeepDOC") == "Plain Text": + if parser_config.get("layout_recognize", "DeepDOC") == "Plain Text": pdf_parser = PlainParser() sections, tbls = pdf_parser(filename if not binary else binary, from_page=from_page, to_page=to_page, callback=callback) diff --git a/rag/app/email.py b/rag/app/email.py index 7f08dd41c..d8520e43d 100644 --- a/rag/app/email.py +++ b/rag/app/email.py @@ -40,7 +40,7 @@ def chunk( eng = lang.lower() == "english" # is_english(cks) parser_config = kwargs.get( "parser_config", - {"chunk_token_num": 128, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}, + {"chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}, ) doc = { "docnm_kwd": filename, diff --git a/rag/app/laws.py b/rag/app/laws.py index 1843079c0..185c66935 100644 --- a/rag/app/laws.py +++ b/rag/app/laws.py @@ -145,6 +145,9 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, """ Supported file formats are docx, pdf, txt. """ + parser_config = kwargs.get( + "parser_config", { + "chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) doc = { "docnm_kwd": filename, "title_tks": rag_tokenizer.tokenize(re.sub(r"\.[a-zA-Z]+$", "", filename)) @@ -163,7 +166,7 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, elif re.search(r"\.pdf$", filename, re.IGNORECASE): pdf_parser = Pdf() - if kwargs.get("layout_recognize", "DeepDOC") == "Plain Text": + if parser_config.get("layout_recognize", "DeepDOC") == "Plain Text": pdf_parser = PlainParser() for txt, poss in pdf_parser(filename if not binary else binary, from_page=from_page, to_page=to_page, callback=callback)[0]: diff --git a/rag/app/manual.py b/rag/app/manual.py index e73b13c0a..7fa395fe1 100644 --- a/rag/app/manual.py +++ b/rag/app/manual.py @@ -45,9 +45,6 @@ class Pdf(PdfParser): callback ) callback(msg="OCR finished ({:.2f}s)".format(timer() - start)) - # for bb in self.boxes: - # for b in bb: - # print(b) logging.debug("OCR: {}".format(timer() - start)) start = timer() @@ -177,6 +174,9 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, """ Only pdf is supported. """ + parser_config = kwargs.get( + "parser_config", { + "chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) pdf_parser = None doc = { "docnm_kwd": filename @@ -187,7 +187,7 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, eng = lang.lower() == "english" # pdf_parser.is_english if re.search(r"\.pdf$", filename, re.IGNORECASE): pdf_parser = Pdf() - if kwargs.get("layout_recognize", "DeepDOC") == "Plain Text": + if parser_config.get("layout_recognize", "DeepDOC") == "Plain Text": pdf_parser = PlainParser() sections, tbls = pdf_parser(filename if not binary else binary, from_page=from_page, to_page=to_page, callback=callback) @@ -222,7 +222,6 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, if lvl <= most_level and i > 0 and lvl != levels[i - 1]: sid += 1 sec_ids.append(sid) - # print(lvl, self.boxes[i]["text"], most_level, sid) sections = [(txt, sec_ids[i], poss) for i, (txt, _, poss) in enumerate(sections)] diff --git a/rag/app/naive.py b/rag/app/naive.py index bf8f3f3a9..06d0f3369 100644 --- a/rag/app/naive.py +++ b/rag/app/naive.py @@ -370,7 +370,7 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, is_english = lang.lower() == "english" # is_english(cks) parser_config = kwargs.get( "parser_config", { - "chunk_token_num": 128, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) + "chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) doc = { "docnm_kwd": filename, "title_tks": rag_tokenizer.tokenize(re.sub(r"\.[a-zA-Z]+$", "", filename)) diff --git a/rag/app/one.py b/rag/app/one.py index 4882233d3..77c9645c7 100644 --- a/rag/app/one.py +++ b/rag/app/one.py @@ -72,7 +72,9 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, Supported file formats are docx, pdf, excel, txt. One file forms a chunk which maintains original text order. """ - + parser_config = kwargs.get( + "parser_config", { + "chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) eng = lang.lower() == "english" # is_english(cks) if re.search(r"\.docx$", filename, re.IGNORECASE): @@ -85,7 +87,7 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, elif re.search(r"\.pdf$", filename, re.IGNORECASE): pdf_parser = Pdf() - if kwargs.get("layout_recognize", "DeepDOC") == "Plain Text": + if parser_config.get("layout_recognize", "DeepDOC") == "Plain Text": pdf_parser = PlainParser() sections, _ = pdf_parser( filename if not binary else binary, to_page=to_page, callback=callback) diff --git a/rag/app/paper.py b/rag/app/paper.py index 7b980eae8..c46f417a8 100644 --- a/rag/app/paper.py +++ b/rag/app/paper.py @@ -143,8 +143,11 @@ def chunk(filename, binary=None, from_page=0, to_page=100000, Only pdf is supported. The abstract of the paper will be sliced as an entire chunk, and will not be sliced partly. """ + parser_config = kwargs.get( + "parser_config", { + "chunk_token_num": 512, "delimiter": "\n!?。;!?", "layout_recognize": "DeepDOC"}) if re.search(r"\.pdf$", filename, re.IGNORECASE): - if kwargs.get("parser_config", {}).get("layout_recognize", "DeepDOC") == "Plain Text": + if parser_config.get("layout_recognize", "DeepDOC") == "Plain Text": pdf_parser = PlainParser() paper = { "title": filename, diff --git a/rag/llm/chat_model.py b/rag/llm/chat_model.py index 28ecbc20e..9ecd7a1f2 100644 --- a/rag/llm/chat_model.py +++ b/rag/llm/chat_model.py @@ -18,6 +18,7 @@ import json import logging import os import random +import re import time from abc import ABC from copy import deepcopy @@ -31,25 +32,33 @@ from dashscope import Generation from ollama import Client from openai import OpenAI from openai.lib.azure import AzureOpenAI +from strenum import StrEnum from zhipuai import ZhipuAI from rag.nlp import is_chinese, is_english from rag.utils import num_tokens_from_string # Error message constants -ERROR_PREFIX = "**ERROR**" -ERROR_RATE_LIMIT = "RATE_LIMIT_EXCEEDED" -ERROR_AUTHENTICATION = "AUTH_ERROR" -ERROR_INVALID_REQUEST = "INVALID_REQUEST" -ERROR_SERVER = "SERVER_ERROR" -ERROR_TIMEOUT = "TIMEOUT" -ERROR_CONNECTION = "CONNECTION_ERROR" -ERROR_MODEL = "MODEL_ERROR" -ERROR_CONTENT_FILTER = "CONTENT_FILTERED" -ERROR_QUOTA = "QUOTA_EXCEEDED" -ERROR_MAX_RETRIES = "MAX_RETRIES_EXCEEDED" -ERROR_GENERIC = "GENERIC_ERROR" +class LLMErrorCode(StrEnum): + ERROR_RATE_LIMIT = "RATE_LIMIT_EXCEEDED" + ERROR_AUTHENTICATION = "AUTH_ERROR" + ERROR_INVALID_REQUEST = "INVALID_REQUEST" + ERROR_SERVER = "SERVER_ERROR" + ERROR_TIMEOUT = "TIMEOUT" + ERROR_CONNECTION = "CONNECTION_ERROR" + ERROR_MODEL = "MODEL_ERROR" + ERROR_MAX_ROUNDS = "ERROR_MAX_ROUNDS" + ERROR_CONTENT_FILTER = "CONTENT_FILTERED" + ERROR_QUOTA = "QUOTA_EXCEEDED" + ERROR_MAX_RETRIES = "MAX_RETRIES_EXCEEDED" + ERROR_GENERIC = "GENERIC_ERROR" + +class ReActMode(StrEnum): + FUNCTION_CALL = "function_call" + REACT = "react" + +ERROR_PREFIX = "**ERROR**" LENGTH_NOTIFICATION_CN = "······\n由于大模型的上下文窗口大小限制,回答已经被大模型截断。" LENGTH_NOTIFICATION_EN = "...\nThe answer is truncated by your chosen LLM due to its limitation on context length." @@ -73,51 +82,78 @@ class Base(ABC): def _get_delay(self): """Calculate retry delay time""" - return self.base_delay + random.uniform(60, 150) + return self.base_delay * random.uniform(10, 150) def _classify_error(self, error): """Classify error based on error message content""" error_str = str(error).lower() - if "rate limit" in error_str or "429" in error_str or "tpm limit" in error_str or "too many requests" in error_str or "requests per minute" in error_str: - return ERROR_RATE_LIMIT - elif "auth" in error_str or "key" in error_str or "apikey" in error_str or "401" in error_str or "forbidden" in error_str or "permission" in error_str: - return ERROR_AUTHENTICATION - elif "invalid" in error_str or "bad request" in error_str or "400" in error_str or "format" in error_str or "malformed" in error_str or "parameter" in error_str: - return ERROR_INVALID_REQUEST - elif "server" in error_str or "502" in error_str or "503" in error_str or "504" in error_str or "500" in error_str or "unavailable" in error_str: - return ERROR_SERVER - elif "timeout" in error_str or "timed out" in error_str: - return ERROR_TIMEOUT - elif "connect" in error_str or "network" in error_str or "unreachable" in error_str or "dns" in error_str: - return ERROR_CONNECTION - elif "quota" in error_str or "capacity" in error_str or "credit" in error_str or "billing" in error_str or "limit" in error_str and "rate" not in error_str: - return ERROR_QUOTA - elif "filter" in error_str or "content" in error_str or "policy" in error_str or "blocked" in error_str or "safety" in error_str or "inappropriate" in error_str: - return ERROR_CONTENT_FILTER - elif "model" in error_str or "not found" in error_str or "does not exist" in error_str or "not available" in error_str: - return ERROR_MODEL - else: - return ERROR_GENERIC + keywords_mapping = [ + (["quota", "capacity", "credit", "billing", "balance", "欠费"], LLMErrorCode.ERROR_QUOTA), + (["rate limit", "429", "tpm limit", "too many requests", "requests per minute"], LLMErrorCode.ERROR_RATE_LIMIT), + (["auth", "key", "apikey", "401", "forbidden", "permission"], LLMErrorCode.ERROR_AUTHENTICATION), + (["invalid", "bad request", "400", "format", "malformed", "parameter"], LLMErrorCode.ERROR_INVALID_REQUEST), + (["server", "503", "502", "504", "500", "unavailable"], LLMErrorCode.ERROR_SERVER), + (["timeout", "timed out"], LLMErrorCode.ERROR_TIMEOUT), + (["connect", "network", "unreachable", "dns"], LLMErrorCode.ERROR_CONNECTION), + (["filter", "content", "policy", "blocked", "safety", "inappropriate"], LLMErrorCode.ERROR_CONTENT_FILTER), + (["model", "not found", "does not exist", "not available"], LLMErrorCode.ERROR_MODEL), + (["max rounds"], LLMErrorCode.ERROR_MODEL), + ] + for words, code in keywords_mapping: + if re.search("({})".format("|".join(words)), error_str): + return code + + return LLMErrorCode.ERROR_GENERIC def _clean_conf(self, gen_conf): if "max_tokens" in gen_conf: del gen_conf["max_tokens"] return gen_conf - def _chat(self, history, gen_conf): - response = self.client.chat.completions.create(model=self.model_name, messages=history, **gen_conf) + def _chat(self, history, gen_conf, **kwargs): + logging.info("[HISTORY]" + json.dumps(history, ensure_ascii=False, indent=2)) + if self.model_name.lower().find("qwen3") >=0: + kwargs["extra_body"] = {"enable_thinking": False} + response = self.client.chat.completions.create(model=self.model_name, messages=history, **gen_conf, **kwargs) if any([not response.choices, not response.choices[0].message, not response.choices[0].message.content]): return "", 0 ans = response.choices[0].message.content.strip() if response.choices[0].finish_reason == "length": - if is_chinese(ans): - ans += LENGTH_NOTIFICATION_CN - else: - ans += LENGTH_NOTIFICATION_EN + ans = self._length_stop(ans) return ans, self.total_token_count(response) + def _chat_streamly(self, history, gen_conf, **kwargs): + logging.info("[HISTORY STREAMLY]" + json.dumps(history, ensure_ascii=False, indent=4)) + reasoning_start = False + response = self.client.chat.completions.create(model=self.model_name, messages=history, stream=True, **gen_conf, stop=kwargs.get("stop")) + for resp in response: + if not resp.choices: + continue + if not resp.choices[0].delta.content: + resp.choices[0].delta.content = "" + if kwargs.get("with_reasoning", True) and hasattr(resp.choices[0].delta, "reasoning_content") and resp.choices[0].delta.reasoning_content: + ans = "" + if not reasoning_start: + reasoning_start = True + ans = "" + ans += resp.choices[0].delta.reasoning_content + "" + else: + reasoning_start = False + ans = resp.choices[0].delta.content + + tol = self.total_token_count(resp) + if not tol: + tol = num_tokens_from_string(resp.choices[0].delta.content) + + if resp.choices[0].finish_reason == "length": + if is_chinese(ans): + ans += LENGTH_NOTIFICATION_CN + else: + ans += LENGTH_NOTIFICATION_EN + yield ans, tol + def _length_stop(self, ans): if is_chinese([ans]): return ans + LENGTH_NOTIFICATION_CN @@ -127,22 +163,24 @@ class Base(ABC): logging.exception("OpenAI chat_with_tools") # Classify the error error_code = self._classify_error(e) + if attempt == self.max_retries: + error_code = LLMErrorCode.ERROR_MAX_RETRIES # Check if it's a rate limit error or server error and not the last attempt - should_retry = (error_code == ERROR_RATE_LIMIT or error_code == ERROR_SERVER) and attempt < self.max_retries - - if should_retry: - delay = self._get_delay() - logging.warning(f"Error: {error_code}. Retrying in {delay:.2f} seconds... (Attempt {attempt + 1}/{self.max_retries})") - time.sleep(delay) - else: - # For non-rate limit errors or the last attempt, return an error message - if attempt == self.max_retries: - error_code = ERROR_MAX_RETRIES + should_retry = (error_code == LLMErrorCode.ERROR_RATE_LIMIT or error_code == LLMErrorCode.ERROR_SERVER) + if not should_retry: return f"{ERROR_PREFIX}: {error_code} - {str(e)}" + delay = self._get_delay() + logging.warning(f"Error: {error_code}. Retrying in {delay:.2f} seconds... (Attempt {attempt + 1}/{self.max_retries})") + time.sleep(delay) + def _verbose_tool_use(self, name, args, res): - return "" + json.dumps({"name": name, "args": args, "result": res}, ensure_ascii=False, indent=2) + "" + return "" + json.dumps({ + "name": name, + "args": args, + "result": res + }, ensure_ascii=False, indent=2) + "" def _append_history(self, hist, tool_call, tool_res): hist.append( @@ -172,17 +210,14 @@ class Base(ABC): if not (toolcall_session and tools): return self.is_tools = True + self.toolcall_session = toolcall_session + self.tools = tools - for tool in tools: - self.toolcall_sessions[tool["function"]["name"]] = toolcall_session - self.tools.append(tool) - - def chat_with_tools(self, system: str, history: list, gen_conf: dict): + def chat_with_tools(self, system: str, history: list, gen_conf: dict={}): gen_conf = self._clean_conf(gen_conf) if system: history.insert(0, {"role": "system", "content": system}) - gen_conf = self._clean_conf(gen_conf) ans = "" tk_count = 0 hist = deepcopy(history) @@ -190,8 +225,9 @@ class Base(ABC): for attempt in range(self.max_retries + 1): history = hist try: - for _ in range(self.max_rounds * 2): - response = self.client.chat.completions.create(model=self.model_name, messages=history, tools=self.tools, **gen_conf) + for _ in range(self.max_rounds+1): + logging.info(f"{self.tools=}") + response = self.client.chat.completions.create(model=self.model_name, messages=history, tools=self.tools, tool_choice="auto", **gen_conf) tk_count += self.total_token_count(response) if any([not response.choices, not response.choices[0].message]): raise Exception(f"500 response structure error. Response: {response}") @@ -207,10 +243,11 @@ class Base(ABC): return ans, tk_count for tool_call in response.choices[0].message.tool_calls: + logging.info(f"Response {tool_call=}") name = tool_call.function.name try: args = json_repair.loads(tool_call.function.arguments) - tool_response = self.toolcall_sessions[name].tool_call(name, args) + tool_response = self.toolcall_session.tool_call(name, args) history = self._append_history(history, tool_call, tool_response) ans += self._verbose_tool_use(name, args, tool_response) except Exception as e: @@ -218,13 +255,20 @@ class Base(ABC): history.append({"role": "tool", "tool_call_id": tool_call.id, "content": f"Tool call error: \n{tool_call}\nException:\n" + str(e)}) ans += self._verbose_tool_use(name, {}, str(e)) + logging.warning( f"Exceed max rounds: {self.max_rounds}") + history.append({"role": "user", "content": f"Exceed max rounds: {self.max_rounds}"}) + response, token_count = self._chat(history, gen_conf) + ans += response + tk_count += token_count + return ans, tk_count except Exception as e: e = self._exceptions(e, attempt) if e: return e, tk_count + assert False, "Shouldn't be here." - def chat(self, system, history, gen_conf): + def chat(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) gen_conf = self._clean_conf(gen_conf) @@ -232,7 +276,7 @@ class Base(ABC): # Implement exponential backoff retry strategy for attempt in range(self.max_retries + 1): try: - return self._chat(history, gen_conf) + return self._chat(history, gen_conf, **kwargs) except Exception as e: e = self._exceptions(e, attempt) if e: @@ -253,7 +297,7 @@ class Base(ABC): return final_tool_calls - def chat_streamly_with_tools(self, system: str, history: list, gen_conf: dict): + def chat_streamly_with_tools(self, system: str, history: list, gen_conf: dict={}): gen_conf = self._clean_conf(gen_conf) tools = self.tools if system: @@ -265,9 +309,10 @@ class Base(ABC): for attempt in range(self.max_retries + 1): history = hist try: - for _ in range(self.max_rounds * 2): + for _ in range(self.max_rounds+1): reasoning_start = False - response = self.client.chat.completions.create(model=self.model_name, messages=history, stream=True, tools=tools, **gen_conf) + logging.info(f"{tools=}") + response = self.client.chat.completions.create(model=self.model_name, messages=history, stream=True, tools=tools, tool_choice="auto", **gen_conf) final_tool_calls = {} answer = "" for resp in response: @@ -319,7 +364,8 @@ class Base(ABC): name = tool_call.function.name try: args = json_repair.loads(tool_call.function.arguments) - tool_response = self.toolcall_session[name].tool_call(name, args) + yield self._verbose_tool_use(name, args, "Begin to call...") + tool_response = self.toolcall_session.tool_call(name, args) history = self._append_history(history, tool_call, tool_response) yield self._verbose_tool_use(name, args, tool_response) except Exception as e: @@ -327,51 +373,45 @@ class Base(ABC): history.append({"role": "tool", "tool_call_id": tool_call.id, "content": f"Tool call error: \n{tool_call}\nException:\n" + str(e)}) yield self._verbose_tool_use(name, {}, str(e)) + logging.warning( f"Exceed max rounds: {self.max_rounds}") + history.append({"role": "user", "content": f"Exceed max rounds: {self.max_rounds}"}) + response = self.client.chat.completions.create(model=self.model_name, messages=history, stream=True, **gen_conf) + for resp in response: + if any([not resp.choices, not resp.choices[0].delta, not hasattr(resp.choices[0].delta, "content")]): + raise Exception("500 response structure error.") + if not resp.choices[0].delta.content: + resp.choices[0].delta.content = "" + continue + tol = self.total_token_count(resp) + if not tol: + total_tokens += num_tokens_from_string(resp.choices[0].delta.content) + else: + total_tokens += tol + answer += resp.choices[0].delta.content + yield resp.choices[0].delta.content + + yield total_tokens + return + except Exception as e: e = self._exceptions(e, attempt) if e: + yield e yield total_tokens return - yield total_tokens + assert False, "Shouldn't be here." - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf: dict={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) gen_conf = self._clean_conf(gen_conf) ans = "" total_tokens = 0 - reasoning_start = False try: - response = self.client.chat.completions.create(model=self.model_name, messages=history, stream=True, **gen_conf) - for resp in response: - if not resp.choices: - continue - if not resp.choices[0].delta.content: - resp.choices[0].delta.content = "" - if hasattr(resp.choices[0].delta, "reasoning_content") and resp.choices[0].delta.reasoning_content: - ans = "" - if not reasoning_start: - reasoning_start = True - ans = "" - ans += resp.choices[0].delta.reasoning_content + "" - else: - reasoning_start = False - ans = resp.choices[0].delta.content - - tol = self.total_token_count(resp) - if not tol: - total_tokens += num_tokens_from_string(resp.choices[0].delta.content) - else: - total_tokens += tol - - if resp.choices[0].finish_reason == "length": - if is_chinese(ans): - ans += LENGTH_NOTIFICATION_CN - else: - ans += LENGTH_NOTIFICATION_EN - yield ans - + for delta_ans, tol in self._chat_streamly(history, gen_conf, **kwargs): + yield delta_ans + total_tokens += tol except openai.APIError as e: yield ans + "\n**ERROR**: " + str(e) @@ -514,7 +554,7 @@ class BaiChuanChat(Base): "top_p": gen_conf.get("top_p", 0.85), } - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): response = self.client.chat.completions.create( model=self.model_name, messages=history, @@ -529,7 +569,7 @@ class BaiChuanChat(Base): ans += LENGTH_NOTIFICATION_EN return ans, self.total_token_count(response) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) if "max_tokens" in gen_conf: @@ -614,7 +654,7 @@ class ZhipuChat(Base): return super().chat_with_tools(system, history, gen_conf) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) if "max_tokens" in gen_conf: @@ -626,6 +666,7 @@ class ZhipuChat(Base): ans = "" tk_count = 0 try: + logging.info(json.dumps(history, ensure_ascii=False, indent=2)) response = self.client.chat.completions.create(model=self.model_name, messages=history, stream=True, **gen_conf) for resp in response: if not resp.choices[0].delta.content: @@ -675,7 +716,7 @@ class OllamaChat(Base): options[k] = gen_conf[k] return options - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): # Calculate context size ctx_size = self._calculate_dynamic_ctx(history) @@ -685,7 +726,7 @@ class OllamaChat(Base): token_count = response.get("eval_count", 0) + response.get("prompt_eval_count", 0) return ans, token_count - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) if "max_tokens" in gen_conf: @@ -766,7 +807,7 @@ class LocalLLM(Base): yield answer + "\n**ERROR**: " + str(e) yield num_tokens_from_string(answer) - def chat(self, system, history, gen_conf): + def chat(self, system, history, gen_conf={}, **kwargs): if "max_tokens" in gen_conf: del gen_conf["max_tokens"] prompt = self._prepare_prompt(system, history, gen_conf) @@ -775,7 +816,7 @@ class LocalLLM(Base): total_tokens = next(chat_gen) return ans, total_tokens - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if "max_tokens" in gen_conf: del gen_conf["max_tokens"] prompt = self._prepare_prompt(system, history, gen_conf) @@ -894,7 +935,7 @@ class MistralChat(Base): del gen_conf[k] return gen_conf - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): response = self.client.chat(model=self.model_name, messages=history, **gen_conf) ans = response.choices[0].message.content if response.choices[0].finish_reason == "length": @@ -904,7 +945,7 @@ class MistralChat(Base): ans += LENGTH_NOTIFICATION_EN return ans, self.total_token_count(response) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) for k in list(gen_conf.keys()): @@ -913,7 +954,7 @@ class MistralChat(Base): ans = "" total_tokens = 0 try: - response = self.client.chat_stream(model=self.model_name, messages=history, **gen_conf) + response = self.client.chat_stream(model=self.model_name, messages=history, **gen_conf, **kwargs) for resp in response: if not resp.choices or not resp.choices[0].delta.content: continue @@ -957,7 +998,7 @@ class BedrockChat(Base): del gen_conf[k] return gen_conf - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): system = history[0]["content"] if history and history[0]["role"] == "system" else "" hist = [] for item in history: @@ -978,7 +1019,7 @@ class BedrockChat(Base): ans = response["output"]["message"]["content"][0]["text"] return ans, num_tokens_from_string(ans) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): from botocore.exceptions import ClientError for k in list(gen_conf.keys()): @@ -1036,7 +1077,7 @@ class GeminiChat(Base): del gen_conf[k] return gen_conf - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): from google.generativeai.types import content_types system = history[0]["content"] if history and history[0]["role"] == "system" else "" @@ -1059,7 +1100,7 @@ class GeminiChat(Base): ans = response.text return ans, response.usage_metadata.total_token_count - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): from google.generativeai.types import content_types gen_conf = self._clean_conf(gen_conf) @@ -1101,7 +1142,7 @@ class GroqChat(Base): del gen_conf[k] return gen_conf - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) for k in list(gen_conf.keys()): @@ -1229,7 +1270,7 @@ class CoHereChat(Base): response.meta.tokens.input_tokens + response.meta.tokens.output_tokens, ) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if system: history.insert(0, {"role": "system", "content": system}) if "max_tokens" in gen_conf: @@ -1348,7 +1389,7 @@ class ReplicateChat(Base): self.model_name = model_name self.client = Client(api_token=key) - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): system = history[0]["content"] if history and history[0]["role"] == "system" else "" prompt = "\n".join([item["role"] + ":" + item["content"] for item in history[-5:] if item["role"] != "system"]) response = self.client.run( @@ -1358,7 +1399,7 @@ class ReplicateChat(Base): ans = "".join(response) return ans, num_tokens_from_string(ans) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if "max_tokens" in gen_conf: del gen_conf["max_tokens"] prompt = "\n".join([item["role"] + ":" + item["content"] for item in history[-5:]]) @@ -1402,7 +1443,7 @@ class HunyuanChat(Base): _gen_conf["TopP"] = gen_conf["top_p"] return _gen_conf - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): from tencentcloud.hunyuan.v20230901 import models hist = [{k.capitalize(): v for k, v in item.items()} for item in history] @@ -1413,7 +1454,7 @@ class HunyuanChat(Base): ans = response.Choices[0].Message.Content return ans, response.Usage.TotalTokens - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): from tencentcloud.common.exception.tencent_cloud_sdk_exception import ( TencentCloudSDKException, ) @@ -1504,7 +1545,7 @@ class BaiduYiyanChat(Base): ans = response["result"] return ans, self.total_token_count(response) - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): gen_conf["penalty_score"] = ((gen_conf.get("presence_penalty", 0) + gen_conf.get("frequency_penalty", 0)) / 2) + 1 if "max_tokens" in gen_conf: del gen_conf["max_tokens"] @@ -1588,7 +1629,7 @@ class GoogleChat(Base): del gen_conf[k] return gen_conf - def _chat(self, history, gen_conf): + def _chat(self, history, gen_conf={}, **kwargs): system = history[0]["content"] if history and history[0]["role"] == "system" else "" if "claude" in self.model_name: response = self.client.messages.create( @@ -1626,7 +1667,7 @@ class GoogleChat(Base): ans = response.text return ans, response.usage_metadata.total_token_count - def chat_streamly(self, system, history, gen_conf): + def chat_streamly(self, system, history, gen_conf={}, **kwargs): if "claude" in self.model_name: if "max_tokens" in gen_conf: del gen_conf["max_tokens"] diff --git a/rag/llm/cv_model.py b/rag/llm/cv_model.py index b465661de..707f01302 100644 --- a/rag/llm/cv_model.py +++ b/rag/llm/cv_model.py @@ -14,30 +14,30 @@ # limitations under the License. # import base64 -import io import json import os from abc import ABC +from copy import deepcopy from io import BytesIO from urllib.parse import urljoin - import requests -from ollama import Client from openai import OpenAI from openai.lib.azure import AzureOpenAI -from PIL import Image from zhipuai import ZhipuAI - -from api.utils import get_uuid -from api.utils.file_utils import get_project_base_directory from rag.nlp import is_english from rag.prompts import vision_llm_describe_prompt from rag.utils import num_tokens_from_string class Base(ABC): - def __init__(self, key, model_name): - pass + def __init__(self, **kwargs): + # Configure retry parameters + self.max_retries = kwargs.get("max_retries", int(os.environ.get("LLM_MAX_RETRIES", 5))) + self.base_delay = kwargs.get("retry_interval", float(os.environ.get("LLM_BASE_DELAY", 2.0))) + self.max_rounds = kwargs.get("max_rounds", 5) + self.is_tools = False + self.tools = [] + self.toolcall_sessions = {} def describe(self, image): raise NotImplementedError("Please implement encode method!") @@ -45,59 +45,66 @@ class Base(ABC): def describe_with_prompt(self, image, prompt=None): raise NotImplementedError("Please implement encode method!") - def chat(self, system, history, gen_conf, image=""): + def _form_history(self, system, history, images=[]): + hist = [] if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - try: - for his in history: - if his["role"] == "user": - his["content"] = self.chat_prompt(his["content"], image) + hist.append({"role": "system", "content": system}) + for h in history: + if images and h["role"] == "user": + h["content"] = self._image_prompt(h["content"], images) + images = [] + hist.append(h) + return hist + def _image_prompt(self, text, images): + if not images: + return text + pmpt = [{"type": "text", "text": text}] + for img in images: + pmpt.append({ + "type": "image_url", + "image_url": { + "url": f"data:image/jpeg;base64,{img}" if img[:4] != "data" else img + } + }) + return pmpt + + def chat(self, system, history, gen_conf, images=[], **kwargs): + try: response = self.client.chat.completions.create( model=self.model_name, - messages=history, - temperature=gen_conf.get("temperature", 0.3), - top_p=gen_conf.get("top_p", 0.7), + messages=self._form_history(system, history, images) ) return response.choices[0].message.content.strip(), response.usage.total_tokens except Exception as e: return "**ERROR**: " + str(e), 0 - def chat_streamly(self, system, history, gen_conf, image=""): - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - + def chat_streamly(self, system, history, gen_conf, images=[], **kwargs): ans = "" tk_count = 0 try: - for his in history: - if his["role"] == "user": - his["content"] = self.chat_prompt(his["content"], image) - response = self.client.chat.completions.create( model=self.model_name, - messages=history, - temperature=gen_conf.get("temperature", 0.3), - top_p=gen_conf.get("top_p", 0.7), - stream=True, + messages=self._form_history(system, history, images), + stream=True ) for resp in response: if not resp.choices[0].delta.content: continue delta = resp.choices[0].delta.content - ans += delta + ans = delta if resp.choices[0].finish_reason == "length": ans += "...\nFor the content length reason, it stopped, continue?" if is_english([ans]) else "······\n由于长度的原因,回答被截断了,要继续吗?" - tk_count = resp.usage.total_tokens if resp.choices[0].finish_reason == "stop": - tk_count = resp.usage.total_tokens + tk_count += resp.usage.total_tokens yield ans except Exception as e: yield ans + "\n**ERROR**: " + str(e) yield tk_count - def image2base64(self, image): + @staticmethod + def image2base64(image): if isinstance(image, bytes): return base64.b64encode(image).decode("utf-8") if isinstance(image, BytesIO): @@ -113,17 +120,12 @@ class Base(ABC): return [ { "role": "user", - "content": [ - { - "type": "image_url", - "image_url": {"url": f"data:image/jpeg;base64,{b64}"}, - }, - { - "text": "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" - if self.lang.lower() == "chinese" - else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out.", - }, - ], + "content": self._image_prompt( + "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" + if self.lang.lower() == "chinese" + else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out.", + b64 + ) } ] @@ -131,67 +133,40 @@ class Base(ABC): return [ { "role": "user", - "content": [ - { - "type": "image_url", - "image_url": {"url": f"data:image/jpeg;base64,{b64}"}, - }, - { - "type": "text", - "text": prompt if prompt else vision_llm_describe_prompt(), - }, - ], + "content": self._image_prompt(prompt if prompt else vision_llm_describe_prompt(), b64) } ] - def chat_prompt(self, text, b64): - return [ - { - "type": "image_url", - "image_url": { - "url": f"data:image/jpeg;base64,{b64}", - }, - }, - {"type": "text", "text": text}, - ] - class GptV4(Base): _FACTORY_NAME = "OpenAI" - def __init__(self, key, model_name="gpt-4-vision-preview", lang="Chinese", base_url="https://api.openai.com/v1"): + def __init__(self, key, model_name="gpt-4-vision-preview", lang="Chinese", base_url="https://api.openai.com/v1", **kwargs): if not base_url: base_url = "https://api.openai.com/v1" self.client = OpenAI(api_key=key, base_url=base_url) self.model_name = model_name self.lang = lang + super().__init__(**kwargs) def describe(self, image): b64 = self.image2base64(image) - prompt = self.prompt(b64) - for i in range(len(prompt)): - for c in prompt[i]["content"]: - if "text" in c: - c["type"] = "text" - res = self.client.chat.completions.create( model=self.model_name, - messages=prompt, + messages=self.prompt(b64), ) return res.choices[0].message.content.strip(), res.usage.total_tokens def describe_with_prompt(self, image, prompt=None): b64 = self.image2base64(image) - vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) - res = self.client.chat.completions.create( model=self.model_name, - messages=vision_prompt, + messages=self.vision_llm_prompt(b64, prompt), ) return res.choices[0].message.content.strip(), res.usage.total_tokens -class AzureGptV4(Base): +class AzureGptV4(GptV4): _FACTORY_NAME = "Azure-OpenAI" def __init__(self, key, model_name, lang="Chinese", **kwargs): @@ -200,283 +175,229 @@ class AzureGptV4(Base): self.client = AzureOpenAI(api_key=api_key, azure_endpoint=kwargs["base_url"], api_version=api_version) self.model_name = model_name self.lang = lang - - def describe(self, image): - b64 = self.image2base64(image) - prompt = self.prompt(b64) - for i in range(len(prompt)): - for c in prompt[i]["content"]: - if "text" in c: - c["type"] = "text" - - res = self.client.chat.completions.create(model=self.model_name, messages=prompt) - return res.choices[0].message.content.strip(), res.usage.total_tokens - - def describe_with_prompt(self, image, prompt=None): - b64 = self.image2base64(image) - vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) - - res = self.client.chat.completions.create( - model=self.model_name, - messages=vision_prompt, - ) - return res.choices[0].message.content.strip(), res.usage.total_tokens + Base.__init__(self, **kwargs) -class xAICV(Base): +class xAICV(GptV4): _FACTORY_NAME = "xAI" - def __init__(self, key, model_name="grok-3", base_url=None, **kwargs): + def __init__(self, key, model_name="grok-3", lang="Chinese", base_url=None, **kwargs): if not base_url: base_url = "https://api.x.ai/v1" - super().__init__(key, model_name, base_url=base_url, **kwargs) - return + super().__init__(key, model_name, lang=lang, base_url=base_url, **kwargs) -class QWenCV(Base): +class QWenCV(GptV4): _FACTORY_NAME = "Tongyi-Qianwen" - def __init__(self, key, model_name="qwen-vl-chat-v1", lang="Chinese", **kwargs): - import dashscope - - dashscope.api_key = key - self.model_name = model_name - self.lang = lang - - def prompt(self, binary): - # stupid as hell - tmp_dir = get_project_base_directory("tmp") - if not os.path.exists(tmp_dir): - os.makedirs(tmp_dir, exist_ok=True) - path = os.path.join(tmp_dir, "%s.jpg" % get_uuid()) - Image.open(io.BytesIO(binary)).save(path) - return [ - { - "role": "user", - "content": [ - {"image": f"file://{path}"}, - { - "text": "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" - if self.lang.lower() == "chinese" - else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out.", - }, - ], - } - ] - - def vision_llm_prompt(self, binary, prompt=None): - # stupid as hell - tmp_dir = get_project_base_directory("tmp") - if not os.path.exists(tmp_dir): - os.makedirs(tmp_dir, exist_ok=True) - path = os.path.join(tmp_dir, "%s.jpg" % get_uuid()) - Image.open(io.BytesIO(binary)).save(path) - - return [ - { - "role": "user", - "content": [ - {"image": f"file://{path}"}, - { - "text": prompt if prompt else vision_llm_describe_prompt(), - }, - ], - } - ] - - def chat_prompt(self, text, b64): - return [ - {"image": f"{b64}"}, - {"text": text}, - ] - - def describe(self, image): - from http import HTTPStatus - - from dashscope import MultiModalConversation - - response = MultiModalConversation.call(model=self.model_name, messages=self.prompt(image)) - if response.status_code == HTTPStatus.OK: - return response.output.choices[0]["message"]["content"][0]["text"], response.usage.output_tokens - return response.message, 0 - - def describe_with_prompt(self, image, prompt=None): - from http import HTTPStatus - - from dashscope import MultiModalConversation - - vision_prompt = self.vision_llm_prompt(image, prompt) if prompt else self.vision_llm_prompt(image) - response = MultiModalConversation.call(model=self.model_name, messages=vision_prompt) - if response.status_code == HTTPStatus.OK: - return response.output.choices[0]["message"]["content"][0]["text"], response.usage.output_tokens - return response.message, 0 - - def chat(self, system, history, gen_conf, image=""): - from http import HTTPStatus - - from dashscope import MultiModalConversation - - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - - for his in history: - if his["role"] == "user": - his["content"] = self.chat_prompt(his["content"], image) - response = MultiModalConversation.call( - model=self.model_name, - messages=history, - temperature=gen_conf.get("temperature", 0.3), - top_p=gen_conf.get("top_p", 0.7), - ) - - ans = "" - tk_count = 0 - if response.status_code == HTTPStatus.OK: - ans = response.output.choices[0]["message"]["content"] - if isinstance(ans, list): - ans = ans[0]["text"] if ans else "" - tk_count += response.usage.total_tokens - if response.output.choices[0].get("finish_reason", "") == "length": - ans += "...\nFor the content length reason, it stopped, continue?" if is_english([ans]) else "······\n由于长度的原因,回答被截断了,要继续吗?" - return ans, tk_count - - return "**ERROR**: " + response.message, tk_count - - def chat_streamly(self, system, history, gen_conf, image=""): - from http import HTTPStatus - - from dashscope import MultiModalConversation - - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - - for his in history: - if his["role"] == "user": - his["content"] = self.chat_prompt(his["content"], image) - - ans = "" - tk_count = 0 - try: - response = MultiModalConversation.call( - model=self.model_name, - messages=history, - temperature=gen_conf.get("temperature", 0.3), - top_p=gen_conf.get("top_p", 0.7), - stream=True, - ) - for resp in response: - if resp.status_code == HTTPStatus.OK: - cnt = resp.output.choices[0]["message"]["content"] - if isinstance(cnt, list): - cnt = cnt[0]["text"] if ans else "" - ans += cnt - tk_count = resp.usage.total_tokens - if resp.output.choices[0].get("finish_reason", "") == "length": - ans += "...\nFor the content length reason, it stopped, continue?" if is_english([ans]) else "······\n由于长度的原因,回答被截断了,要继续吗?" - yield ans - else: - yield ans + "\n**ERROR**: " + resp.message if str(resp.message).find("Access") < 0 else "Out of credit. Please set the API key in **settings > Model providers.**" - except Exception as e: - yield ans + "\n**ERROR**: " + str(e) - - yield tk_count + def __init__(self, key, model_name="qwen-vl-chat-v1", lang="Chinese", base_url=None, **kwargs): + if not base_url: + base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1" + super().__init__(key, model_name, lang=lang, base_url=base_url, **kwargs) -class Zhipu4V(Base): +class HunyuanCV(GptV4): + _FACTORY_NAME = "Tencent Hunyuan" + + def __init__(self, key, model_name, lang="Chinese", base_url=None, **kwargs): + if not base_url: + base_url = "https://api.hunyuan.cloud.tencent.com/v1" + super().__init__(key, model_name, lang=lang, base_url=base_url, **kwargs) + + +class Zhipu4V(GptV4): _FACTORY_NAME = "ZHIPU-AI" def __init__(self, key, model_name="glm-4v", lang="Chinese", **kwargs): self.client = ZhipuAI(api_key=key) self.model_name = model_name self.lang = lang + Base.__init__(self, **kwargs) + + +class StepFunCV(GptV4): + _FACTORY_NAME = "StepFun" + + def __init__(self, key, model_name="step-1v-8k", lang="Chinese", base_url="https://api.stepfun.com/v1", **kwargs): + if not base_url: + base_url = "https://api.stepfun.com/v1" + self.client = OpenAI(api_key=key, base_url=base_url) + self.model_name = model_name + self.lang = lang + Base.__init__(self, **kwargs) + + +class LmStudioCV(GptV4): + _FACTORY_NAME = "LM-Studio" + + def __init__(self, key, model_name, lang="Chinese", base_url="", **kwargs): + if not base_url: + raise ValueError("Local llm url cannot be None") + base_url = urljoin(base_url, "v1") + self.client = OpenAI(api_key="lm-studio", base_url=base_url) + self.model_name = model_name + self.lang = lang + Base.__init__(self, **kwargs) + + +class OpenAI_APICV(GptV4): + _FACTORY_NAME = ["VLLM", "OpenAI-API-Compatible"] + + def __init__(self, key, model_name, lang="Chinese", base_url="", **kwargs): + if not base_url: + raise ValueError("url cannot be None") + base_url = urljoin(base_url, "v1") + self.client = OpenAI(api_key=key, base_url=base_url) + self.model_name = model_name.split("___")[0] + self.lang = lang + Base.__init__(self, **kwargs) + + +class TogetherAICV(GptV4): + _FACTORY_NAME = "TogetherAI" + + def __init__(self, key, model_name, lang="Chinese", base_url="https://api.together.xyz/v1", **kwargs): + if not base_url: + base_url = "https://api.together.xyz/v1" + super().__init__(key, model_name, lang, base_url, **kwargs) + + +class YiCV(GptV4): + _FACTORY_NAME = "01.AI" + + def __init__( + self, + key, + model_name, + lang="Chinese", + base_url="https://api.lingyiwanwu.com/v1", **kwargs + ): + if not base_url: + base_url = "https://api.lingyiwanwu.com/v1" + super().__init__(key, model_name, lang, base_url, **kwargs) + + +class SILICONFLOWCV(GptV4): + _FACTORY_NAME = "SILICONFLOW" + + def __init__( + self, + key, + model_name, + lang="Chinese", + base_url="https://api.siliconflow.cn/v1", **kwargs + ): + if not base_url: + base_url = "https://api.siliconflow.cn/v1" + super().__init__(key, model_name, lang, base_url, **kwargs) + + +class OpenRouterCV(GptV4): + _FACTORY_NAME = "OpenRouter" + + def __init__( + self, + key, + model_name, + lang="Chinese", + base_url="https://openrouter.ai/api/v1", **kwargs + ): + if not base_url: + base_url = "https://openrouter.ai/api/v1" + self.client = OpenAI(api_key=key, base_url=base_url) + self.model_name = model_name + self.lang = lang + Base.__init__(self, **kwargs) + + +class LocalAICV(GptV4): + _FACTORY_NAME = "LocalAI" + + def __init__(self, key, model_name, base_url, lang="Chinese", **kwargs): + if not base_url: + raise ValueError("Local cv model url cannot be None") + base_url = urljoin(base_url, "v1") + self.client = OpenAI(api_key="empty", base_url=base_url) + self.model_name = model_name.split("___")[0] + self.lang = lang + Base.__init__(self, **kwargs) + + +class XinferenceCV(GptV4): + _FACTORY_NAME = "Xinference" + + def __init__(self, key, model_name="", lang="Chinese", base_url="", **kwargs): + base_url = urljoin(base_url, "v1") + self.client = OpenAI(api_key=key, base_url=base_url) + self.model_name = model_name + self.lang = lang + Base.__init__(self, **kwargs) + + +class GPUStackCV(GptV4): + _FACTORY_NAME = "GPUStack" + + def __init__(self, key, model_name, lang="Chinese", base_url="", **kwargs): + if not base_url: + raise ValueError("Local llm url cannot be None") + base_url = urljoin(base_url, "v1") + self.client = OpenAI(api_key=key, base_url=base_url) + self.model_name = model_name + self.lang = lang + Base.__init__(self, **kwargs) + + +class LocalCV(Base): + _FACTORY_NAME = "Moonshot" + + def __init__(self, key, model_name="glm-4v", lang="Chinese", **kwargs): + pass def describe(self, image): - b64 = self.image2base64(image) - - prompt = self.prompt(b64) - prompt[0]["content"][1]["type"] = "text" - - res = self.client.chat.completions.create( - model=self.model_name, - messages=prompt, - ) - return res.choices[0].message.content.strip(), res.usage.total_tokens - - def describe_with_prompt(self, image, prompt=None): - b64 = self.image2base64(image) - vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) - - res = self.client.chat.completions.create(model=self.model_name, messages=vision_prompt) - return res.choices[0].message.content.strip(), res.usage.total_tokens - - def chat(self, system, history, gen_conf, image=""): - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - try: - for his in history: - if his["role"] == "user": - his["content"] = self.chat_prompt(his["content"], image) - - response = self.client.chat.completions.create( - model=self.model_name, - messages=history, - temperature=gen_conf.get("temperature", 0.3), - top_p=gen_conf.get("top_p", 0.7), - ) - return response.choices[0].message.content.strip(), response.usage.total_tokens - except Exception as e: - return "**ERROR**: " + str(e), 0 - - def chat_streamly(self, system, history, gen_conf, image=""): - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - - ans = "" - tk_count = 0 - try: - for his in history: - if his["role"] == "user": - his["content"] = self.chat_prompt(his["content"], image) - - response = self.client.chat.completions.create( - model=self.model_name, - messages=history, - temperature=gen_conf.get("temperature", 0.3), - top_p=gen_conf.get("top_p", 0.7), - stream=True, - ) - for resp in response: - if not resp.choices[0].delta.content: - continue - delta = resp.choices[0].delta.content - ans += delta - if resp.choices[0].finish_reason == "length": - ans += "...\nFor the content length reason, it stopped, continue?" if is_english([ans]) else "······\n由于长度的原因,回答被截断了,要继续吗?" - tk_count = resp.usage.total_tokens - if resp.choices[0].finish_reason == "stop": - tk_count = resp.usage.total_tokens - yield ans - except Exception as e: - yield ans + "\n**ERROR**: " + str(e) - - yield tk_count + return "", 0 class OllamaCV(Base): _FACTORY_NAME = "Ollama" def __init__(self, key, model_name, lang="Chinese", **kwargs): + from ollama import Client self.client = Client(host=kwargs["base_url"]) self.model_name = model_name self.lang = lang self.keep_alive = kwargs.get("ollama_keep_alive", int(os.environ.get("OLLAMA_KEEP_ALIVE", -1))) + Base.__init__(self, **kwargs) + + def _clean_conf(self, gen_conf): + options = {} + if "temperature" in gen_conf: + options["temperature"] = gen_conf["temperature"] + if "top_p" in gen_conf: + options["top_k"] = gen_conf["top_p"] + if "presence_penalty" in gen_conf: + options["presence_penalty"] = gen_conf["presence_penalty"] + if "frequency_penalty" in gen_conf: + options["frequency_penalty"] = gen_conf["frequency_penalty"] + return options + + def _form_history(self, system, history, images=[]): + hist = deepcopy(history) + if system and hist[0]["role"] == "user": + hist.insert(0, {"role": "system", "content": system}) + if not images: + return hist + for his in hist: + if his["role"] == "user": + his["images"] = images + break + return hist def describe(self, image): prompt = self.prompt("") try: response = self.client.generate( model=self.model_name, - prompt=prompt[0]["content"][1]["text"], + prompt=prompt[0]["content"][0]["text"], images=[image], ) ans = response["response"].strip() @@ -489,7 +410,7 @@ class OllamaCV(Base): try: response = self.client.generate( model=self.model_name, - prompt=vision_prompt[0]["content"][1]["text"], + prompt=vision_prompt[0]["content"][0]["text"], images=[image], ) ans = response["response"].strip() @@ -497,28 +418,13 @@ class OllamaCV(Base): except Exception as e: return "**ERROR**: " + str(e), 0 - def chat(self, system, history, gen_conf, image=""): - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - + def chat(self, system, history, gen_conf, images=[]): try: - for his in history: - if his["role"] == "user": - his["images"] = [image] - options = {} - if "temperature" in gen_conf: - options["temperature"] = gen_conf["temperature"] - if "top_p" in gen_conf: - options["top_k"] = gen_conf["top_p"] - if "presence_penalty" in gen_conf: - options["presence_penalty"] = gen_conf["presence_penalty"] - if "frequency_penalty" in gen_conf: - options["frequency_penalty"] = gen_conf["frequency_penalty"] response = self.client.chat( model=self.model_name, - messages=history, - options=options, - keep_alive=self.keep_alive, + messages=self._form_history(system, history, images), + options=self._clean_conf(gen_conf), + keep_alive=self.keep_alive ) ans = response["message"]["content"].strip() @@ -526,79 +432,26 @@ class OllamaCV(Base): except Exception as e: return "**ERROR**: " + str(e), 0 - def chat_streamly(self, system, history, gen_conf, image=""): - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - - for his in history: - if his["role"] == "user": - his["images"] = [image] - options = {} - if "temperature" in gen_conf: - options["temperature"] = gen_conf["temperature"] - if "top_p" in gen_conf: - options["top_k"] = gen_conf["top_p"] - if "presence_penalty" in gen_conf: - options["presence_penalty"] = gen_conf["presence_penalty"] - if "frequency_penalty" in gen_conf: - options["frequency_penalty"] = gen_conf["frequency_penalty"] + def chat_streamly(self, system, history, gen_conf, images=[]): ans = "" try: response = self.client.chat( model=self.model_name, - messages=history, + messages=self._form_history(system, history, images), stream=True, - options=options, - keep_alive=self.keep_alive, + options=self._clean_conf(gen_conf), + keep_alive=self.keep_alive ) for resp in response: if resp["done"]: yield resp.get("prompt_eval_count", 0) + resp.get("eval_count", 0) - ans += resp["message"]["content"] + ans = resp["message"]["content"] yield ans except Exception as e: yield ans + "\n**ERROR**: " + str(e) yield 0 -class LocalAICV(GptV4): - _FACTORY_NAME = "LocalAI" - - def __init__(self, key, model_name, base_url, lang="Chinese"): - if not base_url: - raise ValueError("Local cv model url cannot be None") - base_url = urljoin(base_url, "v1") - self.client = OpenAI(api_key="empty", base_url=base_url) - self.model_name = model_name.split("___")[0] - self.lang = lang - - -class XinferenceCV(Base): - _FACTORY_NAME = "Xinference" - - def __init__(self, key, model_name="", lang="Chinese", base_url=""): - base_url = urljoin(base_url, "v1") - self.client = OpenAI(api_key=key, base_url=base_url) - self.model_name = model_name - self.lang = lang - - def describe(self, image): - b64 = self.image2base64(image) - - res = self.client.chat.completions.create(model=self.model_name, messages=self.prompt(b64)) - return res.choices[0].message.content.strip(), res.usage.total_tokens - - def describe_with_prompt(self, image, prompt=None): - b64 = self.image2base64(image) - vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) - - res = self.client.chat.completions.create( - model=self.model_name, - messages=vision_prompt, - ) - return res.choices[0].message.content.strip(), res.usage.total_tokens - - class GeminiCV(Base): _FACTORY_NAME = "Gemini" @@ -611,6 +464,17 @@ class GeminiCV(Base): self.model = GenerativeModel(model_name=self.model_name) self.model._client = _client self.lang = lang + Base.__init__(self, **kwargs) + + def _form_history(self, system, history, images=[]): + hist = [] + if system: + hist.append({"role": "user", "parts": [system, history[0]["content"]]}) + for img in images: + hist[0]["parts"].append(("data:image/jpeg;base64," + img) if img[:4]!="data" else img) + for h in history[1:]: + hist.append({"role": "user" if h["role"]=="user" else "model", "parts": [h["content"]]}) + return hist def describe(self, image): from PIL.Image import open @@ -638,49 +502,23 @@ class GeminiCV(Base): ) return res.text, res.usage_metadata.total_token_count - def chat(self, system, history, gen_conf, image=""): + def chat(self, system, history, gen_conf, images=[]): from transformers import GenerationConfig - - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] try: - for his in history: - if his["role"] == "assistant": - his["role"] = "model" - his["parts"] = [his["content"]] - his.pop("content") - if his["role"] == "user": - his["parts"] = [his["content"]] - his.pop("content") - history[-1]["parts"].append("data:image/jpeg;base64," + image) - - response = self.model.generate_content(history, generation_config=GenerationConfig(temperature=gen_conf.get("temperature", 0.3), top_p=gen_conf.get("top_p", 0.7))) - + response = self.model.generate_content( + self._form_history(system, history, images), + generation_config=GenerationConfig(temperature=gen_conf.get("temperature", 0.3), top_p=gen_conf.get("top_p", 0.7))) ans = response.text return ans, response.usage_metadata.total_token_count except Exception as e: return "**ERROR**: " + str(e), 0 - def chat_streamly(self, system, history, gen_conf, image=""): + def chat_streamly(self, system, history, gen_conf, images=[]): from transformers import GenerationConfig - - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - ans = "" try: - for his in history: - if his["role"] == "assistant": - his["role"] = "model" - his["parts"] = [his["content"]] - his.pop("content") - if his["role"] == "user": - his["parts"] = [his["content"]] - his.pop("content") - history[-1]["parts"].append("data:image/jpeg;base64," + image) - response = self.model.generate_content( - history, + self._form_history(system, history, images), generation_config=GenerationConfig(temperature=gen_conf.get("temperature", 0.3), top_p=gen_conf.get("top_p", 0.7)), stream=True, ) @@ -688,7 +526,7 @@ class GeminiCV(Base): for resp in response: if not resp.text: continue - ans += resp.text + ans = resp.text yield ans except Exception as e: yield ans + "\n**ERROR**: " + str(e) @@ -696,33 +534,6 @@ class GeminiCV(Base): yield response._chunks[-1].usage_metadata.total_token_count -class OpenRouterCV(GptV4): - _FACTORY_NAME = "OpenRouter" - - def __init__( - self, - key, - model_name, - lang="Chinese", - base_url="https://openrouter.ai/api/v1", - ): - if not base_url: - base_url = "https://openrouter.ai/api/v1" - self.client = OpenAI(api_key=key, base_url=base_url) - self.model_name = model_name - self.lang = lang - - -class LocalCV(Base): - _FACTORY_NAME = "Moonshot" - - def __init__(self, key, model_name="glm-4v", lang="Chinese", **kwargs): - pass - - def describe(self, image): - return "", 0 - - class NvidiaCV(Base): _FACTORY_NAME = "NVIDIA" @@ -731,7 +542,7 @@ class NvidiaCV(Base): key, model_name, lang="Chinese", - base_url="https://ai.api.nvidia.com/v1/vlm", + base_url="https://ai.api.nvidia.com/v1/vlm", **kwargs ): if not base_url: base_url = ("https://ai.api.nvidia.com/v1/vlm",) @@ -742,6 +553,15 @@ class NvidiaCV(Base): else: self.base_url = urljoin(f"{base_url}/community", llm_name.replace("-v1.6", "16")) self.key = key + Base.__init__(self, **kwargs) + + def _image_prompt(self, text, images): + if not images: + return text + htmls = "" + for img in images: + htmls += ' '.format(f"data:image/jpeg;base64,{img}" if img[:4] != "data" else img) + return text + htmls def describe(self, image): b64 = self.image2base64(image) @@ -760,10 +580,7 @@ class NvidiaCV(Base): response["usage"]["total_tokens"], ) - def describe_with_prompt(self, image, prompt=None): - b64 = self.image2base64(image) - vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) - + def _request(self, msg, gen_conf={}): response = requests.post( url=self.base_url, headers={ @@ -772,193 +589,46 @@ class NvidiaCV(Base): "Authorization": f"Bearer {self.key}", }, json={ - "messages": vision_prompt, + "messages": msg, **gen_conf }, ) - response = response.json() + return response.json() + + def describe_with_prompt(self, image, prompt=None): + b64 = self.image2base64(image) + vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) + response = self._request(vision_prompt) return ( response["choices"][0]["message"]["content"].strip(), response["usage"]["total_tokens"], ) - def prompt(self, b64): - return [ - { - "role": "user", - "content": ( - "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" - if self.lang.lower() == "chinese" - else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out." - ) - + f' ', - } - ] - - def vision_llm_prompt(self, b64, prompt=None): - return [ - { - "role": "user", - "content": (prompt if prompt else vision_llm_describe_prompt()) + f' ', - } - ] - - def chat_prompt(self, text, b64): - return [ - { - "role": "user", - "content": text + f' ', - } - ] - - -class StepFunCV(GptV4): - _FACTORY_NAME = "StepFun" - - def __init__(self, key, model_name="step-1v-8k", lang="Chinese", base_url="https://api.stepfun.com/v1"): - if not base_url: - base_url = "https://api.stepfun.com/v1" - self.client = OpenAI(api_key=key, base_url=base_url) - self.model_name = model_name - self.lang = lang - - -class LmStudioCV(GptV4): - _FACTORY_NAME = "LM-Studio" - - def __init__(self, key, model_name, lang="Chinese", base_url=""): - if not base_url: - raise ValueError("Local llm url cannot be None") - base_url = urljoin(base_url, "v1") - self.client = OpenAI(api_key="lm-studio", base_url=base_url) - self.model_name = model_name - self.lang = lang - - -class OpenAI_APICV(GptV4): - _FACTORY_NAME = ["VLLM", "OpenAI-API-Compatible"] - - def __init__(self, key, model_name, lang="Chinese", base_url=""): - if not base_url: - raise ValueError("url cannot be None") - base_url = urljoin(base_url, "v1") - self.client = OpenAI(api_key=key, base_url=base_url) - self.model_name = model_name.split("___")[0] - self.lang = lang - - -class TogetherAICV(GptV4): - _FACTORY_NAME = "TogetherAI" - - def __init__(self, key, model_name, lang="Chinese", base_url="https://api.together.xyz/v1"): - if not base_url: - base_url = "https://api.together.xyz/v1" - super().__init__(key, model_name, lang, base_url) - - -class YiCV(GptV4): - _FACTORY_NAME = "01.AI" - - def __init__( - self, - key, - model_name, - lang="Chinese", - base_url="https://api.lingyiwanwu.com/v1", - ): - if not base_url: - base_url = "https://api.lingyiwanwu.com/v1" - super().__init__(key, model_name, lang, base_url) - - -class SILICONFLOWCV(GptV4): - _FACTORY_NAME = "SILICONFLOW" - - def __init__( - self, - key, - model_name, - lang="Chinese", - base_url="https://api.siliconflow.cn/v1", - ): - if not base_url: - base_url = "https://api.siliconflow.cn/v1" - super().__init__(key, model_name, lang, base_url) - - -class HunyuanCV(Base): - _FACTORY_NAME = "Tencent Hunyuan" - - def __init__(self, key, model_name, lang="Chinese", base_url=None): - from tencentcloud.common import credential - from tencentcloud.hunyuan.v20230901 import hunyuan_client - - key = json.loads(key) - sid = key.get("hunyuan_sid", "") - sk = key.get("hunyuan_sk", "") - cred = credential.Credential(sid, sk) - self.model_name = model_name - self.client = hunyuan_client.HunyuanClient(cred, "") - self.lang = lang - - def describe(self, image): - from tencentcloud.common.exception.tencent_cloud_sdk_exception import ( - TencentCloudSDKException, - ) - from tencentcloud.hunyuan.v20230901 import models - - b64 = self.image2base64(image) - req = models.ChatCompletionsRequest() - params = {"Model": self.model_name, "Messages": self.prompt(b64)} - req.from_json_string(json.dumps(params)) - ans = "" + def chat(self, system, history, gen_conf, images=[], **kwargs): try: - response = self.client.ChatCompletions(req) - ans = response.Choices[0].Message.Content - return ans, response.Usage.TotalTokens - except TencentCloudSDKException as e: - return ans + "\n**ERROR**: " + str(e), 0 + response = self._request(self._form_history(system, history, images), gen_conf) + return ( + response["choices"][0]["message"]["content"].strip(), + response["usage"]["total_tokens"], + ) + except Exception as e: + return "**ERROR**: " + str(e), 0 - def describe_with_prompt(self, image, prompt=None): - from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException - from tencentcloud.hunyuan.v20230901 import models - - b64 = self.image2base64(image) - vision_prompt = self.vision_llm_prompt(b64, prompt) if prompt else self.vision_llm_prompt(b64) - req = models.ChatCompletionsRequest() - params = {"Model": self.model_name, "Messages": vision_prompt} - req.from_json_string(json.dumps(params)) - ans = "" + def chat_streamly(self, system, history, gen_conf, images=[], **kwargs): try: - response = self.client.ChatCompletions(req) - ans = response.Choices[0].Message.Content - return ans, response.Usage.TotalTokens - except TencentCloudSDKException as e: - return ans + "\n**ERROR**: " + str(e), 0 + response = self._request(self._form_history(system, history, images), gen_conf) + cnt = response["choices"][0]["message"]["content"] + for resp in cnt: + yield resp + except Exception as e: + yield "\n**ERROR**: " + str(e) - def prompt(self, b64): - return [ - { - "Role": "user", - "Contents": [ - { - "Type": "image_url", - "ImageUrl": {"Url": f"data:image/jpeg;base64,{b64}"}, - }, - { - "Type": "text", - "Text": "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" - if self.lang.lower() == "chinese" - else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out.", - }, - ], - } - ] + yield response["usage"]["total_tokens"] class AnthropicCV(Base): _FACTORY_NAME = "Anthropic" - def __init__(self, key, model_name, base_url=None): + def __init__(self, key, model_name, base_url=None, **kwargs): import anthropic self.client = anthropic.Anthropic(api_key=key) @@ -967,35 +637,27 @@ class AnthropicCV(Base): self.max_tokens = 8192 if "haiku" in self.model_name or "opus" in self.model_name: self.max_tokens = 4096 + Base.__init__(self, **kwargs) - def prompt(self, b64, prompt): - return [ - { - "role": "user", - "content": [ - { + def _image_prompt(self, text, images): + if not images: + return text + pmpt = [{"type": "text", "text": text}] + for img in images: + pmpt.append({ "type": "image", "source": { "type": "base64", - "media_type": "image/jpeg", - "data": b64, + "media_type": "image/jpeg" if img[:4] != "data" else img.split(":")[1].split(";")[0], + "data": img if img[:4] != "data" else img.split(",")[1] }, - }, - {"type": "text", "text": prompt}, - ], - } - ] + } + ) + return pmpt def describe(self, image): b64 = self.image2base64(image) - prompt = self.prompt( - b64, - "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" - if self.lang.lower() == "chinese" - else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out.", - ) - - response = self.client.messages.create(model=self.model_name, max_tokens=self.max_tokens, messages=prompt) + response = self.client.messages.create(model=self.model_name, max_tokens=self.max_tokens, messages=self.prompt(b64)) return response["content"][0]["text"].strip(), response["usage"]["input_tokens"] + response["usage"]["output_tokens"] def describe_with_prompt(self, image, prompt=None): @@ -1005,18 +667,22 @@ class AnthropicCV(Base): response = self.client.messages.create(model=self.model_name, max_tokens=self.max_tokens, messages=prompt) return response["content"][0]["text"].strip(), response["usage"]["input_tokens"] + response["usage"]["output_tokens"] - def chat(self, system, history, gen_conf): + def _clean_conf(self, gen_conf): if "presence_penalty" in gen_conf: del gen_conf["presence_penalty"] if "frequency_penalty" in gen_conf: del gen_conf["frequency_penalty"] - gen_conf["max_tokens"] = self.max_tokens + if "max_token" in gen_conf: + gen_conf["max_tokens"] = self.max_tokens + return gen_conf + def chat(self, system, history, gen_conf, images=[]): + gen_conf = self._clean_conf(gen_conf) ans = "" try: response = self.client.messages.create( model=self.model_name, - messages=history, + messages=self._form_history(system, history, images), system=system, stream=False, **gen_conf, @@ -1031,54 +697,38 @@ class AnthropicCV(Base): except Exception as e: return ans + "\n**ERROR**: " + str(e), 0 - def chat_streamly(self, system, history, gen_conf): - if "presence_penalty" in gen_conf: - del gen_conf["presence_penalty"] - if "frequency_penalty" in gen_conf: - del gen_conf["frequency_penalty"] - gen_conf["max_tokens"] = self.max_tokens - - ans = "" + def chat_streamly(self, system, history, gen_conf, images=[]): + gen_conf = self._clean_conf(gen_conf) total_tokens = 0 try: response = self.client.messages.create( model=self.model_name, - messages=history, + messages=self._form_history(system, history, images), system=system, stream=True, **gen_conf, ) + think = False for res in response: if res.type == "content_block_delta": if res.delta.type == "thinking_delta" and res.delta.thinking: - if ans.find("") < 0: - ans += "" - ans = ans.replace("", "") - ans += res.delta.thinking + "" + if not think: + yield "" + think = True + yield res.delta.thinking + total_tokens += num_tokens_from_string(res.delta.thinking) + elif think: + yield "" else: - text = res.delta.text - ans += text - total_tokens += num_tokens_from_string(text) - yield ans + yield res.delta.text + total_tokens += num_tokens_from_string(res.delta.text) except Exception as e: - yield ans + "\n**ERROR**: " + str(e) + yield "\n**ERROR**: " + str(e) yield total_tokens -class GPUStackCV(GptV4): - _FACTORY_NAME = "GPUStack" - - def __init__(self, key, model_name, lang="Chinese", base_url=""): - if not base_url: - raise ValueError("Local llm url cannot be None") - base_url = urljoin(base_url, "v1") - self.client = OpenAI(api_key=key, base_url=base_url) - self.model_name = model_name - self.lang = lang - - -class GoogleCV(Base): +class GoogleCV(AnthropicCV, GeminiCV): _FACTORY_NAME = "Google Cloud" def __init__(self, key, model_name, lang="Chinese", base_url=None, **kwargs): @@ -1117,127 +767,30 @@ class GoogleCV(Base): else: aiplatform.init(project=project_id, location=region) self.client = glm.GenerativeModel(model_name=self.model_name) + Base.__init__(self, **kwargs) def describe(self, image): - prompt = ( - "请用中文详细描述一下图中的内容,比如时间,地点,人物,事情,人物心情等,如果有数据请提取出数据。" - if self.lang.lower() == "chinese" - else "Please describe the content of this picture, like where, when, who, what happen. If it has number data, please extract them out." - ) - if "claude" in self.model_name: - b64 = self.image2base64(image) - vision_prompt = [ - { - "role": "user", - "content": [ - { - "type": "image", - "source": { - "type": "base64", - "media_type": "image/jpeg", - "data": b64, - }, - }, - {"type": "text", "text": prompt}, - ], - } - ] - response = self.client.messages.create( - model=self.model_name, - max_tokens=8192, - messages=vision_prompt, - ) - return response.content[0].text.strip(), response.usage.input_tokens + response.usage.output_tokens + return AnthropicCV.describe(self, image) else: - import vertexai.generative_models as glm - - b64 = self.image2base64(image) - # Create proper image part for Gemini - image_part = glm.Part.from_data(data=base64.b64decode(b64), mime_type="image/jpeg") - input = [prompt, image_part] - res = self.client.generate_content(input) - return res.text, res.usage_metadata.total_token_count + return GeminiCV.describe(self, image) def describe_with_prompt(self, image, prompt=None): if "claude" in self.model_name: - b64 = self.image2base64(image) - vision_prompt = [ - { - "role": "user", - "content": [ - { - "type": "image", - "source": { - "type": "base64", - "media_type": "image/jpeg", - "data": b64, - }, - }, - {"type": "text", "text": prompt if prompt else vision_llm_describe_prompt()}, - ], - } - ] - response = self.client.messages.create(model=self.model_name, max_tokens=8192, messages=vision_prompt) - return response.content[0].text.strip(), response.usage.input_tokens + response.usage.output_tokens + return AnthropicCV.describe_with_prompt(self, image, prompt) else: - import vertexai.generative_models as glm + return GeminiCV.describe_with_prompt(self, image, prompt) - b64 = self.image2base64(image) - vision_prompt = prompt if prompt else vision_llm_describe_prompt() - # Create proper image part for Gemini - image_part = glm.Part.from_data(data=base64.b64decode(b64), mime_type="image/jpeg") - input = [vision_prompt, image_part] - res = self.client.generate_content(input) - return res.text, res.usage_metadata.total_token_count - - def chat(self, system, history, gen_conf, image=""): + def chat(self, system, history, gen_conf, images=[]): if "claude" in self.model_name: - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - try: - for his in history: - if his["role"] == "user": - his["content"] = [ - { - "type": "image", - "source": { - "type": "base64", - "media_type": "image/jpeg", - "data": image, - }, - }, - {"type": "text", "text": his["content"]}, - ] - - response = self.client.messages.create(model=self.model_name, max_tokens=8192, messages=history, temperature=gen_conf.get("temperature", 0.3), top_p=gen_conf.get("top_p", 0.7)) - return response.content[0].text.strip(), response.usage.input_tokens + response.usage.output_tokens - except Exception as e: - return "**ERROR**: " + str(e), 0 + return AnthropicCV.chat(self, system, history, gen_conf, images) else: - import vertexai.generative_models as glm - from transformers import GenerationConfig + return GeminiCV.chat(self, system, history, gen_conf, images) - if system: - history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] - try: - for his in history: - if his["role"] == "assistant": - his["role"] = "model" - his["parts"] = [his["content"]] - his.pop("content") - if his["role"] == "user": - his["parts"] = [his["content"]] - his.pop("content") - - # Create proper image part for Gemini - img_bytes = base64.b64decode(image) - image_part = glm.Part.from_data(data=img_bytes, mime_type="image/jpeg") - history[-1]["parts"].append(image_part) - - response = self.client.generate_content(history, generation_config=GenerationConfig(temperature=gen_conf.get("temperature", 0.3), top_p=gen_conf.get("top_p", 0.7))) - - ans = response.text - return ans, response.usage_metadata.total_token_count - except Exception as e: - return "**ERROR**: " + str(e), 0 + def chat_streamly(self, system, history, gen_conf, images=[]): + if "claude" in self.model_name: + for ans in AnthropicCV.chat_streamly(self, system, history, gen_conf, images): + yield ans + else: + for ans in GeminiCV.chat_streamly(self, system, history, gen_conf, images): + yield ans \ No newline at end of file diff --git a/rag/llm/rerank_model.py b/rag/llm/rerank_model.py index de6efb87b..7f2181bdf 100644 --- a/rag/llm/rerank_model.py +++ b/rag/llm/rerank_model.py @@ -89,7 +89,7 @@ class DefaultRerank(Base): torch.cuda.empty_cache() except Exception as e: - print(f"Error emptying cache: {e}") + log_exception(e) def _process_batch(self, pairs, max_batch_size=None): """template method for subclass call""" diff --git a/rag/nlp/__init__.py b/rag/nlp/__init__.py index e54eb96b6..605601824 100644 --- a/rag/nlp/__init__.py +++ b/rag/nlp/__init__.py @@ -518,7 +518,8 @@ def hierarchical_merge(bull, sections, depth): return res -def naive_merge(sections, chunk_token_num=128, delimiter="\n。;!?"): +def naive_merge(sections, chunk_token_num=128, delimiter="\n。;!?", overlapped_percent=0): + from deepdoc.parser.pdf_parser import RAGFlowPdfParser if not sections: return [] if isinstance(sections[0], type("")): @@ -534,8 +535,10 @@ def naive_merge(sections, chunk_token_num=128, delimiter="\n。;!?"): if tnum < 8: pos = "" # Ensure that the length of the merged chunk does not exceed chunk_token_num - if cks[-1] == "" or tk_nums[-1] > chunk_token_num: - + if cks[-1] == "" or tk_nums[-1] > chunk_token_num * (100 - overlapped_percent)/100.: + if cks: + overlapped = RAGFlowPdfParser.remove_tag(cks[-1]) + t = overlapped[int(len(overlapped)*(100-overlapped_percent)/100.):] + t if t.find(pos) < 0: t += pos cks.append(t) @@ -548,7 +551,10 @@ def naive_merge(sections, chunk_token_num=128, delimiter="\n。;!?"): dels = get_delimiters(delimiter) for sec, pos in sections: - splited_sec = re.split(r"(%s)" % dels, sec) + if num_tokens_from_string(sec) < chunk_token_num: + add_chunk(sec, pos) + continue + splited_sec = re.split(r"(%s)" % dels, sec, flags=re.DOTALL) for sub_sec in splited_sec: if re.match(f"^{dels}$", sub_sec): continue diff --git a/rag/nlp/search.py b/rag/nlp/search.py index a8229c948..660fab0bc 100644 --- a/rag/nlp/search.py +++ b/rag/nlp/search.py @@ -384,7 +384,7 @@ class Dealer: zero_vector = [0.0] * dim sim_np = np.array(sim) if doc_ids: - similarity_threshold = 0 + similarity_threshold = 0 filtered_count = (sim_np >= similarity_threshold).sum() ranks["total"] = int(filtered_count) # Convert from np.int64 to Python int otherwise JSON serializable error for i in idx: @@ -403,7 +403,7 @@ class Dealer: ranks["doc_aggs"][dnm]["count"] += 1 continue break - + position_int = chunk.get("position_int", []) d = { "chunk_id": id, diff --git a/rag/prompts/__init__.py b/rag/prompts/__init__.py new file mode 100644 index 000000000..f5616dddd --- /dev/null +++ b/rag/prompts/__init__.py @@ -0,0 +1,6 @@ +from . import prompts + +__all__ = [name for name in dir(prompts) + if not name.startswith('_')] + +globals().update({name: getattr(prompts, name) for name in __all__}) \ No newline at end of file diff --git a/rag/prompts/analyze_task_system.md b/rag/prompts/analyze_task_system.md new file mode 100644 index 000000000..c086195b8 --- /dev/null +++ b/rag/prompts/analyze_task_system.md @@ -0,0 +1,8 @@ +Your responsibility is to execute assigned tasks to a high standard. Please: +1. Carefully analyze the task requirements. +2. Develop a reasonable execution plan. +3. Execute step-by-step and document the reasoning process. +4. Provide clear and accurate results. + +If difficulties are encountered, clearly state the problem and explore alternative approaches. + diff --git a/rag/prompts/analyze_task_user.md b/rag/prompts/analyze_task_user.md new file mode 100644 index 000000000..65ddba7a8 --- /dev/null +++ b/rag/prompts/analyze_task_user.md @@ -0,0 +1,20 @@ +Please analyze the following task: + +Task: {{ task }} + +Context: {{ context }} + +**Analysis Requirements:** +1. Is it just a small talk? (If yes, no further plan or analysis is needed) +2. What is the core objective of the task? +3. What is the complexity level of the task? +4. What types of specialized skills are required? +5. Does the task need to be decomposed into subtasks? (If yes, propose the subtask structure) +6. How to know the task or the subtasks are impossible to lead to the success after a few rounds of interaction? +7. What are the expected success criteria? + +**Available Sub-Agents and Their Specializations:** + +{{ tools_desc }} + +Provide a detailed analysis of the task based on the above requirements. \ No newline at end of file diff --git a/rag/prompts/citation_plus.md b/rag/prompts/citation_plus.md new file mode 100644 index 000000000..77bba4e25 --- /dev/null +++ b/rag/prompts/citation_plus.md @@ -0,0 +1,13 @@ +You are an agent for adding correct citations to the given text by user. +You are given a piece of text within [ID:] tags, which was generated based on the provided sources. +However, the sources are not cited in the [ID:]. +Your task is to enhance user trust by generating correct, appropriate citations for this report. + +{{ example }} + + + +{{ sources }} + + + diff --git a/rag/prompts/citation_prompt.md b/rag/prompts/citation_prompt.md index c36036c27..53928b991 100644 --- a/rag/prompts/citation_prompt.md +++ b/rag/prompts/citation_prompt.md @@ -1,46 +1,108 @@ -## Citation Requirements +Based on the provided document or chat history, add citations to the input text using the format specified later. -- Use a uniform citation format such as [ID:i] [ID:j], where "i" and "j" are document IDs enclosed in square brackets. Separate multiple IDs with spaces (e.g., [ID:0] [ID:1]). -- Citation markers must be placed at the end of a sentence, separated by a space from the final punctuation (e.g., period, question mark). -- A maximum of 4 citations are allowed per sentence. -- DO NOT insert citations if the content is not from retrieved chunks. -- DO NOT use standalone Document IDs (e.g., #ID#). -- Citations MUST always follow the [ID:i] format. -- STRICTLY prohibit the use of strikethrough symbols (e.g., ~~) or any other non-standard formatting syntax. -- Any violation of the above rules — including incorrect formatting, prohibited styles, or unsupported citations — will result in no citation being added for that sentence. +# Citation Requirements: ---- +## Technical Rules: +- Use format: [ID:i] or [ID:i] [ID:j] for multiple sources +- Place citations at the end of sentences, before punctuation +- Maximum 4 citations per sentence +- DO NOT cite content not from +- DO NOT modify whitespace or original text +- STRICTLY prohibit non-standard formatting (~~, etc.) -## Example START +## What MUST Be Cited: +1. **Quantitative data**: Numbers, percentages, statistics, measurements +2. **Temporal claims**: Dates, timeframes, sequences of events +3. **Causal relationships**: Claims about cause and effect +4. **Comparative statements**: Rankings, comparisons, superlatives +5. **Technical definitions**: Specialized terms, concepts, methodologies +6. **Direct attributions**: What someone said, did, or believes +7. **Predictions/forecasts**: Future projections, trend analyses +8. **Controversial claims**: Disputed facts, minority opinions -: Here is the knowledge base: +## What Should NOT Be Cited: +- Common knowledge (e.g., "The sun rises in the east") +- Transitional phrases +- General introductions +- Your own analysis or synthesis (unless directly from source) -Document: Elon Musk Breaks Silence on Crypto, Warns Against Dogecoin ... -URL: https://blockworks.co/news/elon-musk-crypto-dogecoin -ID: 0 -The Tesla co-founder advised against going all-in on dogecoin, but Elon Musk said it’s still his favorite crypto... +# Comprehensive Examples: -Document: Elon Musk's Dogecoin tweet sparks social media frenzy -ID: 1 -Musk said he is 'willing to serve' D.O.G.E. – shorthand for Dogecoin. +## Example 1: Data and Statistics + +ID: 45 +└── Content: The global smartphone market grew by 7.8% in Q3 2024, with Samsung holding 20.6% market share and Apple at 15.8%. -Document: Causal effect of Elon Musk tweets on Dogecoin price -ID: 2 -If you think of Dogecoin — the cryptocurrency based on a meme — you can’t help but also think of Elon Musk... +ID: 46 +└── Content: 5G adoption reached 1.5 billion users worldwide by October 2024. + -Document: Elon Musk's Tweet Ignites Dogecoin's Future In Public Services -ID: 3 -The market is heating up after Elon Musk's announcement about Dogecoin. Is this a new era for crypto?... +USER: How is the smartphone market performing? -The above is the knowledge base. +ASSISTANT: +The smartphone industry is showing strong recovery. The global smartphone market grew by 7.8% in Q3 2024 [ID:45]. Samsung leads with 20.6% market share, followed by Apple at 15.8% [ID:45]. This growth is partly driven by 5G technology, which reached 1.5 billion users worldwide by October 2024 [ID:46]. -: What's Elon's view on dogecoin? +## Example 2: Causal Relationships and Predictions + +ID: 78 +└── Content: Rising interest rates have led to a 15% decline in housing starts. Economists predict this trend will continue through 2025. -: -Musk has consistently expressed his fondness for Dogecoin, often citing its humor and the inclusion of dogs in its branding. He has referred to it as his favorite cryptocurrency [ID:0] [ID:1]. +ID: 79 +└── Content: The Federal Reserve's aggressive monetary policy is the primary driver behind the real estate slowdown. + -Recently, Musk has hinted at potential future roles for Dogecoin. His tweets have sparked speculation about Dogecoin's potential integration into public services [ID:3]. +USER: What's happening in the real estate market? -Overall, while Musk enjoys Dogecoin and often promotes it, he also warns against over-investing in it, reflecting both his personal amusement and caution regarding its speculative nature. +ASSISTANT: +The real estate market is experiencing significant challenges. Rising interest rates have led to a 15% decline in housing starts [ID:78]. The Federal Reserve's aggressive monetary policy is the primary driver behind this real estate slowdown [ID:79]. Economists predict this trend will continue through 2025 [ID:78]. These factors suggest a prolonged period of market adjustment ahead. -## Example END +## Example 3: Technical Concepts and Comparisons + +ID: 101 +└── Content: Quantum computing uses quantum bits (qubits) that can exist in superposition, unlike classical bits which are either 0 or 1. + +ID: 102 +└── Content: Current quantum computers can solve certain problems 158 million times faster than classical supercomputers. + + +USER: Explain quantum computing advantages. + +ASSISTANT: +Quantum computing represents a fundamental shift in computational capability. Unlike classical computers, quantum computing uses quantum bits (qubits) that can exist in superposition, rather than being limited to just 0 or 1 [ID:101]. This unique property enables extraordinary performance gains. Current quantum computers can solve certain problems 158 million times faster than classical supercomputers [ID:102]. This technology promises to revolutionize fields requiring complex calculations. + +## Example 4: Mixed Citation Needs + +ID: 201 +└── Content: CEO Jane Smith announced: "We're pivoting to AI-first strategy, expecting 40% revenue growth by 2026." + +ID: 202 +└── Content: Industry analysts remain skeptical, with Morgan Stanley rating the stock as "underperform." + +ID: 203 +└── Content: The company's AI division currently represents only 5% of total revenue. + + +USER: What's the company's new strategy? + +ASSISTANT: +The company is undergoing a major strategic transformation. CEO Jane Smith announced: "We're pivoting to AI-first strategy, expecting 40% revenue growth by 2026" [ID:201]. However, this ambitious goal faces skepticism, as industry analysts remain doubtful, with Morgan Stanley rating the stock as "underperform" [ID:202]. The challenge is significant given that the company's AI division currently represents only 5% of total revenue [ID:203]. Success will depend on execution of this bold vision. + +## Example 5: When NOT to Cite + +ID: 301 +└── Content: Paris is the capital of France. The Eiffel Tower was completed in 1889. + + +USER: Tell me about Paris. + +ASSISTANT: +Paris is the capital of France. It's known for its rich history, culture, and architecture. The Eiffel Tower was completed in 1889 [ID:301]. The city attracts millions of tourists annually. Paris remains one of the world's most visited destinations. +(Note: Only the specific date needs citation, not common knowledge about Paris) + +--- Examples END --- + +REMEMBER: +- Cite FACTS, not opinions or transitions +- Each citation supports the ENTIRE sentence +- When in doubt, ask: "Would a fact-checker need to verify this?" +- Place citations at sentence end, before punctuation \ No newline at end of file diff --git a/rag/prompts/next_step.md b/rag/prompts/next_step.md new file mode 100644 index 000000000..a57f90005 --- /dev/null +++ b/rag/prompts/next_step.md @@ -0,0 +1,63 @@ +You are an expert Planning Agent tasked with solving problems efficiently through structured plans. +Your job is: +1. Based on the task analysis, chose some right tools to execute. +2. Track progress and adapt plans(tool calls) when necessary. +3. Use `complete_task` if no further step you need to take from tools. (All necessary steps done or little hope to be done) + +# ========== TASK ANALYSIS ============= +{{ task_analisys }} + + +# ========== TOOLS (JSON-Schema) ========== +You may invoke only the tools listed below. +Return a JSON array of objects in which item is with exactly two top-level keys: +• "name": the tool to call +• "arguments": an object whose keys/values satisfy the schema + +{{ desc }} + +# ========== RESPONSE FORMAT ========== +✦ **When you need a tool** +Return ONLY the Json (no additional keys, no commentary, end with `<|stop|>`), such as following: +[{ + "name": "", + "arguments": { /* tool arguments matching its schema */ } +},{ + "name": "", + "arguments": { /* tool arguments matching its schema */ } +}...]<|stop|> + +✦ **When you are certain the task is solved OR no further information can be obtained** +Return ONLY: +[{ + "name": "complete_task", + "arguments": { "answer": "" } +}]<|stop|> + + +Before providing a final answer: +1. Double-check all gathered information +2. Verify calculations and logic +3. Ensure answer matches exactly what was asked +4. Confirm answer format meets requirements +5. Run additional verification if confidence is not 100% + + + +If you encounter issues: +1. Try alternative approaches before giving up +2. Use different tools or combinations of tools +3. Break complex problems into simpler sub-tasks +4. Verify intermediate results frequently +5. Never return "I cannot answer" without exhausting all options + + +⚠️ Any output that is not valid JSON or that contains extra fields will be rejected. + +# ========== REASONING & REFLECTION ========== +You may think privately (not shown to the user) before producing each JSON object. +Internal guideline: +1. **Reason**: Analyse the user question; decide which tools (if any) are needed. +2. **Act**: Emit the JSON object to call the tool. + +Today is {{ today }}. Remember that success in answering questions accurately is paramount - take all necessary steps to ensure your answer is correct. diff --git a/rag/prompt_template.py b/rag/prompts/prompt_template.py similarity index 84% rename from rag/prompt_template.py rename to rag/prompts/prompt_template.py index c30a6f9a5..654e71c5c 100644 --- a/rag/prompt_template.py +++ b/rag/prompts/prompt_template.py @@ -1,8 +1,7 @@ import os -BASE_DIR = os.path.dirname(__file__) -PROMPT_DIR = os.path.join(BASE_DIR, "prompts") +PROMPT_DIR = os.path.dirname(__file__) _loaded_prompts = {} diff --git a/rag/prompts.py b/rag/prompts/prompts.py similarity index 57% rename from rag/prompts.py rename to rag/prompts/prompts.py index ccaa198b6..aeeb6cb91 100644 --- a/rag/prompts.py +++ b/rag/prompts/prompts.py @@ -17,19 +17,25 @@ import datetime import json import logging import re -from collections import defaultdict - +from copy import deepcopy +from typing import Tuple import jinja2 import json_repair - -from rag.prompt_template import load_prompt +from api.utils import hash_str2int +from rag.prompts.prompt_template import load_prompt from rag.settings import TAG_FLD from rag.utils import encoder, num_tokens_from_string +STOP_TOKEN="<|STOP|>" +COMPLETE_TASK="complete_task" + + +def get_value(d, k1, k2): + return d.get(k1, d.get(k2)) + + def chunks_format(reference): - def get_value(d, k1, k2): - return d.get(k1, d.get(k2)) return [ { @@ -87,14 +93,16 @@ def message_fit_in(msg, max_length=4000): return max_length, msg -def kb_prompt(kbinfos, max_tokens): +def kb_prompt(kbinfos, max_tokens, hash_id=False): from api.db.services.document_service import DocumentService - knowledges = [ck["content_with_weight"] for ck in kbinfos["chunks"]] + knowledges = [get_value(ck, "content", "content_with_weight") for ck in kbinfos["chunks"]] kwlg_len = len(knowledges) used_token_count = 0 chunks_num = 0 for i, c in enumerate(knowledges): + if not c: + continue used_token_count += num_tokens_from_string(c) chunks_num += 1 if max_tokens * 0.97 < used_token_count: @@ -102,29 +110,30 @@ def kb_prompt(kbinfos, max_tokens): logging.warning(f"Not all the retrieval into prompt: {len(knowledges)}/{kwlg_len}") break - docs = DocumentService.get_by_ids([ck["doc_id"] for ck in kbinfos["chunks"][:chunks_num]]) + docs = DocumentService.get_by_ids([get_value(ck, "doc_id", "document_id") for ck in kbinfos["chunks"][:chunks_num]]) docs = {d.id: d.meta_fields for d in docs} - doc2chunks = defaultdict(lambda: {"chunks": [], "meta": []}) - for i, ck in enumerate(kbinfos["chunks"][:chunks_num]): - cnt = f"---\nID: {i}\n" + (f"URL: {ck['url']}\n" if "url" in ck else "") - cnt += re.sub(r"( style=\"[^\"]+\"||)", " ", ck["content_with_weight"], flags=re.DOTALL | re.IGNORECASE) - doc2chunks[ck["docnm_kwd"]]["chunks"].append(cnt) - doc2chunks[ck["docnm_kwd"]]["meta"] = docs.get(ck["doc_id"], {}) + def draw_node(k, line): + if not line: + return "" + return f"\n├── {k}: " + re.sub(r"\n+", " ", line, flags=re.DOTALL) knowledges = [] - for nm, cks_meta in doc2chunks.items(): - txt = f"\nDocument: {nm} \n" - for k, v in cks_meta["meta"].items(): - txt += f"{k}: {v}\n" - txt += "Relevant fragments as following:\n" - for i, chunk in enumerate(cks_meta["chunks"], 1): - txt += f"{chunk}\n" - knowledges.append(txt) + for i, ck in enumerate(kbinfos["chunks"][:chunks_num]): + cnt = "\nID: {}".format(i if not hash_id else hash_str2int(get_value(ck, "id", "chunk_id"), 100)) + cnt += draw_node("Title", get_value(ck, "docnm_kwd", "document_name")) + cnt += draw_node("URL", ck['url']) if "url" in ck else "" + for k, v in docs.get(get_value(ck, "doc_id", "document_id"), {}).items(): + cnt += draw_node(k, v) + cnt += "\n└── Content:\n" + cnt += get_value(ck, "content", "content_with_weight") + knowledges.append(cnt) + return knowledges CITATION_PROMPT_TEMPLATE = load_prompt("citation_prompt") +CITATION_PLUS_TEMPLATE = load_prompt("citation_plus") CONTENT_TAGGING_PROMPT_TEMPLATE = load_prompt("content_tagging_prompt") CROSS_LANGUAGES_SYS_PROMPT_TEMPLATE = load_prompt("cross_languages_sys_prompt") CROSS_LANGUAGES_USER_PROMPT_TEMPLATE = load_prompt("cross_languages_user_prompt") @@ -134,6 +143,13 @@ QUESTION_PROMPT_TEMPLATE = load_prompt("question_prompt") VISION_LLM_DESCRIBE_PROMPT = load_prompt("vision_llm_describe_prompt") VISION_LLM_FIGURE_DESCRIBE_PROMPT = load_prompt("vision_llm_figure_describe_prompt") +ANALYZE_TASK_SYSTEM = load_prompt("analyze_task_system") +ANALYZE_TASK_USER = load_prompt("analyze_task_user") +NEXT_STEP = load_prompt("next_step") +REFLECT = load_prompt("reflect") +SUMMARY4MEMORY = load_prompt("summary4memory") +RANK_MEMORY = load_prompt("rank_memory") + PROMPT_JINJA_ENV = jinja2.Environment(autoescape=False, trim_blocks=True, lstrip_blocks=True) @@ -142,6 +158,11 @@ def citation_prompt() -> str: return template.render() +def citation_plus(sources: str) -> str: + template = PROMPT_JINJA_ENV.from_string(CITATION_PLUS_TEMPLATE) + return template.render(example=citation_prompt(), sources=sources) + + def keyword_extraction(chat_mdl, content, topn=3): template = PROMPT_JINJA_ENV.from_string(KEYWORD_PROMPT_TEMPLATE) rendered_prompt = template.render(content=content, topn=topn) @@ -172,15 +193,16 @@ def question_proposal(chat_mdl, content, topn=3): return kwd -def full_question(tenant_id, llm_id, messages, language=None): +def full_question(tenant_id=None, llm_id=None, messages=[], language=None, chat_mdl=None): from api.db import LLMType from api.db.services.llm_service import LLMBundle from api.db.services.llm_service import TenantLLMService - if TenantLLMService.llm_id2llm_type(llm_id) == "image2text": - chat_mdl = LLMBundle(tenant_id, LLMType.IMAGE2TEXT, llm_id) - else: - chat_mdl = LLMBundle(tenant_id, LLMType.CHAT, llm_id) + if not chat_mdl: + if TenantLLMService.llm_id2llm_type(llm_id) == "image2text": + chat_mdl = LLMBundle(tenant_id, LLMType.IMAGE2TEXT, llm_id) + else: + chat_mdl = LLMBundle(tenant_id, LLMType.CHAT, llm_id) conv = [] for m in messages: if m["role"] not in ["user", "assistant"]: @@ -200,7 +222,7 @@ def full_question(tenant_id, llm_id, messages, language=None): language=language, ) - ans = chat_mdl.chat(rendered_prompt, [{"role": "user", "content": "Output: "}], {"temperature": 0.2}) + ans = chat_mdl.chat(rendered_prompt, [{"role": "user", "content": "Output: "}]) ans = re.sub(r"^.*", "", ans, flags=re.DOTALL) return ans if ans.find("**ERROR**") < 0 else messages[-1]["content"] @@ -278,13 +300,116 @@ def vision_llm_figure_describe_prompt() -> str: return template.render() -if __name__ == "__main__": - print(CITATION_PROMPT_TEMPLATE) - print(CONTENT_TAGGING_PROMPT_TEMPLATE) - print(CROSS_LANGUAGES_SYS_PROMPT_TEMPLATE) - print(CROSS_LANGUAGES_USER_PROMPT_TEMPLATE) - print(FULL_QUESTION_PROMPT_TEMPLATE) - print(KEYWORD_PROMPT_TEMPLATE) - print(QUESTION_PROMPT_TEMPLATE) - print(VISION_LLM_DESCRIBE_PROMPT) - print(VISION_LLM_FIGURE_DESCRIBE_PROMPT) +def tool_schema(tools_description: list[dict], complete_task=False): + if not tools_description: + return "" + desc = {} + if complete_task: + desc[COMPLETE_TASK] = { + "type": "function", + "function": { + "name": COMPLETE_TASK, + "description": "When you have the final answer and are ready to complete the task, call this function with your answer", + "parameters": { + "type": "object", + "properties": {"answer":{"type":"string", "description": "The final answer to the user's question"}}, + "required": ["answer"] + } + } + } + for tool in tools_description: + desc[tool["function"]["name"]] = tool + + return "\n\n".join([f"## {i+1}. {fnm}\n{json.dumps(des, ensure_ascii=False, indent=4)}" for i, (fnm, des) in enumerate(desc.items())]) + + +def form_history(history, limit=-6): + context = "" + for h in history[limit:]: + if h["role"] == "system": + continue + role = "USER" + if h["role"].upper()!= role: + role = "AGENT" + context += f"\n{role}: {h['content'][:2048] + ('...' if len(h['content'])>2048 else '')}" + return context + + +def analyze_task(chat_mdl, task_name, tools_description: list[dict]): + tools_desc = tool_schema(tools_description) + context = "" + + template = PROMPT_JINJA_ENV.from_string(ANALYZE_TASK_USER) + + kwd = chat_mdl.chat(ANALYZE_TASK_SYSTEM,[{"role": "user", "content": template.render(task=task_name, context=context, tools_desc=tools_desc)}], {}) + if isinstance(kwd, tuple): + kwd = kwd[0] + kwd = re.sub(r"^.*", "", kwd, flags=re.DOTALL) + if kwd.find("**ERROR**") >= 0: + return "" + return kwd + + +def next_step(chat_mdl, history:list, tools_description: list[dict], task_desc): + if not tools_description: + return "" + desc = tool_schema(tools_description) + template = PROMPT_JINJA_ENV.from_string(NEXT_STEP) + user_prompt = "\nWhat's the next tool to call? If ready OR IMPOSSIBLE TO BE READY, then call `complete_task`." + hist = deepcopy(history) + if hist[-1]["role"] == "user": + hist[-1]["content"] += user_prompt + else: + hist.append({"role": "user", "content": user_prompt}) + json_str = chat_mdl.chat(template.render(task_analisys=task_desc, desc=desc, today=datetime.datetime.now().strftime("%Y-%m-%d")), + hist[1:], stop=["<|stop|>"]) + tk_cnt = num_tokens_from_string(json_str) + json_str = re.sub(r"^.*", "", json_str, flags=re.DOTALL) + return json_str, tk_cnt + + +def reflect(chat_mdl, history: list[dict], tool_call_res: list[Tuple]): + tool_calls = [{"name": p[0], "result": p[1]} for p in tool_call_res] + goal = history[1]["content"] + template = PROMPT_JINJA_ENV.from_string(REFLECT) + user_prompt = template.render(goal=goal, tool_calls=tool_calls) + hist = deepcopy(history) + if hist[-1]["role"] == "user": + hist[-1]["content"] += user_prompt + else: + hist.append({"role": "user", "content": user_prompt}) + _, msg = message_fit_in(hist, chat_mdl.max_length) + ans = chat_mdl.chat(msg[0]["content"], msg[1:]) + ans = re.sub(r"^.*", "", ans, flags=re.DOTALL) + return """ +**Observation** +{} + +**Reflection** +{} + """.format(json.dumps(tool_calls, ensure_ascii=False, indent=2), ans) + + +def form_message(system_prompt, user_prompt): + return [{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}] + + +def tool_call_summary(chat_mdl, name: str, params: dict, result: str) -> str: + template = PROMPT_JINJA_ENV.from_string(SUMMARY4MEMORY) + system_prompt = template.render(name=name, + params=json.dumps(params, ensure_ascii=False, indent=2), + result=result) + user_prompt = "→ Summary: " + _, msg = message_fit_in(form_message(system_prompt, user_prompt), chat_mdl.max_length) + ans = chat_mdl.chat(msg[0]["content"], msg[1:]) + return re.sub(r"^.*", "", ans, flags=re.DOTALL) + + +def rank_memories(chat_mdl, goal:str, sub_goal:str, tool_call_summaries: list[str]): + template = PROMPT_JINJA_ENV.from_string(RANK_MEMORY) + system_prompt = template.render(goal=goal, sub_goal=sub_goal, results=[{"i": i, "content": s} for i,s in enumerate(tool_call_summaries)]) + user_prompt = " → rank: " + _, msg = message_fit_in(form_message(system_prompt, user_prompt), chat_mdl.max_length) + ans = chat_mdl.chat(msg[0]["content"], msg[1:], stop="<|stop|>") + return re.sub(r"^.*", "", ans, flags=re.DOTALL) + diff --git a/rag/prompts/rank_memory.md b/rag/prompts/rank_memory.md new file mode 100644 index 000000000..719698582 --- /dev/null +++ b/rag/prompts/rank_memory.md @@ -0,0 +1,30 @@ +**Task**: Sort the tool call results based on relevance to the overall goal and current sub-goal. Return ONLY a sorted list of indices (0-indexed). + +**Rules**: +1. Analyze each result's contribution to both: + - The overall goal (primary priority) + - The current sub-goal (secondary priority) +2. Sort from MOST relevant (highest impact) to LEAST relevant +3. Output format: Strictly a Python-style list of integers. Example: [2, 0, 1] + +🔹 Overall Goal: {{ goal }} +🔹 Sub-goal: {{ sub_goal }} + +**Examples**: +🔹 Tool Response: + - index: 0 + > Tokyo temperature is 78°F. + - index: 1 + > Error: Authentication failed (expired API key). + - index: 2 + > Available: 12 widgets in stock (max 5 per customer). + + → rank: [1,2,0]<|stop|> + + +**Your Turn**: +🔹 Tool Response: +{% for f in results %} + - index: f.i + > f.content +{% endfor %} \ No newline at end of file diff --git a/rag/prompts/reflect.md b/rag/prompts/reflect.md new file mode 100644 index 000000000..a9c0e4f1f --- /dev/null +++ b/rag/prompts/reflect.md @@ -0,0 +1,34 @@ +**Context**: + - To achieve the goal: {{ goal }}. + - You have executed following tool calls: +{% for call in tool_calls %} +Tool call: `{{ call.name }}` +Results: {{ call.result }} +{% endfor %} + + +**Reflection Instructions:** + +Analyze the current state of the overall task ({{ goal }}), then provide structured responses to the following: + +## 1. Goal Achievement Status + - Does the current outcome align with the original purpose of this task phase? + - If not, what critical gaps exist? + +## 2. Step Completion Check + - Which planned steps were completed? (List verified items) + - Which steps are pending/incomplete? (Specify exactly what’s missing) + +## 3. Information Adequacy + - Is the collected data sufficient to proceed? + - What key information is still needed? (e.g., metrics, user input, external data) + +## 4. Critical Observations + - Unexpected outcomes: [Flag anomalies/errors] + - Risks/blockers: [Identify immediate obstacles] + - Accuracy concerns: [Highlight unreliable results] + +## 5. Next-Step Recommendations + - Proposed immediate action: [Concrete next step] + - Alternative strategies if blocked: [Workaround solution] + - Tools/inputs required for next phase: [Specify resources] \ No newline at end of file diff --git a/rag/prompts/summary4memory.md b/rag/prompts/summary4memory.md new file mode 100644 index 000000000..eb0f283f9 --- /dev/null +++ b/rag/prompts/summary4memory.md @@ -0,0 +1,35 @@ +**Role**: AI Assistant +**Task**: Summarize tool call responses +**Rules**: +1. Context: You've executed a tool (API/function) and received a response. +2. Condense the response into 1-2 short sentences. +3. Never omit: + - Success/error status + - Core results (e.g., data points, decisions) + - Critical constraints (e.g., limits, conditions) +4. Exclude technical details like timestamps/request IDs unless crucial. +5. Use language as the same as main content of the tool response. + +**Response Template**: +"[Status] + [Key Outcome] + [Critical Constraints]" + +**Examples**: +🔹 Tool Response: +{"status": "success", "temperature": 78.2, "unit": "F", "location": "Tokyo", "timestamp": 16923456} +→ Summary: "Success: Tokyo temperature is 78°F." + +🔹 Tool Response: +{"error": "invalid_api_key", "message": "Authentication failed: expired key"} +→ Summary: "Error: Authentication failed (expired API key)." + +🔹 Tool Response: +{"available": true, "inventory": 12, "product": "widget", "limit": "max 5 per customer"} +→ Summary: "Available: 12 widgets in stock (max 5 per customer)." + +**Your Turn**: + - Tool call: {{ name }} + - Tool inputs as following: +{{ params }} + + - Tool Response: +{{ result }} \ No newline at end of file diff --git a/rag/prompts/tool_call_summary.md b/rag/prompts/tool_call_summary.md new file mode 100644 index 000000000..b1c77dd40 --- /dev/null +++ b/rag/prompts/tool_call_summary.md @@ -0,0 +1,19 @@ +**Task Instruction:** + +You are tasked with reading and analyzing tool call result based on the following inputs: **Inputs for current call**, and **Results**. Your objective is to extract relevant and helpful information for **Inputs for current call** from the **Results** and seamlessly integrate this information into the previous steps to continue reasoning for the original question. + +**Guidelines:** + +1. **Analyze the Results:** + - Carefully review the content of each results of tool call. + - Identify factual information that is relevant to the **Inputs for current call** and can aid in the reasoning process for the original question. + +2. **Extract Relevant Information:** + - Select the information from the Searched Web Pages that directly contributes to advancing the previous reasoning steps. + - Ensure that the extracted information is accurate and relevant. + + - **Inputs for current call:** + {{ inputs }} + + - **Results:** + {{ results }} diff --git a/rag/utils/mcp_tool_call_conn.py b/rag/utils/mcp_tool_call_conn.py index 5e449477f..80b597374 100644 --- a/rag/utils/mcp_tool_call_conn.py +++ b/rag/utils/mcp_tool_call_conn.py @@ -239,7 +239,17 @@ def shutdown_all_mcp_sessions(): logging.info("All MCPToolCallSession instances have been closed.") -def mcp_tool_metadata_to_openai_tool(mcp_tool: Tool) -> dict[str, Any]: +def mcp_tool_metadata_to_openai_tool(mcp_tool: Tool|dict) -> dict[str, Any]: + if isinstance(mcp_tool, dict): + return { + "type": "function", + "function": { + "name": mcp_tool["name"], + "description": mcp_tool["description"], + "parameters": mcp_tool["inputSchema"], + }, + } + return { "type": "function", "function": { diff --git a/uv.lock b/uv.lock index 3e550fba6..a60530bbe 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,4 @@ version = 1 -revision = 2 requires-python = ">=3.10, <3.13" resolution-markers = [ "python_full_version >= '3.12' and sys_platform == 'darwin'", @@ -15,7 +14,7 @@ resolution-markers = [ [[package]] name = "accelerate" -version = "1.5.2" +version = "1.9.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "huggingface-hub" }, @@ -26,9 +25,9 @@ dependencies = [ { name = "safetensors" }, { name = "torch" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a9/4c/a61132924da12cef62a88c04b5825246ab83dcc1bae6291d098cfcb0b72d/accelerate-1.5.2.tar.gz", hash = "sha256:a1cf39473edc0e42772a9d9a18c9eb1ce8ffd9e1719dc0ab80670f5c1fd4dc43" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c4/25/969456a95a90ed38f73f68d0f0915bdf1d76145d05054c59ad587b171150/accelerate-1.9.0.tar.gz", hash = "sha256:0e8c61f81af7bf37195b6175a545ed292617dd90563c88f49020aea5b6a0b47f" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/70/83/167d4b638bb758a966828eb8d23c5e7047825edfdf768ff5f4fb01440063/accelerate-1.5.2-py3-none-any.whl", hash = "sha256:68a3b272f6a6ffebb457bdc138581a2bf52efad6a5e0214dc46675f3edd98792" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9f/1c/a17fb513aeb684fb83bef5f395910f53103ab30308bbdd77fd66d6698c46/accelerate-1.9.0-py3-none-any.whl", hash = "sha256:c24739a97ade1d54af4549a65f8b6b046adc87e2b3e4d6c66516e32c53d5a8f1" }, ] [[package]] @@ -42,7 +41,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.11.14" +version = "3.12.15" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -54,56 +53,59 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6c/96/91e93ae5fd04d428c101cdbabce6c820d284d61d2614d00518f4fa52ea24/aiohttp-3.11.14.tar.gz", hash = "sha256:d6edc538c7480fa0a3b2bdd705f8010062d74700198da55d16498e1b49549b9c" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/6a/e1/f1ccc6cf29a31fb33e4eaa07a9d8e4dff00e23b32423b679cdb89536fe71/aiohttp-3.11.14-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e2bc827c01f75803de77b134afdbf74fa74b62970eafdf190f3244931d7a5c0d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/80/7d/195965f183a724d0470560b097543e96dc4a672fc2714012d1be87d6775c/aiohttp-3.11.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e365034c5cf6cf74f57420b57682ea79e19eb29033399dd3f40de4d0171998fa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/46/02/3a4f05e966c2edeace5103f40d296ba0159cee633ab0f162fbea579653e3/aiohttp-3.11.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c32593ead1a8c6aabd58f9d7ee706e48beac796bb0cb71d6b60f2c1056f0a65f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/68/a6/c96cd5452af267fdda1cf46accc356d1295fb14da4a7a0e081567ea297af/aiohttp-3.11.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4e7c7ec4146a94a307ca4f112802a8e26d969018fabed526efc340d21d3e7d0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7f/f4/e50ef78483485bcdae9cf29c9144af2b42457e18175a6ace7c560d89325e/aiohttp-3.11.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8b2df9feac55043759aa89f722a967d977d80f8b5865a4153fc41c93b957efc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8b/92/b6bd4b89304eee827cf07a40b98af171342cddfa1f8b02b55cd0485b9d4f/aiohttp-3.11.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7571f99525c76a6280f5fe8e194eeb8cb4da55586c3c61c59c33a33f10cfce7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c7/21/f3230a9f78bb4a4c4462040bf8425ebb673e3773dd17fd9d06d1af43a955/aiohttp-3.11.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b59d096b5537ec7c85954cb97d821aae35cfccce3357a2cafe85660cc6295628" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8e/12/e4fd2616950a39425b739476c3eccc820061ea5f892815566d27282e7825/aiohttp-3.11.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b42dbd097abb44b3f1156b4bf978ec5853840802d6eee2784857be11ee82c6a0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6a/7c/3f82c2fdcca53cc8732fa342abbe0372bbbd8af3162d6629ac0a7dc8b281/aiohttp-3.11.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b05774864c87210c531b48dfeb2f7659407c2dda8643104fb4ae5e2c311d12d9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/aa/3e/60af2d40f78612062788c2bf6be38738f9525750d3a7678d31f950047536/aiohttp-3.11.14-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4e2e8ef37d4bc110917d038807ee3af82700a93ab2ba5687afae5271b8bc50ff" }, - { url = "https://mirrors.aliyun.com/pypi/packages/08/71/93e11c4ef9a72f5f26d7e9f92294707437fae8de49c2019ed713dea7625b/aiohttp-3.11.14-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e9faafa74dbb906b2b6f3eb9942352e9e9db8d583ffed4be618a89bd71a4e914" }, - { url = "https://mirrors.aliyun.com/pypi/packages/da/4b/77b170ae7eb9859d80b9648a7439991425663f66422f3ef0b27f29bde9d0/aiohttp-3.11.14-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7e7abe865504f41b10777ac162c727af14e9f4db9262e3ed8254179053f63e6d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/02/0b/5fcad20243799e9a3f326140d3d767884449e293fb5d8fca10f83001787c/aiohttp-3.11.14-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4848ae31ad44330b30f16c71e4f586cd5402a846b11264c412de99fa768f00f3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3f/e3/bb454add253f939c7331794b2619c156ef5a108403000221ff2dc01f9072/aiohttp-3.11.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d0b46abee5b5737cb479cc9139b29f010a37b1875ee56d142aefc10686a390b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/08/6b061de352a614461a4a19e60a87e578fe28e1d3fca38315484a17ff484f/aiohttp-3.11.14-cp310-cp310-win32.whl", hash = "sha256:a0d2c04a623ab83963576548ce098baf711a18e2c32c542b62322a0b4584b990" }, - { url = "https://mirrors.aliyun.com/pypi/packages/91/f7/533384607d35a8c7a9dbe4497cee7899aa7c3b29c14cd83373c0f415bdcf/aiohttp-3.11.14-cp310-cp310-win_amd64.whl", hash = "sha256:5409a59d5057f2386bb8b8f8bbcfb6e15505cedd8b2445db510563b5d7ea1186" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b3/f5/5e2ae82822b1781f828bb9285fb585a4ac028cfd329788caf073bde45706/aiohttp-3.11.14-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f296d637a50bb15fb6a229fbb0eb053080e703b53dbfe55b1e4bb1c5ed25d325" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2f/eb/a0e118c54eb9f897e13e7a357b2ef9b8d0ca438060a9db8ad4af4561aab4/aiohttp-3.11.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ec6cd1954ca2bbf0970f531a628da1b1338f594bf5da7e361e19ba163ecc4f3b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/3f/03c2f177536ad6ab4d3052e21fb67ce430d0257b3c61a0ef6b91b7b12cb4/aiohttp-3.11.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:572def4aad0a4775af66d5a2b5923c7de0820ecaeeb7987dcbccda2a735a993f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d8/fe/849c000be857f60e36d2ce0a8c3d1ad34f8ea64b0ff119ecdafbc94cddfb/aiohttp-3.11.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c68e41c4d576cd6aa6c6d2eddfb32b2acfb07ebfbb4f9da991da26633a3db1a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a8/e9/737aef162bf618f3b3e0f4a6ed03b5baca5e2a9ffabdab4be1b756ca1061/aiohttp-3.11.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b8bbfc8111826aa8363442c0fc1f5751456b008737ff053570f06a151650b3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/15/19/a510c51e5a383ad804e51040819898d074106dc297adf0e2c78dccc8ab47/aiohttp-3.11.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b0a200e85da5c966277a402736a96457b882360aa15416bf104ca81e6f5807b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/51/66/30b217d0de5584650340025a285f1d0abf2039e5a683342891e84f250da9/aiohttp-3.11.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d173c0ac508a2175f7c9a115a50db5fd3e35190d96fdd1a17f9cb10a6ab09aa1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/27/90/9f61d0c7b185e5a413ae7a3e206e7759ea1b208fff420b380ab205ab82b5/aiohttp-3.11.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:413fe39fd929329f697f41ad67936f379cba06fcd4c462b62e5b0f8061ee4a77" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c9/5a/455a6b8aea18ec8590f0a5642caf6d0494152de09579a4fd4f9530a4a111/aiohttp-3.11.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65c75b14ee74e8eeff2886321e76188cbe938d18c85cff349d948430179ad02c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f5/4b/b369e5e809bdb46a306df7b22e611dc8622ebb5313498c11f6e1cb986408/aiohttp-3.11.14-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:321238a42ed463848f06e291c4bbfb3d15ba5a79221a82c502da3e23d7525d06" }, - { url = "https://mirrors.aliyun.com/pypi/packages/25/ac/a211dd149485e7c518481b08d7c13e7acd32090daf1e396aaea6b9f2eea9/aiohttp-3.11.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:59a05cdc636431f7ce843c7c2f04772437dd816a5289f16440b19441be6511f1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/74/c4/8b1d41853f1ccd4cb66edc909ccc2a95b332081661f04324f7064cc200d8/aiohttp-3.11.14-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:daf20d9c3b12ae0fdf15ed92235e190f8284945563c4b8ad95b2d7a31f331cd3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d9/e2/e244684266722d819f41d7e798ce8bbee3b72420eb684193a076ea1bf18f/aiohttp-3.11.14-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:05582cb2d156ac7506e68b5eac83179faedad74522ed88f88e5861b78740dc0e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e9/59/79d37f2badafbe229c7654dbf631b38419fcaa979a45c04941397ad7251c/aiohttp-3.11.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:12c5869e7ddf6b4b1f2109702b3cd7515667b437da90a5a4a50ba1354fe41881" }, - { url = "https://mirrors.aliyun.com/pypi/packages/04/0f/aaaf3fc8533f65eba4572a79a935b9033e663f67f763b10db16f1c40a067/aiohttp-3.11.14-cp311-cp311-win32.whl", hash = "sha256:92868f6512714efd4a6d6cb2bfc4903b997b36b97baea85f744229f18d12755e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/07/3c/aa468550b7fcd0c634d4aa8192f33ce32a179ecba08b908a0ed272194f87/aiohttp-3.11.14-cp311-cp311-win_amd64.whl", hash = "sha256:bccd2cb7aa5a3bfada72681bdb91637094d81639e116eac368f8b3874620a654" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/ca/e4acb3b41f9e176f50960f7162d656e79bed151b1f911173b2c4a6c0a9d2/aiohttp-3.11.14-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:70ab0f61c1a73d3e0342cedd9a7321425c27a7067bebeeacd509f96695b875fc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/84/d5/dcf870e0b11f0c1e3065b7f17673485afa1ddb3d630ccd8f328bccfb459f/aiohttp-3.11.14-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:602d4db80daf4497de93cb1ce00b8fc79969c0a7cf5b67bec96fa939268d806a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/f0/dc417d819ae26be6abcd72c28af99d285887fddbf76d4bbe46346f201870/aiohttp-3.11.14-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a8a0d127c10b8d89e69bbd3430da0f73946d839e65fec00ae48ca7916a31948" }, - { url = "https://mirrors.aliyun.com/pypi/packages/28/db/f7deb0862ebb821aa3829db20081a122ba67ffd149303f2d5202e30f20cd/aiohttp-3.11.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9f835cdfedcb3f5947304e85b8ca3ace31eef6346d8027a97f4de5fb687534" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5e/0d/8bf0619e21c6714902c44ab53e275deb543d4d2e68ab2b7b8fe5ba267506/aiohttp-3.11.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8aa5c68e1e68fff7cd3142288101deb4316b51f03d50c92de6ea5ce646e6c71f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f5/10/204b3700bb57b30b9e759d453fcfb3ad79a3eb18ece4e298aaf7917757dd/aiohttp-3.11.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b512f1de1c688f88dbe1b8bb1283f7fbeb7a2b2b26e743bb2193cbadfa6f307" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cc/39/3f65072614c62a315a951fda737e4d9e6e2703f1da0cd2f2d8f629e6092e/aiohttp-3.11.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc9253069158d57e27d47a8453d8a2c5a370dc461374111b5184cf2f147a3cc3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/73/77/cc06ecea173f9bee2f20c8e32e2cf4c8e03909a707183cdf95434db4993e/aiohttp-3.11.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b2501f1b981e70932b4a552fc9b3c942991c7ae429ea117e8fba57718cdeed0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/87/75/5bd424bcd90c7eb2f50fd752d013db4cefb447deeecfc5bc4e8e0b1c74dd/aiohttp-3.11.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:28a3d083819741592685762d51d789e6155411277050d08066537c5edc4066e6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/81/f0/ce936ec575e0569f91e5c8374086a6f7760926f16c3b95428fb55d6bfe91/aiohttp-3.11.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0df3788187559c262922846087e36228b75987f3ae31dd0a1e5ee1034090d42f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/68/b7/5216590b99b5b1f18989221c25ac9d9a14a7b0c3c4ae1ff728e906c36430/aiohttp-3.11.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e73fa341d8b308bb799cf0ab6f55fc0461d27a9fa3e4582755a3d81a6af8c09" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a5/c2/c27061c4ab93fa25f925c7ebddc10c20d992dbbc329e89d493811299dc93/aiohttp-3.11.14-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:51ba80d473eb780a329d73ac8afa44aa71dfb521693ccea1dea8b9b5c4df45ce" }, - { url = "https://mirrors.aliyun.com/pypi/packages/09/f5/11b2da82f2c52365a5b760a4e944ae50a89cf5fb207024b7853615254584/aiohttp-3.11.14-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8d1dd75aa4d855c7debaf1ef830ff2dfcc33f893c7db0af2423ee761ebffd22b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/03/7f/145e23fe0a4c45b256f14c3268ada5497d487786334721ae8a0c818ee516/aiohttp-3.11.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41cf0cefd9e7b5c646c2ef529c8335e7eafd326f444cc1cdb0c47b6bc836f9be" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1c/78/627dba6ee9fb9439e2e29b521adb1135877a9c7b54811fec5c46e59f2fc8/aiohttp-3.11.14-cp312-cp312-win32.whl", hash = "sha256:948abc8952aff63de7b2c83bfe3f211c727da3a33c3a5866a0e2cf1ee1aa950f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3f/5f/1737cf6fcf0524693a4aeff8746530b65422236761e7bfdd79c6d2ce2e1c/aiohttp-3.11.14-cp312-cp312-win_amd64.whl", hash = "sha256:3b420d076a46f41ea48e5fcccb996f517af0d406267e31e6716f480a3d50d65c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/dc/ef9394bde9080128ad401ac7ede185267ed637df03b51f05d14d1c99ad67/aiohttp-3.12.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b6fc902bff74d9b1879ad55f5404153e2b33a82e72a95c89cec5eb6cc9e92fbc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/42/63fccfc3a7ed97eb6e1a71722396f409c46b60a0552d8a56d7aad74e0df5/aiohttp-3.12.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:098e92835b8119b54c693f2f88a1dec690e20798ca5f5fe5f0520245253ee0af" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/a2/7b8a020549f66ea2a68129db6960a762d2393248f1994499f8ba9728bbed/aiohttp-3.12.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:40b3fee496a47c3b4a39a731954c06f0bd9bd3e8258c059a4beb76ac23f8e421" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/f5/d11e088da9176e2ad8220338ae0000ed5429a15f3c9dfd983f39105399cd/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ce13fcfb0bb2f259fb42106cdc63fa5515fb85b7e87177267d89a771a660b79" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/6b/b60ce2757e2faed3d70ed45dafee48cee7bfb878785a9423f7e883f0639c/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3beb14f053222b391bf9cf92ae82e0171067cc9c8f52453a0f1ec7c37df12a77" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dd/de/8c9fde2072a1b72c4fadecf4f7d4be7a85b1d9a4ab333d8245694057b4c6/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c39e87afe48aa3e814cac5f535bc6199180a53e38d3f51c5e2530f5aa4ec58c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0c/ad/07f863ca3d895a1ad958a54006c6dafb4f9310f8c2fdb5f961b8529029d3/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5f1b4ce5bc528a6ee38dbf5f39bbf11dd127048726323b72b8e85769319ffc4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/43/2bd482ebe2b126533e8755a49b128ec4e58f1a3af56879a3abdb7b42c54f/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1004e67962efabbaf3f03b11b4c43b834081c9e3f9b32b16a7d97d4708a9abe6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/23/40/2fa9f514c4cf4cbae8d7911927f81a1901838baf5e09a8b2c299de1acfe5/aiohttp-3.12.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8faa08fcc2e411f7ab91d1541d9d597d3a90e9004180edb2072238c085eac8c2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b8/c3/94dc7357bc421f4fb978ca72a201a6c604ee90148f1181790c129396ceeb/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fe086edf38b2222328cdf89af0dde2439ee173b8ad7cb659b4e4c6f385b2be3d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/3f/1f8911fe1844a07001e26593b5c255a685318943864b27b4e0267e840f95/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:79b26fe467219add81d5e47b4a4ba0f2394e8b7c7c3198ed36609f9ba161aecb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4e/46/27bf57a99168c4e145ffee6b63d0458b9c66e58bb70687c23ad3d2f0bd17/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b761bac1192ef24e16706d761aefcb581438b34b13a2f069a6d343ec8fb693a5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0f/7e/1d2d9061a574584bb4ad3dbdba0da90a27fdc795bc227def3a46186a8bc1/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e153e8adacfe2af562861b72f8bc47f8a5c08e010ac94eebbe33dc21d677cd5b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/08/98/bee429b52233c4a391980a5b3b196b060872a13eadd41c3a34be9b1469ed/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fc49c4de44977aa8601a00edbf157e9a421f227aa7eb477d9e3df48343311065" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/39/b0314c1ea774df3392751b686104a3938c63ece2b7ce0ba1ed7c0b4a934f/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2776c7ec89c54a47029940177e75c8c07c29c66f73464784971d6a81904ce9d1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/83/3dacb8d3f8f512c8ca43e3fa8a68b20583bd25636ffa4e56ee841ffd79ae/aiohttp-3.12.15-cp310-cp310-win32.whl", hash = "sha256:2c7d81a277fa78b2203ab626ced1487420e8c11a8e373707ab72d189fcdad20a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/f9/470b5daba04d558c9673ca2034f28d067f3202a40e17804425f0c331c89f/aiohttp-3.12.15-cp310-cp310-win_amd64.whl", hash = "sha256:83603f881e11f0f710f8e2327817c82e79431ec976448839f3cd05d7afe8f830" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/19/9e86722ec8e835959bd97ce8c1efa78cf361fa4531fca372551abcc9cdd6/aiohttp-3.12.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d3ce17ce0220383a0f9ea07175eeaa6aa13ae5a41f30bc61d84df17f0e9b1117" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/f9/0a31fcb1a7d4629ac9d8f01f1cb9242e2f9943f47f5d03215af91c3c1a26/aiohttp-3.12.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:010cc9bbd06db80fe234d9003f67e97a10fe003bfbedb40da7d71c1008eda0fe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/62/6c/94846f576f1d11df0c2e41d3001000527c0fdf63fce7e69b3927a731325d/aiohttp-3.12.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f9d7c55b41ed687b9d7165b17672340187f87a773c98236c987f08c858145a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/6c/f766d0aaafcee0447fad0328da780d344489c042e25cd58fde566bf40aed/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc4fbc61bb3548d3b482f9ac7ddd0f18c67e4225aaa4e8552b9f1ac7e6bda9e5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/e5/fb779a05ba6ff44d7bc1e9d24c644e876bfff5abe5454f7b854cace1b9cc/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbc8a7c410bb3ad5d595bb7118147dfbb6449d862cc1125cf8867cb337e8728" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/4e/a22e799c2035f5d6a4ad2cf8e7c1d1bd0923192871dd6e367dafb158b14c/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74dad41b3458dbb0511e760fb355bb0b6689e0630de8a22b1b62a98777136e16" }, + { url = "https://mirrors.aliyun.com/pypi/packages/28/e5/55a33b991f6433569babb56018b2fb8fb9146424f8b3a0c8ecca80556762/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6f0af863cf17e6222b1735a756d664159e58855da99cfe965134a3ff63b0b0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c6/82/1ddf0ea4f2f3afe79dffed5e8a246737cff6cbe781887a6a170299e33204/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b7fe4972d48a4da367043b8e023fb70a04d1490aa7d68800e465d1b97e493b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/96/784c785674117b4cb3877522a177ba1b5e4db9ce0fd519430b5de76eec90/aiohttp-3.12.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6443cca89553b7a5485331bc9bedb2342b08d073fa10b8c7d1c60579c4a7b9bd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/12/8a/8b75f203ea7e5c21c0920d84dd24a5c0e971fe1e9b9ebbf29ae7e8e39790/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c5f40ec615e5264f44b4282ee27628cea221fcad52f27405b80abb346d9f3f8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/0b/a1451543475bb6b86a5cfc27861e52b14085ae232896a2654ff1231c0992/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2abbb216a1d3a2fe86dbd2edce20cdc5e9ad0be6378455b05ec7f77361b3ab50" }, + { url = "https://mirrors.aliyun.com/pypi/packages/55/fd/793a23a197cc2f0d29188805cfc93aa613407f07e5f9da5cd1366afd9d7c/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:db71ce547012a5420a39c1b744d485cfb823564d01d5d20805977f5ea1345676" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ca/bf/23a335a6670b5f5dfc6d268328e55a22651b440fca341a64fccf1eada0c6/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ced339d7c9b5030abad5854aa5413a77565e5b6e6248ff927d3e174baf3badf7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/4f/ed60a591839a9d85d40694aba5cef86dde9ee51ce6cca0bb30d6eb1581e7/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7c7dd29c7b5bda137464dc9bfc738d7ceea46ff70309859ffde8c022e9b08ba7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/e0/444747a9455c5de188c0f4a0173ee701e2e325d4b2550e9af84abb20cdba/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:421da6fd326460517873274875c6c5a18ff225b40da2616083c5a34a7570b685" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/ab/1006278d1ffd13a698e5dd4bfa01e5878f6bddefc296c8b62649753ff249/aiohttp-3.12.15-cp311-cp311-win32.whl", hash = "sha256:4420cf9d179ec8dfe4be10e7d0fe47d6d606485512ea2265b0d8c5113372771b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/10/97/ad2b18700708452400278039272032170246a1bf8ec5d832772372c71f1a/aiohttp-3.12.15-cp311-cp311-win_amd64.whl", hash = "sha256:edd533a07da85baa4b423ee8839e3e91681c7bfa19b04260a469ee94b778bf6d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545" }, + { url = "https://mirrors.aliyun.com/pypi/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34" }, ] [[package]] @@ -117,14 +119,15 @@ wheels = [ [[package]] name = "aiosignal" -version = "1.3.2" +version = "1.4.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "frozenlist" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e" }, ] [[package]] @@ -150,7 +153,7 @@ wheels = [ [[package]] name = "akshare" -version = "1.16.77" +version = "1.17.26" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "aiohttp" }, @@ -171,9 +174,9 @@ dependencies = [ { name = "urllib3" }, { name = "xlrd" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/94/90/ae63cd06d24bbfd0e79b0f4e1ac35a28af30ef9c7b9faee22e90deee3ae7/akshare-1.16.77.tar.gz", hash = "sha256:7f8d9f9fad15dda3d2736c3079ee4726e003701f9450574dc653e6047aa76ecc" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/82/ca/b5eea0a3f2783ce8934495c7364425acbc70a021bdf7e79e8ba02d0ce0a8/akshare-1.17.26.tar.gz", hash = "sha256:3245df116965c46b16bb23da9c0372e61ea802d1f996243d26a64c3e16b513f1" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/51/85/c0ccc7d8b3697997cc36351bb16377a37f31ff92fd82ac2a52c08ce05a0f/akshare-1.16.77-py3-none-any.whl", hash = "sha256:7e330514d2f851bb9938d5b469602918703951cbaa0e0961851ae39249d8a265" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/4a/f40c8adb970514eac84f3c0728ebb5e069f2e2ca202d9e94cbc6f50057fe/akshare-1.17.26-py3-none-any.whl", hash = "sha256:b8216f81336349d1069972c2916e7083a5e06eb21b4a9db2d5051e771c9fd4df" }, ] [[package]] @@ -230,35 +233,23 @@ wheels = [ [[package]] name = "anytree" -version = "2.12.1" +version = "2.13.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -dependencies = [ - { name = "six" }, -] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f9/44/2dd9c5d0c3befe899738b930aa056e003b1441bfbf34aab8fce90b2b7dea/anytree-2.12.1.tar.gz", hash = "sha256:244def434ccf31b668ed282954e5d315b4e066c4940b94aff4a7962d85947830" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bc/a8/eb55fab589c56f9b6be2b3fd6997aa04bb6f3da93b01154ce6fc8e799db2/anytree-2.13.0.tar.gz", hash = "sha256:c9d3aa6825fdd06af7ebb05b4ef291d2db63e62bb1f9b7d9b71354be9d362714" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/6a/fb/ff946843e6b55ae9fda84df3964d6c233cd2261dface789f5be02ab79bc5/anytree-2.12.1-py3-none-any.whl", hash = "sha256:5ea9e61caf96db1e5b3d0a914378d2cd83c269dfce1fb8242ce96589fa3382f0" }, -] - -[[package]] -name = "appdirs" -version = "1.4.4" -source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41" } -wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7b/98/f6aa7fe0783e42be3093d8ef1b0ecdc22c34c0d69640dfb37f56925cb141/anytree-2.13.0-py3-none-any.whl", hash = "sha256:4cbcf10df36b1f1cba131b7e487ff3edafc9d6e932a3c70071b5b768bab901ff" }, ] [[package]] name = "argon2-cffi" -version = "23.1.0" +version = "25.1.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "argon2-cffi-bindings" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741" }, ] [[package]] @@ -339,28 +330,28 @@ wheels = [ [[package]] name = "autograd" -version = "1.7.0" +version = "1.8.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/28/ed/67975d75c0fe71220c8df2370c6c1390805790a641359b502f39c042c0c1/autograd-1.7.0.tar.gz", hash = "sha256:de743fd368d6df523cd37305dcd171861a9752a144493677d2c9f5a56983ff2f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/67/1c/3c24ec03c8ba4decc742b1df5a10c52f98c84ca8797757f313e7bdcdf276/autograd-1.8.0.tar.gz", hash = "sha256:107374ded5b09fc8643ac925348c0369e7b0e73bbed9565ffd61b8fd04425683" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/6d/90/d13cf396989052cadd8511c1878b0913bbce28eeef5feb95710a92e03076/autograd-1.7.0-py3-none-any.whl", hash = "sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/84/ea/e16f0c423f7d83cf8b79cae9452040fb7b2e020c7439a167ee7c317de448/autograd-1.8.0-py3-none-any.whl", hash = "sha256:4ab9084294f814cf56c280adbe19612546a35574d67c574b04933c7d2ecb7d78" }, ] [[package]] name = "azure-core" -version = "1.32.0" +version = "1.35.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "requests" }, { name = "six" }, { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cc/ee/668328306a9e963a5ad9f152cd98c7adad86c822729fd1d2a01613ad1e67/azure_core-1.32.0.tar.gz", hash = "sha256:22b3c35d6b2dae14990f6c1be2912bf23ffe50b220e708a28ab1bb92b1c730e5" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ce/89/f53968635b1b2e53e4aad2dd641488929fef4ca9dfb0b97927fa7697ddf3/azure_core-1.35.0.tar.gz", hash = "sha256:c0be528489485e9ede59b6971eb63c1eaacf83ef53001bfe3904e475e972be5c" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/39/83/325bf5e02504dbd8b4faa98197a44cdf8a325ef259b48326a2b6f17f8383/azure_core-1.32.0-py3-none-any.whl", hash = "sha256:eac191a0efb23bfa83fddf321b27b122b4ec847befa3091fa736a5c32c50d7b4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/78/bf94897361fdd650850f0f2e405b2293e2f12808239046232bdedf554301/azure_core-1.35.0-py3-none-any.whl", hash = "sha256:8db78c72868a58f3de8991eb4d22c4d368fae226dac1002998d6c50437e7dad1" }, ] [[package]] @@ -429,16 +420,16 @@ wheels = [ [[package]] name = "bce-python-sdk" -version = "0.9.29" +version = "0.9.42" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "future" }, { name = "pycryptodome" }, { name = "six" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/51/f6/3237811b0a9fd79ba9fcf4d13085f1a1ea19fee43b0cbb24189661d787d5/bce_python_sdk-0.9.29.tar.gz", hash = "sha256:326fbd50d57bf6d2fc21d58f589b069e0e84fc0a8733be9575c109293ab08cc4" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/58/37/bee21dab6b4547538a576982de5b7e4c864bab999c46163a7a4c9f385826/bce_python_sdk-0.9.42.tar.gz", hash = "sha256:41a92b785799b41f25753136ddb6a8bb96afcb69015e2fda6a5a429030ffc6b9" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0f/60/b3247bae81d5ecde1a88430ffe8c57ea3f7212c6a6670b540f7d34d2c625/bce_python_sdk-0.9.29-py3-none-any.whl", hash = "sha256:6518dc0ada422acd1841eeabcb7f89cfc07e3bb1a4be3c75945cab953907b555" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/bb/94071e19b45d9922b2d8014ebe553304bfed9ae02a6eaa20a15a6249c49f/bce_python_sdk-0.9.42-py3-none-any.whl", hash = "sha256:b62207e974e9c1a53ef0d71183b3004cca6c8155da3208b51b3dc48b1dee6b86" }, ] [[package]] @@ -695,11 +686,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.1.31" +version = "2025.7.14" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b3/76/52c535bcebe74590f296d6c77c86dabf761c41980e1347a2422e4aa2ae41/certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2" }, ] [[package]] @@ -759,62 +750,62 @@ wheels = [ [[package]] name = "charset-normalizer" -version = "3.4.1" +version = "3.4.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037" }, - { url = "https://mirrors.aliyun.com/pypi/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12" }, - { url = "https://mirrors.aliyun.com/pypi/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77" }, - { url = "https://mirrors.aliyun.com/pypi/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146" }, - { url = "https://mirrors.aliyun.com/pypi/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35" }, - { url = "https://mirrors.aliyun.com/pypi/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85" }, + { url = "https://mirrors.aliyun.com/pypi/packages/95/28/9901804da60055b406e1a1c5ba7aac1276fb77f1dde635aabfc7fd84b8ab/charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/9b/892a8c8af9110935e5adcbb06d9c6fe741b6bb02608c6513983048ba1a18/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7b/a5/4179abd063ff6414223575e008593861d62abfc22455b5d1a44995b7c101/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/95/bc08c7dfeddd26b4be8c8287b9bb055716f31077c8b0ea1cd09553794665/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/2d/7a5b635aa65284bf3eab7653e8b4151ab420ecbae918d3e359d1947b4d61/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ae/38/51fc6ac74251fd331a8cfdb7ec57beba8c23fd5493f1050f71c87ef77ed0/charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b7/17/edee1e32215ee6e9e46c3e482645b46575a44a2d72c7dfd49e49f60ce6bf/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/26/2c/ea3e66f2b5f21fd00b2825c94cafb8c326ea6240cd80a91eb09e4a285830/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/52/47/7be7fa972422ad062e909fd62460d45c3ef4c141805b7078dbab15904ff7/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/42/9f02c194da282b2b340f28e5fb60762de1151387a36842a92b533685c61e/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/44/89cacd6628f31fb0b63201a618049be4be2a7435a31b55b5eb1c3674547a/charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/79/4b8da9f712bc079c0f16b6d67b099b0b8d808c2292c937f267d816ec5ecc/charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/d7/96970afb4fb66497a40761cdf7bd4f6fca0fc7bafde3a84f836c1f57a926/charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/85/4c40d00dcc6284a1c1ad5de5e0996b06f39d8232f1031cd23c2f5c07ee86/charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/41/d9/7a6c0b9db952598e97e93cbdfcb91bacd89b9b88c7c983250a77c008703c/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645" }, + { url = "https://mirrors.aliyun.com/pypi/packages/66/82/a37989cda2ace7e37f36c1a8ed16c58cf48965a79c2142713244bf945c89/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/df/68/a576b31b694d07b53807269d05ec3f6f1093e9545e8607121995ba7a8313/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/9b/ad67f03d74554bed3aefd56fe836e1623a50780f7c998d00ca128924a499/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/e6/8aebae25e328160b20e31a7e9929b1578bbdc7f42e66f46595a432f8539e/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8b/f2/b3c2f07dbcc248805f10e67a0262c93308cfa149a4cd3d1fe01f593e5fd2/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/60/5b/c3f3a94bc345bc211622ea59b4bed9ae63c00920e2e8f11824aa5708e8b7/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/4d/ff460c8b474122334c2fa394a3f99a04cf11c646da895f81402ae54f5c42/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a2/2b/b964c6a2fda88611a1fe3d4c400d39c66a42d6c169c924818c848f922415/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/59/2e/d3b9811db26a5ebf444bc0fa4f4be5aa6d76fc6e1c0fd537b16c14e849b6/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/90/07/c5fd7c11eafd561bb51220d600a788f1c8d77c5eef37ee49454cc5c35575/charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/05/5e33dbef7e2f773d672b6d79f10ec633d4a71cd96db6673625838a4fd532/charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0" }, ] [[package]] name = "click" -version = "8.1.8" +version = "8.2.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b" }, ] [[package]] @@ -874,101 +865,165 @@ wheels = [ [[package]] name = "contourpy" -version = "1.3.1" +version = "1.3.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -dependencies = [ - { name = "numpy" }, +resolution-markers = [ + "python_full_version < '3.11' and sys_platform == 'darwin'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/25/c2/fc7193cc5383637ff390a712e88e4ded0452c9fbcf84abe3de5ea3df1866/contourpy-1.3.1.tar.gz", hash = "sha256:dfd97abd83335045a913e3bcc4a09c0ceadbe66580cf573fe961f4a825efa699" } +dependencies = [ + { name = "numpy", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/b2/a3/80937fe3efe0edacf67c9a20b955139a1a622730042c1ea991956f2704ad/contourpy-1.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a045f341a77b77e1c5de31e74e966537bba9f3c4099b35bf4c2e3939dd54cdab" }, - { url = "https://mirrors.aliyun.com/pypi/packages/82/1d/e3eaebb4aa2d7311528c048350ca8e99cdacfafd99da87bc0a5f8d81f2c2/contourpy-1.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:500360b77259914f7805af7462e41f9cb7ca92ad38e9f94d6c8641b089338124" }, - { url = "https://mirrors.aliyun.com/pypi/packages/de/f3/d796b22d1a2b587acc8100ba8c07fb7b5e17fde265a7bb05ab967f4c935a/contourpy-1.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2f926efda994cdf3c8d3fdb40b9962f86edbc4457e739277b961eced3d0b4c1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/f5/0e67902bc4394daee8daa39c81d4f00b50e063ee1a46cb3938cc65585d36/contourpy-1.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adce39d67c0edf383647a3a007de0a45fd1b08dedaa5318404f1a73059c2512b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1f/d6/e766395723f6256d45d6e67c13bb638dd1fa9dc10ef912dc7dd3dcfc19de/contourpy-1.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abbb49fb7dac584e5abc6636b7b2a7227111c4f771005853e7d25176daaf8453" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a9/57/86c500d63b3e26e5b73a28b8291a67c5608d4aa87ebd17bd15bb33c178bc/contourpy-1.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0cffcbede75c059f535725c1680dfb17b6ba8753f0c74b14e6a9c68c29d7ea3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b8/62/bb146d1289d6b3450bccc4642e7f4413b92ebffd9bf2e91b0404323704a7/contourpy-1.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab29962927945d89d9b293eabd0d59aea28d887d4f3be6c22deaefbb938a7277" }, - { url = "https://mirrors.aliyun.com/pypi/packages/18/04/9f7d132ce49a212c8e767042cc80ae390f728060d2eea47058f55b9eff1c/contourpy-1.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974d8145f8ca354498005b5b981165b74a195abfae9a8129df3e56771961d595" }, - { url = "https://mirrors.aliyun.com/pypi/packages/46/23/196813901be3f97c83ababdab1382e13e0edc0bb4e7b49a7bff15fcf754e/contourpy-1.3.1-cp310-cp310-win32.whl", hash = "sha256:ac4578ac281983f63b400f7fe6c101bedc10651650eef012be1ccffcbacf3697" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e0/82/c372be3fc000a3b2005061ca623a0d1ecd2eaafb10d9e883a2fc8566e951/contourpy-1.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:174e758c66bbc1c8576992cec9599ce8b6672b741b5d336b5c74e35ac382b18e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/12/bb/11250d2906ee2e8b466b5f93e6b19d525f3e0254ac8b445b56e618527718/contourpy-1.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8b974d8db2c5610fb4e76307e265de0edb655ae8169e8b21f41807ccbeec4b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/67/71/1e6e95aee21a500415f5d2dbf037bf4567529b6a4e986594d7026ec5ae90/contourpy-1.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20914c8c973f41456337652a6eeca26d2148aa96dd7ac323b74516988bea89fc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/2c/b88986e8d79ac45efe9d8801ae341525f38e087449b6c2f2e6050468a42c/contourpy-1.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d40d37c1c3a4961b4619dd9d77b12124a453cc3d02bb31a07d58ef684d3d86" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c4/18/65280989b151fcf33a8352f992eff71e61b968bef7432fbfde3a364f0730/contourpy-1.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:113231fe3825ebf6f15eaa8bc1f5b0ddc19d42b733345eae0934cb291beb88b6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f5/c7/5fd0146c93220dbfe1a2e0f98969293b86ca9bc041d6c90c0e065f4619ad/contourpy-1.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dbbc03a40f916a8420e420d63e96a1258d3d1b58cbdfd8d1f07b49fcbd38e85" }, - { url = "https://mirrors.aliyun.com/pypi/packages/85/fc/7fa5d17daf77306840a4e84668a48ddff09e6bc09ba4e37e85ffc8e4faa3/contourpy-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a04ecd68acbd77fa2d39723ceca4c3197cb2969633836ced1bea14e219d077c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ef/e7/104065c8270c7397c9571620d3ab880558957216f2b5ebb7e040f85eeb22/contourpy-1.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c414fc1ed8ee1dbd5da626cf3710c6013d3d27456651d156711fa24f24bd1291" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e2/4a/c788d0bdbf32c8113c2354493ed291f924d4793c4a2e85b69e737a21a658/contourpy-1.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:31c1b55c1f34f80557d3830d3dd93ba722ce7e33a0b472cba0ec3b6535684d8f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a6/e6/a2f351a90d955f8b0564caf1ebe4b1451a3f01f83e5e3a414055a5b8bccb/contourpy-1.3.1-cp311-cp311-win32.whl", hash = "sha256:f611e628ef06670df83fce17805c344710ca5cde01edfdc72751311da8585375" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a8/7e/cd93cab453720a5d6cb75588cc17dcdc08fc3484b9de98b885924ff61900/contourpy-1.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b2bdca22a27e35f16794cf585832e542123296b4687f9fd96822db6bae17bfc9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/6b/175f60227d3e7f5f1549fcb374592be311293132207e451c3d7c654c25fb/contourpy-1.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ffa84be8e0bd33410b17189f7164c3589c229ce5db85798076a3fa136d0e509" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6b/6a/7833cfae2c1e63d1d8875a50fd23371394f540ce809d7383550681a1fa64/contourpy-1.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805617228ba7e2cbbfb6c503858e626ab528ac2a32a04a2fe88ffaf6b02c32bc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7f/b3/7859efce66eaca5c14ba7619791b084ed02d868d76b928ff56890d2d059d/contourpy-1.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade08d343436a94e633db932e7e8407fe7de8083967962b46bdfc1b0ced39454" }, - { url = "https://mirrors.aliyun.com/pypi/packages/48/b2/011415f5e3f0a50b1e285a0bf78eb5d92a4df000553570f0851b6e309076/contourpy-1.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47734d7073fb4590b4a40122b35917cd77be5722d80683b249dac1de266aac80" }, - { url = "https://mirrors.aliyun.com/pypi/packages/84/7d/ef19b1db0f45b151ac78c65127235239a8cf21a59d1ce8507ce03e89a30b/contourpy-1.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ba94a401342fc0f8b948e57d977557fbf4d515f03c67682dd5c6191cb2d16ec" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ba/99/6794142b90b853a9155316c8f470d2e4821fe6f086b03e372aca848227dd/contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efa874e87e4a647fd2e4f514d5e91c7d493697127beb95e77d2f7561f6905bd9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3c/0f/37d2c84a900cd8eb54e105f4fa9aebd275e14e266736778bb5dccbf3bbbb/contourpy-1.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1bf98051f1045b15c87868dbaea84f92408337d4f81d0e449ee41920ea121d3b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3a/8a/deb5e11dc7d9cc8f0f9c8b29d4f062203f3af230ba83c30a6b161a6effc9/contourpy-1.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61332c87493b00091423e747ea78200659dc09bdf7fd69edd5e98cef5d3e9a8d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1a/35/7e267ae7c13aaf12322ccc493531f1e7f2eb8fba2927b9d7a05ff615df7a/contourpy-1.3.1-cp312-cp312-win32.whl", hash = "sha256:e914a8cb05ce5c809dd0fe350cfbb4e881bde5e2a38dc04e3afe1b3e58bd158e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a1/35/c2de8823211d07e8a79ab018ef03960716c5dff6f4d5bff5af87fd682992/contourpy-1.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:08d9d449a61cf53033612cb368f3a1b26cd7835d9b8cd326647efe43bca7568d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3e/4f/e56862e64b52b55b5ddcff4090085521fc228ceb09a88390a2b103dccd1b/contourpy-1.3.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b457d6430833cee8e4b8e9b6f07aa1c161e5e0d52e118dc102c8f9bd7dd060d6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b0/2e/52bfeeaa4541889f23d8eadc6386b442ee2470bd3cff9baa67deb2dd5c57/contourpy-1.3.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb76c1a154b83991a3cbbf0dfeb26ec2833ad56f95540b442c73950af2013750" }, - { url = "https://mirrors.aliyun.com/pypi/packages/52/94/86bfae441707205634d80392e873295652fc313dfd93c233c52c4dc07874/contourpy-1.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:44a29502ca9c7b5ba389e620d44f2fbe792b1fb5734e8b931ad307071ec58c53" }, + { url = "https://mirrors.aliyun.com/pypi/packages/12/a3/da4153ec8fe25d263aa48c1a4cbde7f49b59af86f0b6f7862788c60da737/contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/6c/330de89ae1087eb622bfca0177d32a7ece50c3ef07b28002de4757d9d875/contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c1/bd/20c6726b1b7f81a8bee5271bed5c165f0a8e1f572578a9d27e2ccb763cb2/contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/fc/a9665c88f8a2473f823cf1ec601de9e5375050f1958cbb356cdf06ef1ab6/contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/25/eb/9f0a0238f305ad8fb7ef42481020d6e20cf15e46be99a1fcf939546a177e/contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/5c/1ee32d1c7956923202f00cf8d2a14a62ed7517bdc0ee1e55301227fc273c/contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631" }, + { url = "https://mirrors.aliyun.com/pypi/packages/83/bf/9baed89785ba743ef329c2b07fd0611d12bfecbedbdd3eeecf929d8d3b52/contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/cc/74e5e83d1e35de2d28bd97033426b450bc4fd96e092a1f7a63dc7369b55d/contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0c/42/17f3b798fd5e033b46a16f8d9fcb39f1aba051307f5ebf441bad1ecf78f8/contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/ec/5162b8582f2c994721018d0c9ece9dc6ff769d298a8ac6b6a652c307e7df/contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b3/b9/ede788a0b56fc5b071639d06c33cb893f68b1178938f3425debebe2dab78/contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/75/3469f011d64b8bbfa04f709bfc23e1dd71be54d05b1b083be9f5b22750d1/contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8d/2f/95adb8dae08ce0ebca4fd8e7ad653159565d9739128b2d5977806656fcd2/contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c3/a6/8ccf97a50f31adfa36917707fe39c9a0cbc24b3bbb58185577f119736cc9/contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1d/b6/7925ab9b77386143f39d9c3243fdd101621b4532eb126743201160ffa7e6/contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/f3/20c5d1ef4f4748e52d60771b8560cf00b69d5c6368b5c2e9311bcfa2a08b/contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8c/e5/9dae809e7e0b2d9d70c52b3d24cba134dd3dad979eb3e5e71f5df22ed1f5/contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/4a/0058ba34aeea35c0b442ae61a4f4d4ca84d6df8f91309bc2d43bb8dd248f/contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/33/7174bdfc8b7767ef2c08ed81244762d93d5c579336fc0b51ca57b33d1b80/contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5e/fe/4029038b4e1c4485cef18e480b0e2cd2d755448bb071eb9977caac80b77b/contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/f7/44785876384eff370c251d58fd65f6ad7f39adce4a093c934d4a67a7c6b6/contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/3b/0004767622a9826ea3d95f0e9d98cd8729015768075d61f9fea8eeca42a8/contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/bb/7bd49e1f4fa805772d9fd130e0d375554ebc771ed7172f48dfcd4ca61549/contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fc/97/e1d5dbbfa170725ef78357a9a0edc996b09ae4af170927ba8ce977e60a5f/contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6f/66/e69e6e904f5ecf6901be3dd16e7e54d41b6ec6ae3405a535286d4418ffb4/contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/32/b8a1c8965e4f72482ff2d1ac2cd670ce0b542f203c8e1d34e7c3e6925da7/contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/30/c6/12a7e6811d08757c7162a541ca4c5c6a34c0f4e98ef2b338791093518e40/contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2a/8a/bebe5a3f68b484d3a2b8ffaf84704b3e343ef1addea528132ef148e22b3b/contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/db/fcd325f19b5978fb509a7d55e06d99f5f856294c1991097534360b307cf1/contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/c8/fadd0b92ffa7b5eb5949bf340a63a4a496a6930a6c37a7ba0f12acb076d6/contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/05/b26e3c6ecc05f349ee0013f0bb850a761016d89cec528a98193a48c34033/contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/25/ac07d6ad12affa7d1ffed11b77417d0a6308170f44ff20fa1d5aa6333f03/contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/4d/5bb3192bbe9d3f27e3061a6a8e7733c9120e203cb8515767d30973f71030/contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/c0/91f1215d0d9f9f343e4773ba6c9b89e8c0cc7a64a6263f21139da639d848/contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/79/6be7e90c955c0487e7712660d6cead01fa17bff98e0ea275737cc2bc8e71/contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/68/7f46fb537958e87427d98a4074bcde4b67a70b04900cfc5ce29bc2f556c1/contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5" }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'darwin'", + "python_full_version >= '3.12' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version >= '3.12' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version == '3.11.*' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", +] +dependencies = [ + { name = "numpy", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381" }, + { url = "https://mirrors.aliyun.com/pypi/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69" }, + { url = "https://mirrors.aliyun.com/pypi/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77" }, ] [[package]] name = "cramjam" -version = "2.9.1" +version = "2.11.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c9/68/09b6b5603d21a0c7d4362d513217a5079c47b1b7a88967c52dbef13db183/cramjam-2.9.1.tar.gz", hash = "sha256:336cc591d86cbd225d256813779f46624f857bc9c779db126271eff9ddc524ae" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/14/12/34bf6e840a79130dfd0da7badfb6f7810b8fcfd60e75b0539372667b41b6/cramjam-2.11.0.tar.gz", hash = "sha256:5c82500ed91605c2d9781380b378397012e25127e89d64f460fea6aeac4389b4" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/27/5d/0b03115fa6a95a6dd9be344cd186879b763f1a6fab57ae55ffe2777aa0a7/cramjam-2.9.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:8e82464d1e00fbbb12958999b8471ba5e9f3d9711954505a0a7b378762332e6f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/ac/a17644e182ede7e8e24fb3af038bc2c1cf3dd0447c935cb10409f21d099b/cramjam-2.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d2df8a6511cc08ef1fccd2e0c65e2ebc9f57574ec8376052a76851af5398810" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9e/1e/e6c4f9695e4ba7b9c63160dcbfa76428bd3221930eedeb8f16364ab6f642/cramjam-2.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:21ea784e6c3f1843d3523ae0f03651dd06058b39eeb64beb82ee3b100fa83662" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ab/37/4c81e5d039bdfc75a695abd426e6cdd9ab18a87f65d57837d78936cfa226/cramjam-2.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e0c5d98a4e791f0bbd0ffcb7dae879baeb2dcc357348a8dc2be0a8c10403a2a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b9/bb/3bf3a8877b9a4105b625d710410bd2bc83ef38d4a7fe4eaeb3895d997b2d/cramjam-2.9.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e076fd87089197cb61117c63dbe7712ad5eccb93968860eb3bae09b767bac813" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c3/78/317b7ab6a9b0f24c45d56305a8288cdb6408f855034dc80530ed16a5cc6c/cramjam-2.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d86b44933aea0151e4a2e1e6935448499849045c38167d288ca4c59d5b8cd4e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c5/2d/bc98992c29eb8647196b3bda814fd7ecfba6aff85177d44180be2aa320e8/cramjam-2.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb032549dec897b942ddcf80c1cdccbcb40629f15fc902731dbe6362da49326" }, - { url = "https://mirrors.aliyun.com/pypi/packages/dd/64/a4e54d74110c22477e467586935167d61fc7bae5284d393e76779b214a3e/cramjam-2.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf29b4def86ec503e329fe138842a9b79a997e3beb6c7809b05665a0d291edff" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b0/1a/6ee093bf8a41cf31980175310abbbcdd1a39dadadbe96843112f42cef0fe/cramjam-2.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a36adf7d13b7accfa206e1c917f08924eb905b45aa8e62176509afa7b14db71e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9d/a6/1ae1f1a8ef559c2fab9d6d7f09b19995684e6727e617bf1b73967ee1c6be/cramjam-2.9.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:cf4ea758d98b6fad1b4b2d808d0de690d3162ac56c26968aea0af6524e3eb736" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d9/e6/cf18deeaa0a96e7fc87f0eacde3c97e2893b573ac148ec746655570c18fc/cramjam-2.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4826d6d81ea490fa7a3ae7a4b9729866a945ffac1f77fe57b71e49d6e1b21efd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/90/97/98a8fa24249dc72a936a9a51a81407a399070ba4ceb528d0af291c760eff/cramjam-2.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:335103317475bf992953c58838152a4761fc3c87354000edbfc4d7e57cf05909" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ae/6b/4f71f72bc3405f221ec8bd2ba869e324d5f87ddd58c14bf59f7937ea37ab/cramjam-2.9.1-cp310-cp310-win32.whl", hash = "sha256:258120cb1e3afc3443f756f9de161ed63eed56a2c31f6093e81c571c0f2dc9f6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8e/f4/32639916897d59e94d286b5b22263ce8c2903ecc93a868ebe9443ece8f12/cramjam-2.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c60e5996aa02547d12bc2740d44e90e006b0f93100f53206f7abe6732ad56e69" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6c/28/dd2b62be30ffe1fa8df10c99ba7b46abfbfb2fc6ace6acbbf9264a1a6b48/cramjam-2.9.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9db1debe48060e41a5b91af9193c524e473c57f6105462c5524a41f5aabdb88" }, - { url = "https://mirrors.aliyun.com/pypi/packages/03/c9/fcebeb6f06879af4226337715fbc42ffe543158bcba8c244bba144767897/cramjam-2.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f6f18f0242212d3409d26ce3874937b5b979cebd61f08b633a6ea893c32fc7b6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e8/f3/77032e4f5db4dfcc2b0365f92655b7d6f3fc1527ea5b637f9fb9f8156a65/cramjam-2.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b5b1cd7d39242b2b903cf09cd4696b3a6e04dc537ffa9f3ac8668edae76eecb6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/38/16/52175e94390f57196382783a3386c122ace7656b57339abaacdc9433b609/cramjam-2.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47de0a68f5f4d9951250ef5af31f2a7228132caa9ed60994234f7eb98090d33" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/25/5f7476d127a8d18cd19a2f3fd25c0fe09ef7848069d23aac70bc96385eb6/cramjam-2.9.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e13c9a697881e5e38148958612dc6856967f5ff8cd7bba5ff751f2d6ac020aa4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7b/97/76ff3e1209add6acb7e2aa7997be48dc1f92ad66ee3e8fa1179eb2bb9b44/cramjam-2.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba560244bc1335b420b74e91e35f9d4e7f307a3be3a4603ce0f0d7e15a0acdf0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/69/c4/228e74c30576556d11e54d86f356955cd86ff5e11bbfec74b66ed0dd237d/cramjam-2.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d47fd41ce260cf4f0ff0e788de961fab9e9c6844a05ce55d06ce31e06107bdc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4b/e7/0fd22e12c6a2879abc501979779d4b8cfe8fe692c708c2c0d1664e88fd79/cramjam-2.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84d154fbadece82935396eb6bcb502085d944d2fd13b07a94348364344370c2c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/dd/9c/845592ddf9eb7130ae8bc5958a01d469304a43f8071effe164e2d239e3fa/cramjam-2.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:038df668ffb94d64d67b6ecc59cbd206745a425ffc0402897dde12d89fa6a870" }, - { url = "https://mirrors.aliyun.com/pypi/packages/10/c2/287cc94b7f8e87e3b0c21819d3a5deead99ebfdcb2b2d85cd04011b37292/cramjam-2.9.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:4125d8cd86fa08495d310e80926c2f0563f157b76862e7479f9b2cf94823ea0c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/22/869a1eeea53db4d9fbde6693a2465909762bffeab1a671e193c95b26f99f/cramjam-2.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4206ebdd1d1ef0f3f86c8c2f7c426aa4af6094f4f41e274601fd4c4569f37454" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3f/89/ff988bd6427f01041ccb1a9104c05b6373ae476682d317b6844f4b40af92/cramjam-2.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ab687bef5c493732b9a4ab870542ee43f5eae0025f9c684c7cb399c3a85cb380" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2e/68/13fa8561335de609f3cd40b132c1a3abbaf26d3c277e8b8a7446de34ef2c/cramjam-2.9.1-cp311-cp311-win32.whl", hash = "sha256:dda7698b6d7caeae1047adafebc4b43b2a82478234f6c2b45bc3edad854e0600" }, - { url = "https://mirrors.aliyun.com/pypi/packages/94/75/f3506ee802460e3b86a91e53bba1f67cf457fa04e4316fe7d5823ba5d28b/cramjam-2.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:872b00ff83e84bcbdc7e951af291ebe65eed20b09c47e7c4af21c312f90b796f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/56/66/69a1c17331e38b02c78c923262fc315272de7c2618ef7eac8b3358969d90/cramjam-2.9.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:79417957972553502b217a0093532e48893c8b4ca30ccc941cefe9c72379df7c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3d/17/23d0b1d3301480e924545cdd27f2b949c50438949f64c74e800a09c12c37/cramjam-2.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce2b94117f373defc876f88e74e44049a9969223dbca3240415b71752d0422fb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8e/da/e9565f4abbbaa14645ccd7ce83f9631e90955454b87dc3ef9208aebc72e6/cramjam-2.9.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:67040e0fd84404885ec716a806bee6110f9960c3647e0ef1670aab3b7375a70a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/88/ac/e6e0794ac01deb52e7a6a3e59720699abdee08d9b9c63a8d8874201d8155/cramjam-2.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bedb84e068b53c944bd08dcb501fd00d67daa8a917922356dd559b484ce7eab" }, - { url = "https://mirrors.aliyun.com/pypi/packages/22/0f/c3724b2dcdfbe7e07917803cf7a6db4a874818a6f8d2b95ca1ceaf177170/cramjam-2.9.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:06e3f97a379386d97debf08638a78b3d3850fdf6124755eb270b54905a169930" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ce/16/929a5ae899ad6298f58e66622dc223476fe8e1d4e8dae608f4e1a34bfd09/cramjam-2.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11118675e9c7952ececabc62f023290ee4f8ecf0bee0d2c7eb8d1c402ee9769d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2a/2a/ad473f1ca65d3285e8c1d99fc0289f5856224c0d452dabcf856fd4dcdd77/cramjam-2.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b7de6b61b11545570e4d6033713f3599525efc615ee353a822be8f6b0c65b77" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9b/5a/e9b4868ee27099a2a21646cf5ea5cf08c660eae90b55a395ada974dcf3fb/cramjam-2.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57ca8f3775324a9de3ee6f05ca172687ba258c0dea79f7e3a6b4112834982f2a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5f/c4/870a9b4524107bf85a207b82a42613318881238b20f2d237e62815af646a/cramjam-2.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9847dd6f288f1c56359f52acb48ff2df848ff3e3bff34d23855bbcf7016427cc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/70/4b/b69e8e3951b7cec5e7da2539b7573bb396bed66af07d760b1878b00fd120/cramjam-2.9.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d1248dfa7f151e893ce819670f00879e4b7650b8d4c01279ce4f12140d68dd2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/05/1a/af02f6192060413314735c0db61259d7279b0d8d99eee29eff2af09c5892/cramjam-2.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9da6d970281083bae91b914362de325414aa03c01fc806f6bb2cc006322ec834" }, - { url = "https://mirrors.aliyun.com/pypi/packages/20/9a/a4ab3e90d72eb4f2c1b983fa32b4050ba676f533ba15bd78158f0632295a/cramjam-2.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1c33bc095db5733c841a102b8693062be5db8cdac17b9782ebc00577c6a94480" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/3b/e632dd7e2c5c8a2af2d83144b00d6840f1afcf9c6959ed59ec5b0f925288/cramjam-2.9.1-cp312-cp312-win32.whl", hash = "sha256:9e9193cd4bb57e7acd3af24891526299244bfed88168945efdaa09af4e50720f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0e/a2/d1c46618b81b83578d58a62f3709046c4f3b4ddba10df4b9797cfe096b98/cramjam-2.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:15955dd75e80f66c1ea271167a5347661d9bdc365f894a57698c383c9b7d465c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bc/91/3f7884172573072a4280bc8bc19b7562b2cd66d2a65576b11e72115cd5fe/cramjam-2.9.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:86824c695688fcd06c5ac9bbd3fea9bdfb4cca194b1e706fbf11a629df48d2b4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ef/49/a0a89e9c45413e89a1e408d4ab416c0f88f19f6db7571fd5c517e429e276/cramjam-2.9.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:27571bfa5a5d618604696747d0dc1d2a99b5906c967c8dee53c13a7107edfde6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/26/f7/6422b9e4d148f1a351c0358a95d59023f25cab76609b180804f6a3ed17e9/cramjam-2.9.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb01f6e38719818778144d3165a89ea1ad9dc58c6342b7f20aa194c70f34cbd1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b5/59/6fc930217f7ae085eca6d22d3477cd0145a105cdc39e63b834cb0c1b25e3/cramjam-2.9.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b5cef5cf40725fe64592af9ec163e7389855077700678a1d94bec549403a74d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2d/36/7e53cf5aaed4b446490e298f7571e69ce15d0dfb148feabe8bf02e58827f/cramjam-2.9.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ac48b978aa0675f62b642750e798c394a64d25ce852e4e541f69bef9a564c2f0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/53/d3/20d0402e4e983b66603117ad3dd3b864a05d7997a830206d3ff9cacef9a2/cramjam-2.11.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:d0859c65775e8ebf2cbc084bfd51bd0ffda10266da6f9306451123b89f8e5a63" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/a8/a6e2744288938ccd320a5c6f6f3653faa790f933f5edd088c6e5782a2354/cramjam-2.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1d77b9b0aca02a3f6eeeff27fcd315ca5972616c0919ee38e522cce257bcd349" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/29/7961e09a849eea7d8302e7baa6f829dd3ef3faf199cb25ed29b318ae799b/cramjam-2.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66425bc25b5481359b12a6719b6e7c90ffe76d85d0691f1da7df304bfb8ce45c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7a/60/6665e52f01a8919bf37c43dcf0e03b6dd3866f5c4e95440b357d508ee14e/cramjam-2.11.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bd748d3407ec63e049b3aea1595e218814fccab329b7fb10bb51120a30e9fb7e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/80/79bd84dbeb109e2c6efb74e661b7bd4c3ba393208ebcf69e2ae9454ae80c/cramjam-2.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6d9a23a35b3a105c42a8de60fc2e80281ae6e758f05a3baea0b68eb1ddcb679" }, + { url = "https://mirrors.aliyun.com/pypi/packages/28/ef/b43280767ebcde022ba31f1e9902137655a956ae30e920d75630fa67e36e/cramjam-2.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:40a75b95e05e38a2a055b2446f09994ce1139151721659315151d4ad6289bbff" }, + { url = "https://mirrors.aliyun.com/pypi/packages/60/1c/79d522757c494dfd9e9b208b0604cc7e97b481483cc477144f5705a06ab7/cramjam-2.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5d042c376d2025300da37d65192d06a457918b63b31140f697f85fd8e310b29" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/70/3bf0670380069b3abd4c6b53f61d3148f4e08935569c08efbeaf7550e87d/cramjam-2.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb148b35ab20c75b19a06c27f05732e2a321adbd86fadc93f9466dbd7b1154a7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/db/7e/4f6ca98a4b474348e965a529b359184785d1119ab7c4c9ec1280b8bea50a/cramjam-2.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ee47c220f0f5179ddc923ab91fc9e282c27b29fabc60c433dfe06f08084f798" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/6c/b241511c7ffd5f1da29641429bb0e19b5fbcffafde5ba1bbcbf9394ea456/cramjam-2.11.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0cf1b5a81b21ea175c976c3ab09e00494258f4b49b7995efc86060cced3f0b2e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/5c/4ef926c8c3c1bf6da96f9c53450ff334cdb6d0fc1efced0aea97e2090803/cramjam-2.11.0-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:360c00338ecf48921492455007f904be607fc7818de3d681acbcc542aae2fb36" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/fb/eb2aef7fb2730e56c5a2c9000817ee8fb4a95c92f19cc6e441afed42ec29/cramjam-2.11.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f31fcc0d30dc3f3e94ea6b4d8e1a855071757c6abf6a7b1e284050ab7d4c299c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/80/925a5c668dcee1c6f61775067185c5dc9a63c766d5393e5c60d2af4217a7/cramjam-2.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:033be66fdceb3d63b2c99b257a98380c4ec22c9e4dca54a2bfec3718cd24e184" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/ac/b2819640eef0592a6de7ca832c0d23c69bd1620f765ce88b60dbc8da9ba2/cramjam-2.11.0-cp310-cp310-win32.whl", hash = "sha256:1c6cea67f6000b81f6bd27d14c8a6f62d00336ca7252fd03ee16f6b70eb5c0d2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5a/f4/06af04727b9556721049e2127656d727306d275c518e3d97f9ed4cffd0d8/cramjam-2.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:98aa4a351b047b0f7f9e971585982065028adc2c162c5c23c5d5734c5ccc1077" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/89/8001f6a9b6b6e9fa69bec5319789083475d6f26d52aaea209d3ebf939284/cramjam-2.11.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:04cfa39118570e70e920a9b75c733299784b6d269733dbc791d9aaed6edd2615" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/f3/001d00070ca92e5fbe6aacc768e455568b0cde46b0eb944561a4ea132300/cramjam-2.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:66a18f68506290349a256375d7aa2f645b9f7993c10fc4cc211db214e4e61d2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/35/041a3af01bf3f6158f120070f798546d4383b962b63c35cd91dcbf193e17/cramjam-2.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:50e7d65533857736cd56f6509cf2c4866f28ad84dd15b5bdbf2f8a81e77fa28a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/eb/5358b238808abebd0c949c42635c3751204ca7cf82b29b984abe9f5e33c8/cramjam-2.11.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1f71989668458fc327ac15396db28d92df22f8024bb12963929798b2729d2df5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/79/19dba7c03a27408d8d11b5a7a4a7908459cfd4e6f375b73264dc66517bf6/cramjam-2.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee77ac543f1e2b22af1e8be3ae589f729491b6090582340aacd77d1d757d9569" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a4/ad/40e4b3408501d886d082db465c33971655fe82573c535428e52ab905f4d0/cramjam-2.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ad52784120e7e4d8a0b5b0517d185b8bf7f74f5e17272857ddc8951a628d9be1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/6e/c1b60ceb6d7ea6ff8b0bf197520aefe23f878bf2bfb0de65f2b0c2f82cd1/cramjam-2.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b86f8e6d9c1b3f9a75b2af870c93ceee0f1b827cd2507387540e053b35d7459" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/ad/32a8d5f4b1e3717787945ec6d71bd1c6e6bccba4b7e903fc0d9d4e4b08c3/cramjam-2.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:320d61938950d95da2371b46c406ec433e7955fae9f396c8e1bf148ffc187d11" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/cd/3b5a662736ea62ff7fa4c4a10a85e050bfdaad375cc53dc80427e8afe41c/cramjam-2.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41eafc8c1653a35a5c7e75ad48138f9f60085cc05cd99d592e5298552d944e9f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/26/8e/1dbcfaaa7a702ee82ee683ec3a81656934dd7e04a7bc4ee854033686f98a/cramjam-2.11.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03a7316c6bf763dfa34279335b27702321da44c455a64de58112968c0818ec4a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/62/f11709bfdce74af79a88b410dcb76dedc97612166e759136931bf63cfd7b/cramjam-2.11.0-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:244c2ed8bd7ccbb294a2abe7ca6498db7e89d7eb5e744691dc511a7dc82e65ca" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/6d/3b98b61841a5376d9a9b8468ae58753a8e6cf22be9534a0fa5af4d8621cc/cramjam-2.11.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:405f8790bad36ce0b4bbdb964ad51507bfc7942c78447f25cb828b870a1d86a0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/72/bd5db5c49dbebc8b002f1c4983101b28d2e7fc9419753db1c31ec22b03ef/cramjam-2.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6b1b751a5411032b08fb3ac556160229ca01c6bbe4757bb3a9a40b951ebaac23" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/32/203c57acdb6eea727e7078b2219984e64ed4ad043c996ed56321301ba167/cramjam-2.11.0-cp311-cp311-win32.whl", hash = "sha256:5251585608778b9ac8effed544933df7ad85b4ba21ee9738b551f17798b215ac" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/bd/102d6deb87a8524ac11cddcd31a7612b8f20bf9b473c3c645045e3b957c7/cramjam-2.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:dca88bc8b68ce6d35dafd8c4d5d59a238a56c43fa02b74c2ce5f9dfb0d1ccb46" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/0d/7c84c913a5fae85b773a9dcf8874390f9d68ba0fcc6630efa7ff1541b950/cramjam-2.11.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dba5c14b8b4f73ea1e65720f5a3fe4280c1d27761238378be8274135c60bbc6e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/cc/4f6d185d8a744776f53035e72831ff8eefc2354f46ab836f4bd3c4f6c138/cramjam-2.11.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:11eb40722b3fcf3e6890fba46c711bf60f8dc26360a24876c85e52d76c33b25b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/a8/626c76263085c6d5ded0e71823b411e9522bfc93ba6cc59855a5869296e7/cramjam-2.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aeb26e2898994b6e8319f19a4d37c481512acdcc6d30e1b5ecc9d8ec57e835cb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/52/0851a16a62447532e30ba95a80e638926fdea869a34b4b5b9d0a020083ba/cramjam-2.11.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4f8d82081ed7d8fe52c982bd1f06e4c7631a73fe1fb6d4b3b3f2404f87dc40fe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/76/122e444f59dbc216451d8e3d8282c9665dc79eaf822f5f1470066be1b695/cramjam-2.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:092a3ec26e0a679305018380e4f652eae1b6dfe3fc3b154ee76aa6b92221a17c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a3/bc/3a0189aef1af2b29632c039c19a7a1b752bc21a4053582a5464183a0ad3d/cramjam-2.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:529d6d667c65fd105d10bd83d1cd3f9869f8fd6c66efac9415c1812281196a92" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/80/8a6343b13778ce52d94bb8d5365a30c3aa951276b1857201fe79d7e2ad25/cramjam-2.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:555eb9c90c450e0f76e27d9ff064e64a8b8c6478ab1a5594c91b7bc5c82fd9f0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/df/6b/cd1778a207c29eda10791e3dfa018b588001928086e179fc71254793c625/cramjam-2.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5edf4c9e32493035b514cf2ba0c969d81ccb31de63bd05490cc8bfe3b431674e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dc/f0/5c2a5cd5711032f3b191ca50cb786c17689b4a9255f9f768866e6c9f04d9/cramjam-2.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa2fe41f48c4d58d923803383b0737f048918b5a0d10390de9628bb6272b107" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f9/8b/b363a5fb2c3347504fe9a64f8d0f1e276844f0e532aa7162c061cd1ffee4/cramjam-2.11.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9ca14cf1cabdb0b77d606db1bb9e9ca593b1dbd421fcaf251ec9a5431ec449f3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/78/7b/d83dad46adb6c988a74361f81ad9c5c22642be53ad88616a19baedd06243/cramjam-2.11.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:309e95bf898829476bccf4fd2c358ec00e7ff73a12f95a3cdeeba4bb1d3683d5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/be/60d9be4cb33d8740a4aa94c7513f2ef3c4eba4fd13536f086facbafade71/cramjam-2.11.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:86dca35d2f15ef22922411496c220f3c9e315d5512f316fe417461971cc1648d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/b0/4a595f01a243aec8ad272b160b161c44351190c35d98d7787919d962e9e5/cramjam-2.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:193c6488bd2f514cbc0bef5c18fad61a5f9c8d059dd56edf773b3b37f0e85496" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/47/7776659aaa677046b77f527106e53ddd47373416d8fcdb1e1a881ec5dc06/cramjam-2.11.0-cp312-cp312-win32.whl", hash = "sha256:514e2c008a8b4fa823122ca3ecab896eac41d9aa0f5fc881bd6264486c204e32" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/b1/d53002729cfd94c5844ddfaf1233c86d29f2dbfc1b764a6562c41c044199/cramjam-2.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:53fed080476d5f6ad7505883ec5d1ec28ba36c2273db3b3e92d7224fe5e463db" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/8f/82e35ec3c5387f1864f46b3c24bce89a07af8bb3ef242ae47281db2c1848/cramjam-2.11.0-pp310-pypy310_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:37bed927abc4a7ae2d2669baa3675e21904d8a038ed8e4313326ea7b3be62b2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/4e/0c821918080a32ba1e52c040e12dd02dada67728f07305c5f778b808a807/cramjam-2.11.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:50e4a58635fa8c6897d84847d6e065eb69f92811670fc5e9f2d9e3b6279a02b6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/fd/848d077bf6abc4ce84273d8e3f3a70d61a2240519a339462f699d8acf829/cramjam-2.11.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3d1ba626dd5f81f7f09bbf59f70b534e2b75e0d6582b056b7bd31b397f1c13e9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/1c/899818999bbdb59c601756b413e87d37fd65875d1315346c10e367bb3505/cramjam-2.11.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c71e140d5eb3145d61d59d0be0bf72f07cc4cf4b32cb136b09f712a3b1040f5f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/26/c2813c5422c43b3dcd8b6645bc359f08870737c44325ee4accc18f24eee0/cramjam-2.11.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a6ed7926a5cca28edebad7d0fedd2ad492710ae3524d25fc59a2b20546d9ce1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/4f/af984f8d7f963f0301812cdd620ddcfd8276461ed7a786c0f89e82b14739/cramjam-2.11.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5eb4ed3cea945b164b0513fd491884993acac2153a27b93a84019c522e8eda82" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/da/b3301962ccd6fce9fefa1ecd8ea479edaeaa38fadb1f34d5391d2587216a/cramjam-2.11.0-pp311-pypy311_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:52d5db3369f95b27b9f3c14d067acb0b183333613363ed34268c9e04560f997f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b6/c2/410ddb8ad4b9dfb129284666293cb6559479645da560f7077dc19d6bee9e/cramjam-2.11.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4820516366d455b549a44d0e2210ee7c4575882dda677564ce79092588321d54" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/99/f68a443c64f7ce7aff5bed369b0aa5b2fac668fa3dfd441837e316e97a1f/cramjam-2.11.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d9e5db525dc0a950a825202f84ee68d89a072479e07da98795a3469df942d301" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6c/02/0ff358ab773def1ee3383587906c453d289953171e9c92db84fdd01bf172/cramjam-2.11.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62ab4971199b2270005359cdc379bc5736071dc7c9a228581c5122d9ffaac50c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/31/3298e15f87c9cf2aabdbdd90b153d8644cf989cb42a45d68a1b71e1f7aaf/cramjam-2.11.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24758375cc5414d3035ca967ebb800e8f24604ececcba3c67d6f0218201ebf2d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c7/90/20d1747255f1ee69a412e319da51ea594c18cca195e7a4d4c713f045eff5/cramjam-2.11.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6c2eea545fef1065c7dd4eda991666fd9c783fbc1d226592ccca8d8891c02f23" }, ] [[package]] @@ -995,47 +1050,49 @@ wheels = [ [[package]] name = "cryptography" -version = "44.0.2" +version = "45.0.5" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/95/1e/49527ac611af559665f71cbb8f92b332b5ec9c6fbc4e88b0f8e92f5e85df/cryptography-45.0.5.tar.gz", hash = "sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181" }, - { url = "https://mirrors.aliyun.com/pypi/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699" }, - { url = "https://mirrors.aliyun.com/pypi/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/10/173be140714d2ebaea8b641ff801cbcb3ef23101a2981cbf08057876f89e/cryptography-44.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2f/b4/424ea2d0fce08c24ede307cead3409ecbfc2f566725d4701b9754c0a1174/cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41" }, - { url = "https://mirrors.aliyun.com/pypi/packages/28/20/8eaa1a4f7c68a1cb15019dbaad59c812d4df4fac6fd5f7b0b9c5177f1edd/cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562" }, - { url = "https://mirrors.aliyun.com/pypi/packages/11/25/5ed9a17d532c32b3bc81cc294d21a36c772d053981c22bd678396bc4ae30/cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/63/31/2aac03b19c6329b62c45ba4e091f9de0b8f687e1b0cd84f101401bece343/cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/ec/6e560908349843718db1a782673f36852952d52a55ab14e46c42c8a7690a/cryptography-44.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d6/d7/f30e75a6aa7d0f65031886fa4a1485c2fbfe25a1896953920f6a9cfe2d3b/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/b4/7a494ce1032323ca9db9a3661894c66e0d7142ad2079a4249303402d8c71/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471" }, - { url = "https://mirrors.aliyun.com/pypi/packages/45/f8/6b3ec0bc56123b344a8d2b3264a325646d2dcdbdd9848b5e6f3d37db90b3/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615" }, - { url = "https://mirrors.aliyun.com/pypi/packages/57/ff/f3b4b2d007c2a646b0f69440ab06224f9cf37a977a72cdb7b50632174e8a/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/fb/09e28bc0c46d2c547085e60897fea96310574c70fb21cd58a730a45f3403/cryptography-45.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b1/05/2194432935e29b91fb649f6149c1a4f9e6d3d9fc880919f4ad1bcc22641e/cryptography-45.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/8b/9ef5da82350175e32de245646b1884fc01124f53eb31164c77f95a08d682/cryptography-45.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7c/e1/c809f398adde1994ee53438912192d92a1d0fc0f2d7582659d9ef4c28b0c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/8b/07eb6bd5acff58406c5e806eff34a124936f41a4fb52909ffa4d00815f8c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ec/ef/3333295ed58d900a13c92806b67e62f27876845a9a908c939f040887cca9/cryptography-45.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/9d/44080674dee514dbb82b21d6fa5d1055368f208304e2ab1828d85c9de8f4/cryptography-45.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/d8/0749f7d39f53f8258e5c18a93131919ac465ee1f9dccaf1b3f420235e0b5/cryptography-45.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/d7/92acac187387bf08902b0bf0699816f08553927bdd6ba3654da0010289b4/cryptography-45.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/c2/840e0710da5106a7c3d4153c7215b2736151bba60bf4491bdb421df5056d/cryptography-45.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/92/cc723dd6d71e9747a887b94eb3827825c6c24b9e6ce2bb33b847d31d5eaa/cryptography-45.0.5-cp311-abi3-win32.whl", hash = "sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/10/197da38a5911a48dd5389c043de4aec4b3c94cb836299b01253940788d78/cryptography-45.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/2b/160ce8c2765e7a481ce57d55eba1546148583e7b6f85514472b1d151711d/cryptography-45.0.5-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/e7/2187be2f871c0221a81f55ee3105d3cf3e273c0a0853651d7011eada0d7e/cryptography-45.0.5-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b9/cf/84210c447c06104e6be9122661159ad4ce7a8190011669afceeaea150524/cryptography-45.0.5-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3e/6a/cb8b5c8bb82fafffa23aeff8d3a39822593cee6e2f16c5ca5c2ecca344f7/cryptography-45.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/04/f7/36d2d69df69c94cbb2473871926daf0f01ad8e00fe3986ac3c1e8c4ca4b3/cryptography-45.0.5-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135" }, + { url = "https://mirrors.aliyun.com/pypi/packages/82/c7/f0ea40f016de72f81288e9fe8d1f6748036cb5ba6118774317a3ffc6022d/cryptography-45.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/ae/94b504dc1a3cdf642d710407c62e86296f7da9e66f27ab12a1ee6fdf005b/cryptography-45.0.5-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/2b/aaf0adb845d5dabb43480f18f7ca72e94f92c280aa983ddbd0bcd6ecd037/cryptography-45.0.5-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492" }, + { url = "https://mirrors.aliyun.com/pypi/packages/91/e4/f17e02066de63e0100a3a01b56f8f1016973a1d67551beaf585157a86b3f/cryptography-45.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f2/2e/e2dbd629481b499b14516eed933f3276eb3239f7cee2dcfa4ee6b44d4711/cryptography-45.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/ea/a78a0c38f4c8736287b71c2ea3799d173d5ce778c7d6e3c163a95a05ad2a/cryptography-45.0.5-cp37-abi3-win32.whl", hash = "sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/b3/28ac139109d9005ad3f6b6f8976ffede6706a6478e21c889ce36c840918e/cryptography-45.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/8b/34394337abe4566848a2bd49b26bcd4b07fd466afd3e8cce4cb79a390869/cryptography-45.0.5-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8b/5d/a19441c1e89afb0f173ac13178606ca6fab0d3bd3ebc29e9ed1318b507fc/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4b/db/daceb259982a3c2da4e619f45b5bfdec0e922a23de213b2636e78ef0919b/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/35/5d06ad06402fc522c8bf7eab73422d05e789b4e38fe3206a85e3d6966c11/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30" }, + { url = "https://mirrors.aliyun.com/pypi/packages/65/79/020a5413347e44c382ef1f7f7e7a66817cd6273e3e6b5a72d18177b08b2f/cryptography-45.0.5-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9b/c5/c0e07d84a9a2a8a0ed4f865e58f37c71af3eab7d5e094ff1b21f3f3af3bc/cryptography-45.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c0/71/9bdbcfd58d6ff5084687fe722c58ac718ebedbc98b9f8f93781354e6d286/cryptography-45.0.5-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/63/83516cfb87f4a8756eaa4203f93b283fda23d210fc14e1e594bd5f20edb6/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/11/d2823d2a5a0bd5802b3565437add16f5c8ce1f0778bf3822f89ad2740a38/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/38/6bf177ca6bce4fe14704ab3e93627c5b0ca05242261a2e43ef3168472540/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/6a/69fc67e5266bff68a91bcb81dff8fb0aba4d79a78521a08812048913e16f/cryptography-45.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f6/34/31a1604c9a9ade0fdab61eb48570e09a796f4d9836121266447b0eaf7feb/cryptography-45.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f" }, ] [[package]] @@ -1047,6 +1104,26 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/ee/58/257350f7db99b4ae12b614a36256d9cc870d71d9e451e79c2dc3b23d7c3c/cssselect-1.3.0-py3-none-any.whl", hash = "sha256:56d1bf3e198080cc1667e137bc51de9cadfca259f03c2d4e09037b3e01e30f0d" }, ] +[[package]] +name = "curl-cffi" +version = "0.12.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "certifi" }, + { name = "cffi" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f4/91/feaf237ab7c5e06cc0a87ed7acdfbd4103beaa3ca5666d78e80b4a044e47/curl_cffi-0.12.0.tar.gz", hash = "sha256:01770d120e2ab82ad076687c7038abe4d614c7e13d7a5378520b027df529dbe7" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/da/58/587f76b06fd7c4176b033275ab63b90e32b6904e5d7c7844311584376cdc/curl_cffi-0.12.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e663d6692aa923a60fd2f050dad4cccd317dc7dd3d9edceb5230f68017e811eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cd/74/e63d74451dcd0a793da1983024f36bbe400e8a3be8eaf860c004f66d489a/curl_cffi-0.12.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:8f7f1745700fcd4f6d5681cdca27426cc3005c3e17ca9a66fe5753c5001a7314" }, + { url = "https://mirrors.aliyun.com/pypi/packages/13/83/10addc9189c8eeb35e7b4c13033e84e174f534caef5df9f520403bcd546d/curl_cffi-0.12.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:368dd6e354933c62d3b35afbecdc5e7e7817ba748db0d23f7276f89b7eec49e8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3f/fd/700edf216767c0e25632e24ec66dfb4a047cf6966d3246507f8a384970cd/curl_cffi-0.12.0-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1df994f9ccf27b391259ba0157d415b1e60f01e59914f75280cb9c1eceb3a3c8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/0b/559443dd7fcdeb424f353c239db3aa0421659f9bab26a89fc65b703cb486/curl_cffi-0.12.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18aadb313a1fe23098e867f9e6e42c57c5c68985521a1fe5fb8ca15bb990341b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/4f/000397ecd769d663dbfdaea10173e4ee860379118c81e40d27faea4382c6/curl_cffi-0.12.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:c0875e85eda5a5314bf1974ad1ecdcdd61811759b820b6617ec7be6daf85a1a3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/aa/01/2ff55d2d73b0d4605fff32112b33894e6b6d79106406d9e1185d680e8930/curl_cffi-0.12.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b9650b85964ed06c634cfff4ce926255b80195f73edf629a1272b1a19908811d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/6e/0194d04312fbf6eed0d0fea6dfd361795fcfd53e9dca259a8ad45ff1ccca/curl_cffi-0.12.0-cp39-abi3-win_amd64.whl", hash = "sha256:cdcbc492a68b7f3592a4dc4eb742281aa74d220f55affbd84645795a7fdb3ddc" }, +] + [[package]] name = "cycler" version = "0.12.1" @@ -1071,10 +1148,9 @@ wheels = [ [[package]] name = "datasets" -version = "3.4.1" +version = "4.0.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "aiohttp" }, { name = "dill" }, { name = "filelock" }, { name = "fsspec", extra = ["http"] }, @@ -1089,9 +1165,9 @@ dependencies = [ { name = "tqdm" }, { name = "xxhash" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/99/4b/40cda74a4e0e58450b0c85a737e134ab5df65e6f5c33c5e175db5d6a5227/datasets-3.4.1.tar.gz", hash = "sha256:e23968da79bc014ef9f7540eeb7771c6180eae82c86ebcfcc10535a03caf08b5" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e3/9d/348ed92110ba5f9b70b51ca1078d4809767a835aa2b7ce7e74ad2b98323d/datasets-4.0.0.tar.gz", hash = "sha256:9657e7140a9050db13443ba21cb5de185af8af944479b00e7ff1e00a61c8dbf1" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/16/44/5de560a2625d31801895fb2663693df210c6465960d61a99192caa9afd63/datasets-3.4.1-py3-none-any.whl", hash = "sha256:b91cf257bd64132fa9d953dd4768ab6d63205597301f132a74271cfcce8b5dd3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/62/eb8157afb21bd229c864521c1ab4fa8e9b4f1b06bafdd8c4668a7a31b5dd/datasets-4.0.0-py3-none-any.whl", hash = "sha256:7ef95e62025fd122882dbce6cb904c8cd3fbc829de6669a5eb939c77d50e203d" }, ] [[package]] @@ -1099,26 +1175,29 @@ name = "datrie" version = "0.8.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } sdist = { url = "https://mirrors.aliyun.com/pypi/packages/9d/fe/db74bd405d515f06657f11ad529878fd389576dca4812bea6f98d9b31574/datrie-0.8.2.tar.gz", hash = "sha256:525b08f638d5cf6115df6ccd818e5a01298cd230b2dac91c8ff2e6499d18765d" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/44/02/53f0cf0bf0cd629ba6c2cc13f2f9db24323459e9c19463783d890a540a96/datrie-0.8.2-pp273-pypy_73-win32.whl", hash = "sha256:b07bd5fdfc3399a6dab86d6e35c72b1dbd598e80c97509c7c7518ab8774d3fda" }, +] [[package]] name = "debugpy" -version = "1.8.13" +version = "1.8.15" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/51/d4/f35f539e11c9344652f362c22413ec5078f677ac71229dc9b4f6f85ccaa3/debugpy-1.8.13.tar.gz", hash = "sha256:837e7bef95bdefba426ae38b9a94821ebdc5bea55627879cd48165c90b9e50ce" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8c/8b/3a9a28ddb750a76eaec445c7f4d3147ea2c579a97dbd9e25d39001b92b21/debugpy-1.8.15.tar.gz", hash = "sha256:58d7a20b7773ab5ee6bdfb2e6cf622fdf1e40c9d5aef2857d85391526719ac00" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/3f/32/901c7204cceb3262fdf38f4c25c9a46372c11661e8490e9ea702bc4ff448/debugpy-1.8.13-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:06859f68e817966723ffe046b896b1bd75c665996a77313370336ee9e1de3e90" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/10/77fe746851c8d84838a807da60c7bd0ac8627a6107d6917dd3293bf8628c/debugpy-1.8.13-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c2db69fb8df3168bc857d7b7d2494fed295dfdbde9a45f27b4b152f37520" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a1/ef/28f8db2070e453dda0e49b356e339d0b4e1d38058d4c4ea9e88cdc8ee8e7/debugpy-1.8.13-cp310-cp310-win32.whl", hash = "sha256:46abe0b821cad751fc1fb9f860fb2e68d75e2c5d360986d0136cd1db8cad4428" }, - { url = "https://mirrors.aliyun.com/pypi/packages/89/16/1d53a80caf5862627d3eaffb217d4079d7e4a1df6729a2d5153733661efd/debugpy-1.8.13-cp310-cp310-win_amd64.whl", hash = "sha256:dc7b77f5d32674686a5f06955e4b18c0e41fb5a605f5b33cf225790f114cfeec" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/90/dd2fcad8364f0964f476537481985198ce6e879760281ad1cec289f1aa71/debugpy-1.8.13-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:eee02b2ed52a563126c97bf04194af48f2fe1f68bb522a312b05935798e922ff" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5c/c9/06ff65f15eb30dbdafd45d1575770b842ce3869ad5580a77f4e5590f1be7/debugpy-1.8.13-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4caca674206e97c85c034c1efab4483f33971d4e02e73081265ecb612af65377" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3b/49/798a4092bde16a4650f17ac5f2301d4d37e1972d65462fb25c80a83b4790/debugpy-1.8.13-cp311-cp311-win32.whl", hash = "sha256:7d9a05efc6973b5aaf076d779cf3a6bbb1199e059a17738a2aa9d27a53bcc888" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cd/d5/3684d7561c8ba2797305cf8259619acccb8d6ebe2117bb33a6897c235eee/debugpy-1.8.13-cp311-cp311-win_amd64.whl", hash = "sha256:62f9b4a861c256f37e163ada8cf5a81f4c8d5148fc17ee31fb46813bd658cdcc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/79/ad/dff929b6b5403feaab0af0e5bb460fd723f9c62538b718a9af819b8fff20/debugpy-1.8.13-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:2b8de94c5c78aa0d0ed79023eb27c7c56a64c68217d881bee2ffbcb13951d0c1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d6/4f/b7d42e6679f0bb525888c278b0c0d2b6dff26ed42795230bb46eaae4f9b3/debugpy-1.8.13-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887d54276cefbe7290a754424b077e41efa405a3e07122d8897de54709dbe522" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ec/18/d9b3e88e85d41f68f77235112adc31012a784e45a3fcdbb039777d570a0f/debugpy-1.8.13-cp312-cp312-win32.whl", hash = "sha256:3872ce5453b17837ef47fb9f3edc25085ff998ce63543f45ba7af41e7f7d370f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c9/f7/0df18a4f530ed3cc06f0060f548efe9e3316102101e311739d906f5650be/debugpy-1.8.13-cp312-cp312-win_amd64.whl", hash = "sha256:63ca7670563c320503fea26ac688988d9d6b9c6a12abc8a8cf2e7dd8e5f6b6ea" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/4f/0b65410a08b6452bfd3f7ed6f3610f1a31fb127f46836e82d31797065dcb/debugpy-1.8.13-py2.py3-none-any.whl", hash = "sha256:d4ba115cdd0e3a70942bd562adba9ec8c651fe69ddde2298a1be296fc331906f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/69/51/0b4315169f0d945271db037ae6b98c0548a2d48cc036335cd1b2f5516c1b/debugpy-1.8.15-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:e9a8125c85172e3ec30985012e7a81ea5e70bbb836637f8a4104f454f9b06c97" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/cc/a5391dedb079280d7b72418022e00ba8227ae0b5bc8b2e3d1ecffc5d6b01/debugpy-1.8.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fd0b6b5eccaa745c214fd240ea82f46049d99ef74b185a3517dad3ea1ec55d9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e8/92/acf64b92010c66b33c077dee3862c733798a2c90e7d14b25c01d771e2a0d/debugpy-1.8.15-cp310-cp310-win32.whl", hash = "sha256:8181cce4d344010f6bfe94a531c351a46a96b0f7987750932b2908e7a1e14a55" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3f/f5/c58c015c9ff78de35901bea3ab4dbf7946d7a4aa867ee73875df06ba6468/debugpy-1.8.15-cp310-cp310-win_amd64.whl", hash = "sha256:af2dcae4e4cd6e8b35f982ccab29fe65f7e8766e10720a717bc80c464584ee21" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/b3/1c44a2ed311199ab11c2299c9474a6c7cd80d19278defd333aeb7c287995/debugpy-1.8.15-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:babc4fb1962dd6a37e94d611280e3d0d11a1f5e6c72ac9b3d87a08212c4b6dd3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f6/69/e2dcb721491e1c294d348681227c9b44fb95218f379aa88e12a19d85528d/debugpy-1.8.15-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f778e68f2986a58479d0ac4f643e0b8c82fdd97c2e200d4d61e7c2d13838eb53" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/76/4ce63b95d8294dcf2fd1820860b300a420d077df4e93afcaa25a984c2ca7/debugpy-1.8.15-cp311-cp311-win32.whl", hash = "sha256:f9d1b5abd75cd965e2deabb1a06b0e93a1546f31f9f621d2705e78104377c702" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/a7/e5a7c784465eb9c976d84408873d597dc7ce74a0fc69ed009548a1a94813/debugpy-1.8.15-cp311-cp311-win_amd64.whl", hash = "sha256:62954fb904bec463e2b5a415777f6d1926c97febb08ef1694da0e5d1463c5c3b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ab/4a/4508d256e52897f5cdfee6a6d7580974811e911c6d01321df3264508a5ac/debugpy-1.8.15-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:3dcc7225cb317469721ab5136cda9ff9c8b6e6fb43e87c9e15d5b108b99d01ba" }, + { url = "https://mirrors.aliyun.com/pypi/packages/99/8d/7f6ef1097e7fecf26b4ef72338d08e41644a41b7ee958a19f494ffcffc29/debugpy-1.8.15-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:047a493ca93c85ccede1dbbaf4e66816794bdc214213dde41a9a61e42d27f8fc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3f/e8/e8c6a9aa33a9c9c6dacbf31747384f6ed2adde4de2e9693c766bdf323aa3/debugpy-1.8.15-cp312-cp312-win32.whl", hash = "sha256:b08e9b0bc260cf324c890626961dad4ffd973f7568fbf57feb3c3a65ab6b6327" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/ad/231050c6177b3476b85fcea01e565dac83607b5233d003ff067e2ee44d8f/debugpy-1.8.15-cp312-cp312-win_amd64.whl", hash = "sha256:e2a4fe357c92334272eb2845fcfcdbec3ef9f22c16cf613c388ac0887aed15fa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/d5/98748d9860e767a1248b5e31ffa7ce8cb7006e97bf8abbf3d891d0a8ba4e/debugpy-1.8.15-py2.py3-none-any.whl", hash = "sha256:bce2e6c5ff4f2e00b98d45e7e01a49c7b489ff6df5f12d881c67d2f1ac635f3d" }, ] [[package]] @@ -1201,11 +1280,11 @@ wheels = [ [[package]] name = "docstring-parser" -version = "0.16" +version = "0.17.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/08/12/9c22a58c0b1e29271051222d8906257616da84135af9ed167c9e28f85cb3/docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b2/9d/c3b43da9515bd270df0f80548d9944e389870713cc1fe2b8fb35fe2bcefd/docstring_parser-0.17.0.tar.gz", hash = "sha256:583de4a309722b3315439bb31d64ba3eebada841f2e2cee23b99df001434c912" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637" }, + { url = "https://mirrors.aliyun.com/pypi/packages/55/e2/2537ebcff11c1ee1ff17d8d0b6f4db75873e3b0fb32c2d4a2ee31ecb310a/docstring_parser-0.17.0-py3-none-any.whl", hash = "sha256:cf2569abd23dce8099b300f9b4fa8191e9582dda731fd533daf54c4551658708" }, ] [[package]] @@ -1219,16 +1298,16 @@ wheels = [ [[package]] name = "duckduckgo-search" -version = "7.5.3" +version = "7.5.5" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "click" }, { name = "lxml" }, { name = "primp" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f2/2b/0b6874f96405ce474f97fd3bd890aee8bd73cf3ed42f1cb754c911a3cde8/duckduckgo_search-7.5.3.tar.gz", hash = "sha256:401757168f9c3521919bfc5e11b4e1a28cc6cde94c5326ff0eed683d27830fa9" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/13/dc/919d3d51ed702890a3e6e736e1e152d5d90856393200306e82fb54fde39e/duckduckgo_search-7.5.5.tar.gz", hash = "sha256:44ef03bfa5484bada786590f2d4c213251131765721383a177a0da6fa5c5e41a" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ad/eb/89e19ce7bb9aecf6ca4453af8314545c85389852ee0edda8424f549abe74/duckduckgo_search-7.5.3-py3-none-any.whl", hash = "sha256:0a5ae49f437d12caeb2ddf2f639057801b8dd7114fa1d1bda3aca15c31eae93f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fc/da/8376678b4a9ae0f9418d93df9c9cf851dced49c95ceb38daac6651e38f7a/duckduckgo_search-7.5.5-py3-none-any.whl", hash = "sha256:c71a0661aa436f215d9a05d653af424affb58825ab3e79f3b788053cbdee9ebc" }, ] [[package]] @@ -1334,11 +1413,14 @@ wheels = [ [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10" }, ] [[package]] @@ -1352,28 +1434,28 @@ wheels = [ [[package]] name = "fastavro" -version = "1.10.0" +version = "1.11.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f3/67/7121d2221e998706cac00fa779ec44c1c943cb65e8a7ed1bd57d78d93f2c/fastavro-1.10.0.tar.gz", hash = "sha256:47bf41ac6d52cdfe4a3da88c75a802321321b37b663a900d12765101a5d6886f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/48/8f/32664a3245247b13702d13d2657ea534daf64e58a3f72a3a2d10598d6916/fastavro-1.11.1.tar.gz", hash = "sha256:bf6acde5ee633a29fb8dfd6dfea13b164722bc3adc05a0e055df080549c1c2f8" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0c/e9/f5813450d672f500c4794a39a7cfea99316cb63d5ea11f215e320ea5243b/fastavro-1.10.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1a9fe0672d2caf0fe54e3be659b13de3cad25a267f2073d6f4b9f8862acc31eb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6a/41/3f120f72e65f0c80e9bc4f855ac1c9578c8c0e2cdac4d4d4da1f91ca73b9/fastavro-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86dd0410770e0c99363788f0584523709d85e57bb457372ec5c285a482c17fe6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e1/e3/7d9b019158498b45c383e696ba8733b01535337136e9402b0487afeb92b6/fastavro-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190e80dc7d77d03a6a8597a026146b32a0bbe45e3487ab4904dc8c1bebecb26d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/36/31/7ede5629e66eeb71c234d17a799000e737fe0ffd71ef9e1d57a3510def46/fastavro-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bf570d63be9155c3fdc415f60a49c171548334b70fff0679a184b69c29b6bc61" }, - { url = "https://mirrors.aliyun.com/pypi/packages/10/13/d215411ff5d5de23d6ed62a31eb7f7fa53941681d86bcd5c6388a0918fc3/fastavro-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e07abb6798e95dccecaec316265e35a018b523d1f3944ad396d0a93cb95e0a08" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6a/1d/7a54fac3f90f0dc120b92f244067976831e393789d3b78c08f2b035ccb19/fastavro-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:37203097ed11d0b8fd3c004904748777d730cafd26e278167ea602eebdef8eb2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ac/bf/e7e8e0f841e608dc6f78c746ef2d971fb1f6fe8a9a428d0731ef0abf8b59/fastavro-1.10.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d183c075f527ab695a27ae75f210d4a86bce660cda2f85ae84d5606efc15ef50" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3a/96/43a65881f061bc5ec6dcf39e59f639a7344e822d4caadae748d076aaf4d0/fastavro-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7a95a2c0639bffd7c079b59e9a796bfc3a9acd78acff7088f7c54ade24e4a77" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/45/dba0cc08cf42500dd0f1e552e0fefe1cd81c47099d99277828a1081cbd87/fastavro-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a678153b5da1b024a32ec3f611b2e7afd24deac588cb51dd1b0019935191a6d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/76/e3/3d9b0824e2e2da56e6a435a70a4db7ed801136daa451577a819bbedc6cf8/fastavro-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:67a597a5cfea4dddcf8b49eaf8c2b5ffee7fda15b578849185bc690ec0cd0d8f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a1/dc/83d985f8212194e8283ebae86491fccde8710fd81d81ef8659e5373f4f1b/fastavro-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fd689724760b17f69565d8a4e7785ed79becd451d1c99263c40cb2d6491f1d4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/7f/21711a9ec9937c84406e0773ba3fc6f8d66389a364da46618706f9c37d30/fastavro-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:4f949d463f9ac4221128a51e4e34e2562f401e5925adcadfd28637a73df6c2d8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/a4/8e69c0a5cd121e5d476237de1bde5a7947f791ae45768ae52ed0d3ea8d18/fastavro-1.10.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cfe57cb0d72f304bd0dcc5a3208ca6a7363a9ae76f3073307d095c9d053b29d4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1e/01/aa219e2b33e5873d27b867ec0fad9f35f23d461114e1135a7e46c06786d2/fastavro-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74e517440c824cb65fb29d3e3903a9406f4d7c75490cef47e55c4c82cdc66270" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a7/ba/1766e2d7d95df2e95e9e9a089dc7a537c0616720b053a111a918fa7ee6b6/fastavro-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:203c17d44cadde76e8eecb30f2d1b4f33eb478877552d71f049265dc6f2ecd10" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2e/40/26e56696b9696ab4fbba25a96b8037ca3f9fd8a8cc55b4b36400ef023e49/fastavro-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6575be7f2b5f94023b5a4e766b0251924945ad55e9a96672dc523656d17fe251" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4e/bc/2f6c92c06c5363372abe828bccdd95762f2c1983b261509f94189c38c8a1/fastavro-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe471deb675ed2f01ee2aac958fbf8ebb13ea00fa4ce7f87e57710a0bc592208" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0c/ce/cfd16546c04ebbca1be80873b533c788cec76f7bfac231bfac6786047572/fastavro-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:567ff515f2a5d26d9674b31c95477f3e6022ec206124c62169bc2ffaf0889089" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ae/be/53df3fec7fdabc1848896a76afb0f01ab96b58abb29611aa68a994290167/fastavro-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:603aa1c1d1be21fb4bcb63e1efb0711a9ddb337de81391c32dac95c6e0dacfcc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/cc/c7c76a082fbf5aaaf82ab7da7b9ede6fc99eb8f008c084c67d230b29c446/fastavro-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45653b312d4ce297e2bd802ea3ffd17ecbe718e5e8b6e2ae04cd72cb50bb99d5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/ff/5f1f0b5e3835e788ba8121d6dd6426cd4c6e58ce1bff02cb7810278648b0/fastavro-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:998a53fc552e6bee9acda32af258f02557313c85fb5b48becba5b71ec82f421e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/b8/1ac01433b55460dabeb6d3fbb05ba1c971d57137041e8f53b2e9f46cd033/fastavro-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9f878c9ad819467120cb066f1c73496c42eb24ecdd7c992ec996f465ef4cedad" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5e/a8/66e599b946ead031a5caba12772e614a7802d95476e8732e2e9481369973/fastavro-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da9e4c231ac4951092c2230ca423d8a3f2966718f072ac1e2c5d2d44c70b2a50" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/e7/17c35e2dfe8a9e4f3735eabdeec366b0edc4041bb1a84fcd528c8efd12af/fastavro-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:7423bfad3199567eeee7ad6816402c7c0ee1658b959e8c10540cfbc60ce96c2a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8e/63/f33d6fd50d8711f305f07ad8c7b4a25f2092288f376f484c979dcf277b07/fastavro-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3573340e4564e8962e22f814ac937ffe0d4be5eabbd2250f77738dc47e3c8fe9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f4/09/a57ad9d8cb9b8affb2e43c29d8fb8cbdc0f1156f8496067a0712c944bacc/fastavro-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7291cf47735b8bd6ff5d9b33120e6e0974f52fd5dff90cd24151b22018e7fd29" }, + { url = "https://mirrors.aliyun.com/pypi/packages/86/70/d6df59309d3754d6d4b0c7beca45b9b1a957d6725aed8da3aca247db3475/fastavro-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf3bb065d657d5bac8b2cb39945194aa086a9b3354f2da7f89c30e4dc20e08e2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ad/ea/122315154d2a799a2787058435ef0d4d289c0e8e575245419436e9b702ca/fastavro-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8758317c85296b848698132efb13bc44a4fbd6017431cc0f26eaeb0d6fa13d35" }, + { url = "https://mirrors.aliyun.com/pypi/packages/62/12/7800de5fec36d55a818adf3db3b085b1a033c4edd60323cf6ca0754cf8cb/fastavro-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ad99d57228f83bf3e2214d183fbf6e2fda97fd649b2bdaf8e9110c36cbb02624" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/65/2b74ccfeba9dcc3f7dbe64907307386b4a0af3f71d2846f63254df0f1e1d/fastavro-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:9134090178bdbf9eefd467717ced3dc151e27a7e7bfc728260ce512697efe5a4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/99/58/8e789b0a2f532b22e2d090c20d27c88f26a5faadcba4c445c6958ae566cf/fastavro-1.11.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e8bc238f2637cd5d15238adbe8fb8c58d2e6f1870e0fb28d89508584670bae4b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/3f/02ed44742b1224fe23c9fc9b9b037fc61769df716c083cf80b59a02b9785/fastavro-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b403933081c83fc4d8a012ee64b86e560a024b1280e3711ee74f2abc904886e8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cc/bc/9cc8b19eeee9039dd49719f8b4020771e805def262435f823fa8f27ddeea/fastavro-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f6ecb4b5f77aa756d973b7dd1c2fb4e4c95b4832a3c98b059aa96c61870c709" }, + { url = "https://mirrors.aliyun.com/pypi/packages/39/77/3b73a986606494596b6d3032eadf813a05b59d1623f54384a23de4217d5f/fastavro-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:059893df63ef823b0231b485c9d43016c7e32850cae7bf69f4e9d46dd41c28f2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8e/1c/b69ceef6494bd0df14752b5d8648b159ad52566127bfd575e9f5ecc0c092/fastavro-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5120ffc9a200699218e01777e695a2f08afb3547ba818184198c757dc39417bd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ef/11/5c2d0db3bd0e6407546fabae9e267bb0824eacfeba79e7dd81ad88afa27d/fastavro-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:7bb9d0d2233f33a52908b6ea9b376fe0baf1144bdfdfb3c6ad326e200a8b56b0" }, ] [[package]] @@ -1404,17 +1486,17 @@ name = "fastembed-gpu" version = "0.3.6" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "huggingface-hub", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "loguru", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "mmh3", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "numpy", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "onnxruntime-gpu", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "pillow", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "pystemmer", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "requests", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "snowballstemmer", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "tokenizers", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "tqdm", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "huggingface-hub" }, + { name = "loguru" }, + { name = "mmh3" }, + { name = "numpy" }, + { name = "onnxruntime-gpu" }, + { name = "pillow" }, + { name = "pystemmer" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "tokenizers" }, + { name = "tqdm" }, ] sdist = { url = "https://mirrors.aliyun.com/pypi/packages/da/07/7336c7f3d7ee47f33b407eeb50f5eeb152889de538a52a8f1cc637192816/fastembed_gpu-0.3.6.tar.gz", hash = "sha256:ee2de8918b142adbbf48caaffec0c492f864d73c073eea5a3dcd0e8c1041c50d" } wheels = [ @@ -1574,35 +1656,35 @@ wheels = [ [[package]] name = "fonttools" -version = "4.56.0" +version = "4.59.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1c/8c/9ffa2a555af0e5e5d0e2ed7fdd8c9bef474ed676995bb4c57c9cd0014248/fonttools-4.56.0.tar.gz", hash = "sha256:a114d1567e1a1586b7e9e7fc2ff686ca542a82769a296cef131e4c4af51e58f4" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8a/27/ec3c723bfdf86f34c5c82bf6305df3e0f0d8ea798d2d3a7cb0c0a866d286/fonttools-4.59.0.tar.gz", hash = "sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/1e/5e/6ac30c2cc6a29454260f13c9c6422fc509b7982c13cd4597041260d8f482/fonttools-4.56.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:331954d002dbf5e704c7f3756028e21db07097c19722569983ba4d74df014000" }, - { url = "https://mirrors.aliyun.com/pypi/packages/92/3a/ac382a8396d1b420ee45eeb0f65b614a9ca7abbb23a1b17524054f0f2200/fonttools-4.56.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d1613abd5af2f93c05867b3a3759a56e8bf97eb79b1da76b2bc10892f96ff16" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8a/ae/00b58bfe20e9ff7fbc3dda38f5d127913942b5e252288ea9583099a31bf5/fonttools-4.56.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:705837eae384fe21cee5e5746fd4f4b2f06f87544fa60f60740007e0aa600311" }, - { url = "https://mirrors.aliyun.com/pypi/packages/46/d0/0004ca8f6a200252e5bd6982ed99b5fe58c4c59efaf5f516621c4cd8f703/fonttools-4.56.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc871904a53a9d4d908673c6faa15689874af1c7c5ac403a8e12d967ebd0c0dc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/45/ea/c8862bd3e09d143ef8ed8268ec8a7d477828f960954889e65288ac050b08/fonttools-4.56.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:38b947de71748bab150259ee05a775e8a0635891568e9fdb3cdd7d0e0004e62f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8f/75/bb88a9552ec1de31a414066257bfd9f40f4ada00074f7a3799ea39b5741f/fonttools-4.56.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:86b2a1013ef7a64d2e94606632683f07712045ed86d937c11ef4dde97319c086" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2a/5f/80a2b640df1e1bb7d459d62c8b3f37fe83fd413897e549106d4ebe6371f5/fonttools-4.56.0-cp310-cp310-win32.whl", hash = "sha256:133bedb9a5c6376ad43e6518b7e2cd2f866a05b1998f14842631d5feb36b5786" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8f/85/0904f9dbe51ac70d878d3242a8583b9453a09105c3ed19c6301247fd0d3a/fonttools-4.56.0-cp310-cp310-win_amd64.whl", hash = "sha256:17f39313b649037f6c800209984a11fc256a6137cbe5487091c6c7187cae4685" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/56/a2f3e777d48fcae7ecd29de4d96352d84e5ea9871e5f3fc88241521572cf/fonttools-4.56.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ef04bc7827adb7532be3d14462390dd71287644516af3f1e67f1e6ff9c6d6df" }, - { url = "https://mirrors.aliyun.com/pypi/packages/71/85/d483e9c4e5ed586b183bf037a353e8d766366b54fd15519b30e6178a6a6e/fonttools-4.56.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ffda9b8cd9cb8b301cae2602ec62375b59e2e2108a117746f12215145e3f786c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/09/67/060473b832b2fade03c127019794df6dc02d9bc66fa4210b8e0d8a99d1e5/fonttools-4.56.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e993e8db36306cc3f1734edc8ea67906c55f98683d6fd34c3fc5593fdbba4c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/28/e9/47c02d5a7027e8ed841ab6a10ca00c93dadd5f16742f1af1fa3f9978adf4/fonttools-4.56.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:003548eadd674175510773f73fb2060bb46adb77c94854af3e0cc5bc70260049" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/8a/221d456d1afb8ca043cfd078f59f187ee5d0a580f4b49351b9ce95121f57/fonttools-4.56.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd9825822e7bb243f285013e653f6741954d8147427aaa0324a862cdbf4cbf62" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a4/8c/e503863adf7a6aeff7b960e2f66fa44dd0c29a7a8b79765b2821950d7b05/fonttools-4.56.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b23d30a2c0b992fb1c4f8ac9bfde44b5586d23457759b6cf9a787f1a35179ee0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2b/50/79ba3b7e42f4eaa70b82b9e79155f0f6797858dc8a97862428b6852c6aee/fonttools-4.56.0-cp311-cp311-win32.whl", hash = "sha256:47b5e4680002ae1756d3ae3b6114e20aaee6cc5c69d1e5911f5ffffd3ee46c6b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3b/90/4926e653041c4116ecd43e50e3c79f5daae6dcafc58ceb64bc4f71dd4924/fonttools-4.56.0-cp311-cp311-win_amd64.whl", hash = "sha256:14a3e3e6b211660db54ca1ef7006401e4a694e53ffd4553ab9bc87ead01d0f05" }, - { url = "https://mirrors.aliyun.com/pypi/packages/39/32/71cfd6877999576a11824a7fe7bc0bb57c5c72b1f4536fa56a3e39552643/fonttools-4.56.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6f195c14c01bd057bc9b4f70756b510e009c83c5ea67b25ced3e2c38e6ee6e9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/15/52/d9f716b072c5061a0b915dd4c387f74bef44c68c069e2195c753905bd9b7/fonttools-4.56.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa760e5fe8b50cbc2d71884a1eff2ed2b95a005f02dda2fa431560db0ddd927f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d1/97/f1b3a8afa9a0d814a092a25cd42f59ccb98a0bb7a295e6e02fc9ba744214/fonttools-4.56.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d54a45d30251f1d729e69e5b675f9a08b7da413391a1227781e2a297fa37f6d2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/70/2a781bedc1c45a0c61d29c56425609b22ed7f971da5d7e5df2679488741b/fonttools-4.56.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:661a8995d11e6e4914a44ca7d52d1286e2d9b154f685a4d1f69add8418961563" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0c/02/a2597858e61a5e3fb6a14d5f6be9e6eb4eaf090da56ad70cedcbdd201685/fonttools-4.56.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d94449ad0a5f2a8bf5d2f8d71d65088aee48adbe45f3c5f8e00e3ad861ed81a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f2/00/aaf00100d6078fdc73f7352b44589804af9dc12b182a2540b16002152ba4/fonttools-4.56.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f59746f7953f69cc3290ce2f971ab01056e55ddd0fb8b792c31a8acd7fee2d28" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/dc/3ff1db522460db60cf3adaf1b64e0c72b43406717d139786d3fa1eb20709/fonttools-4.56.0-cp312-cp312-win32.whl", hash = "sha256:bce60f9a977c9d3d51de475af3f3581d9b36952e1f8fc19a1f2254f1dda7ce9c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/e3/5a181a85777f7809076e51f7422e0dc77eb04676c40ec8bf6a49d390d1ff/fonttools-4.56.0-cp312-cp312-win_amd64.whl", hash = "sha256:300c310bb725b2bdb4f5fc7e148e190bd69f01925c7ab437b9c0ca3e1c7cd9ba" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/ff/44934a031ce5a39125415eb405b9efb76fe7f9586b75291d66ae5cbfc4e6/fonttools-4.56.0-py3-none-any.whl", hash = "sha256:1088182f68c303b50ca4dc0c82d42083d176cba37af1937e1a976a31149d4d14" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/1f/3dcae710b7c4b56e79442b03db64f6c9f10c3348f7af40339dffcefb581e/fonttools-4.59.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:524133c1be38445c5c0575eacea42dbd44374b310b1ffc4b60ff01d881fabb96" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/0e/ae3a1884fa1549acac1191cc9ec039142f6ac0e9cbc139c2e6a3dab967da/fonttools-4.59.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21e606b2d38fed938dde871c5736822dd6bda7a4631b92e509a1f5cd1b90c5df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/46/58bff92a7216829159ac7bdb1d05a48ad1b8ab8c539555f12d29fdecfdd4/fonttools-4.59.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e93df708c69a193fc7987192f94df250f83f3851fda49413f02ba5dded639482" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/57/767e31e48861045d89691128bd81fd4c62b62150f9a17a666f731ce4f197/fonttools-4.59.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:62224a9bb85b4b66d1b46d45cbe43d71cbf8f527d332b177e3b96191ffbc1e64" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/78/adb5e9b0af5c6ce469e8b0e112f144eaa84b30dd72a486e9c778a9b03b31/fonttools-4.59.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8974b2a266b54c96709bd5e239979cddfd2dbceed331aa567ea1d7c4a2202db" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ac/92/bc3881097fbf3d56d112bec308c863c058e5d4c9c65f534e8ae58450ab8a/fonttools-4.59.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:209b75943d158f610b78320eacb5539aa9e920bee2c775445b2846c65d20e19d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4a/54/39cdb23f0eeda2e07ae9cb189f2b6f41da89aabc682d3a387b3ff4a4ed29/fonttools-4.59.0-cp310-cp310-win32.whl", hash = "sha256:4c908a7036f0f3677f8afa577bcd973e3e20ddd2f7c42a33208d18bee95cdb6f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d8/eb/f8388d9e19f95d8df2449febe9b1a38ddd758cfdb7d6de3a05198d785d61/fonttools-4.59.0-cp310-cp310-win_amd64.whl", hash = "sha256:8b4309a2775e4feee7356e63b163969a215d663399cce1b3d3b65e7ec2d9680e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/96/520733d9602fa1bf6592e5354c6721ac6fc9ea72bc98d112d0c38b967199/fonttools-4.59.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:841b2186adce48903c0fef235421ae21549020eca942c1da773ac380b056ab3c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/6a/170fce30b9bce69077d8eec9bea2cfd9f7995e8911c71be905e2eba6368b/fonttools-4.59.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9bcc1e77fbd1609198966ded6b2a9897bd6c6bcbd2287a2fc7d75f1a254179c5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/b6/7c8166c0066856f1408092f7968ac744060cf72ca53aec9036106f57eeca/fonttools-4.59.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:37c377f7cb2ab2eca8a0b319c68146d34a339792f9420fca6cd49cf28d370705" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/0c/707c5a19598eafcafd489b73c4cb1c142102d6197e872f531512d084aa76/fonttools-4.59.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa39475eaccb98f9199eccfda4298abaf35ae0caec676ffc25b3a5e224044464" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f6/e7/6d33737d9fe632a0f59289b6f9743a86d2a9d0673de2a0c38c0f54729822/fonttools-4.59.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d3972b13148c1d1fbc092b27678a33b3080d1ac0ca305742b0119b75f9e87e38" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/e1/a4c3d089ab034a578820c8f2dff21ef60daf9668034a1e4fb38bb1cc3398/fonttools-4.59.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a408c3c51358c89b29cfa5317cf11518b7ce5de1717abb55c5ae2d2921027de6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/77/ca82b9c12fa4de3c520b7760ee61787640cf3fde55ef1b0bfe1de38c8153/fonttools-4.59.0-cp311-cp311-win32.whl", hash = "sha256:6770d7da00f358183d8fd5c4615436189e4f683bdb6affb02cad3d221d7bb757" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ab/25/5aa7ca24b560b2f00f260acf32c4cf29d7aaf8656e159a336111c18bc345/fonttools-4.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:84fc186980231a287b28560d3123bd255d3c6b6659828c642b4cf961e2b923d0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/77/b1c8af22f4265e951cd2e5535dbef8859efcef4fb8dee742d368c967cddb/fonttools-4.59.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f9b3a78f69dcbd803cf2fb3f972779875b244c1115481dfbdd567b2c22b31f6b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/5a/aeb975699588176bb357e8b398dfd27e5d3a2230d92b81ab8cbb6187358d/fonttools-4.59.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:57bb7e26928573ee7c6504f54c05860d867fd35e675769f3ce01b52af38d48e2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/97/c6101a7e60ae138c4ef75b22434373a0da50a707dad523dd19a4889315bf/fonttools-4.59.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4536f2695fe5c1ffb528d84a35a7d3967e5558d2af58b4775e7ab1449d65767b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bd/6c/fa4d18d641054f7bff878cbea14aa9433f292b9057cb1700d8e91a4d5f4f/fonttools-4.59.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:885bde7d26e5b40e15c47bd5def48b38cbd50830a65f98122a8fb90962af7cd1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/5c/331947fc1377deb928a69bde49f9003364f5115e5cbe351eea99e39412a2/fonttools-4.59.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6801aeddb6acb2c42eafa45bc1cb98ba236871ae6f33f31e984670b749a8e58e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/46/b66469dfa26b8ff0baa7654b2cc7851206c6d57fe3abdabbaab22079a119/fonttools-4.59.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:31003b6a10f70742a63126b80863ab48175fb8272a18ca0846c0482968f0588e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/05/ebfb6b1f3a4328ab69787d106a7d92ccde77ce66e98659df0f9e3f28d93d/fonttools-4.59.0-cp312-cp312-win32.whl", hash = "sha256:fbce6dae41b692a5973d0f2158f782b9ad05babc2c2019a970a1094a23909b1b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/45/d2bdc9ea20bbadec1016fd0db45696d573d7a26d95ab5174ffcb6d74340b/fonttools-4.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:332bfe685d1ac58ca8d62b8d6c71c2e52a6c64bc218dc8f7825c9ea51385aa01" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/9c/df0ef2c51845a13043e5088f7bb988ca6cd5bb82d5d4203d6a158aa58cf2/fonttools-4.59.0-py3-none-any.whl", hash = "sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d" }, ] [[package]] @@ -1616,66 +1698,90 @@ dependencies = [ sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d5/10/3654b44093aa3e587948c770279baca3a8dfe4d14a616142e8c6bf04b09b/free_proxy-1.1.3.tar.gz", hash = "sha256:6d82aa112e3df7725bdbf177e2110bccdf5f3bbd6e1c70b8616ec12ae3bbf98c" } [[package]] -name = "frozenlist" -version = "1.5.0" +name = "frozendict" +version = "2.4.6" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8f/ed/0f4cec13a93c02c47ec32d81d11c0c1efbadf4a471e3f3ce7cad366cbbd3/frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bb/59/19eb300ba28e7547538bdf603f1c6c34793240a90e1a7b61b65d8517e35e/frozendict-2.4.6.tar.gz", hash = "sha256:df7cd16470fbd26fc4969a208efadc46319334eb97def1ddf48919b351192b8e" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/54/79/29d44c4af36b2b240725dce566b20f63f9b36ef267aaaa64ee7466f4f2f8/frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/47/47/0c999aeace6ead8a44441b4f4173e2261b18219e4ad1fe9a479871ca02fc/frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8d/60/107a38c1e54176d12e06e9d4b5d755b677d71d1219217cee063911b1384f/frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec" }, - { url = "https://mirrors.aliyun.com/pypi/packages/17/62/594a6829ac5679c25755362a9dc93486a8a45241394564309641425d3ff6/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7e/75/6c8419d8f92c80dd0ee3f63bdde2702ce6398b0ac8410ff459f9b6f2f9cb/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76" }, - { url = "https://mirrors.aliyun.com/pypi/packages/88/3e/82a6f0b84bc6fb7e0be240e52863c6d4ab6098cd62e4f5b972cd31e002e8/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/85/14e5f9ccac1b64ff2f10c927b3ffdf88772aea875882406f9ba0cec8ad84/frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ee/59/928322800306f6529d1852323014ee9008551e9bb027cc38d276cbc0b0e7/frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7d/bd/e01fa4f146a6f6c18c5d34cab8abdc4013774a26c4ff851128cd1bd3008e/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a5/bd/e4771fd18a8ec6757033f0fa903e447aecc3fbba54e3630397b61596acf0/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/21/13/c83821fa5544af4f60c5d3a65d054af3213c26b14d3f5f48e43e5fb48556/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/71/f3/1f91c9a9bf7ed0e8edcf52698d23f3c211d8d00291a53c9f115ceb977ab1/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4c/22/4a256fdf5d9bcb3ae32622c796ee5ff9451b3a13a68cfe3f68e2c95588ce/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/af/89/c48ebe1f7991bd2be6d5f4ed202d94960c01b3017a03d6954dd5fa9ea1e8/frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/28/2f/cc27d5f43e023d21fe5c19538e08894db3d7e081cbf582ad5ed366c24446/frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/79/43/0bed28bf5eb1c9e4301003b74453b8e7aa85fb293b31dde352aac528dafc/frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bb/bf/b74e38f09a246e8abbe1e90eb65787ed745ccab6eaa58b9c9308e052323d/frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2c/31/ab01375682f14f7613a1ade30149f684c84f9b8823a4391ed950c8285656/frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778" }, - { url = "https://mirrors.aliyun.com/pypi/packages/98/a8/d0ac0b9276e1404f58fec3ab6e90a4f76b778a49373ccaf6a563f100dfbc/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ad/c9/c7761084fa822f07dac38ac29f841d4587570dd211e2262544aa0b791d21/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a1/ff/cd7479e703c39df7bdab431798cef89dc75010d8aa0ca2514c5b9321db27/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/59/a0/370941beb47d237eca4fbf27e4e91389fd68699e6f4b0ebcc95da463835b/frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b8/5f/c10123e8d64867bc9b4f2f510a32042a306ff5fcd7e2e09e5ae5100ee333/frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fa/79/38c505601ae29d4348f21706c5d89755ceded02a745016ba2f58bd5f1ea6/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/19/e2/39f3a53191b8204ba9f0bb574b926b73dd2efba2a2b9d2d730517e8f7622/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d5/c9/3075eb7f7f3a91f1a6b00284af4de0a65a9ae47084930916f5528144c9dd/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/05/f5/549f44d314c29408b962fa2b0e69a1a67c59379fb143b92a0a065ffd1f0f/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9d/f8/cb09b3c24a3eac02c4c07a9558e11e9e244fb02bf62c85ac2106d1eb0c0b/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/48/38c2db3f54d1501e692d6fe058f45b6ad1b358d82cd19436efab80cfc965/frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ca/8c/2ddffeb8b60a4bce3b196c32fcc30d8830d4615e7b492ec2071da801b8ad/frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/79/73/fa6d1a96ab7fd6e6d1c3500700963eab46813847f01ef0ccbaa726181dd5/frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ab/04/ea8bf62c8868b8eada363f20ff1b647cf2e93377a7b284d36062d21d81d1/frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d0/9a/8e479b482a6f2070b26bda572c5e6889bb3ba48977e81beea35b5ae13ece/frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e3/12/2aad87deb08a4e7ccfb33600871bbe8f0e08cb6d8224371387f3303654d7/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/77/f2/07f06b05d8a427ea0060a9cef6e63405ea9e0d761846b95ef3fb3be57111/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bd/9f/8bf45a2f1cd4aa401acd271b077989c9267ae8463e7c8b1eb0d3f561b65e/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee" }, - { url = "https://mirrors.aliyun.com/pypi/packages/41/d1/1f20fd05a6c42d3868709b7604c9f15538a29e4f734c694c6bcfc3d3b935/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/af/f2/64b73a9bb86f5a89fb55450e97cd5c1f84a862d4ff90d9fd1a73ab0f64a5/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/29/e2/ffbb1fae55a791fd6c2938dd9ea779509c977435ba3940b9f2e8dc9d5316/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2e/6e/008136a30798bb63618a114b9321b5971172a5abddff44a100c7edc5ad4f/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ae/f0/4e71e54a026b06724cec9b6c54f0b13a4e9e298cc8db0f82ec70e151f5ce/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4d/36/70ec246851478b1c0b59f11ef8ade9c482ff447c1363c2bd5fad45098b12/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/e0/47f87544055b3349b633a03c4d94b405956cf2437f4ab46d0928b74b7526/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f9/7c/490133c160fb6b84ed374c266f42800e33b50c3bbab1652764e6e1fc498a/frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b1/56/4e45136ffc6bdbfa68c29ca56ef53783ef4c2fd395f7cbf99a2624aa9aaa/frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c6/c8/a5be5b7550c10858fcf9b0ea054baccab474da77d37f1e828ce043a3a5d4/frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/7f/e80cdbe0db930b2ba9d46ca35a41b0150156da16dfb79edcc05642690c3b/frozendict-2.4.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3a05c0a50cab96b4bb0ea25aa752efbfceed5ccb24c007612bc63e51299336f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/29/98/27e145ff7e8e63caa95fb8ee4fc56c68acb208bef01a89c3678a66f9a34d/frozendict-2.4.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f5b94d5b07c00986f9e37a38dd83c13f5fe3bf3f1ccc8e88edea8fe15d6cd88c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ac/f1/a10be024a9d53441c997b3661ea80ecba6e3130adc53812a4b95b607cdd1/frozendict-2.4.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4c789fd70879ccb6289a603cdebdc4953e7e5dea047d30c1b180529b28257b5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/46/a6/34c760975e6f1cb4db59a990d58dcf22287e10241c851804670c74c6a27a/frozendict-2.4.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da6a10164c8a50b34b9ab508a9420df38f4edf286b9ca7b7df8a91767baecb34" }, + { url = "https://mirrors.aliyun.com/pypi/packages/62/dd/64bddd1ffa9617f50e7e63656b2a7ad7f0a46c86b5f4a3d2c714d0006277/frozendict-2.4.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9a8a43036754a941601635ea9c788ebd7a7efbed2becba01b54a887b41b175b9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/45/ae/af06a8bde1947277aad895c2f26c3b8b8b6ee9c0c2ad988fb58a9d1dde3f/frozendict-2.4.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9905dcf7aa659e6a11b8051114c9fa76dfde3a6e50e6dc129d5aece75b449a2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/df/be3fa0457ff661301228f4c59c630699568c8ed9b5480f113b3eea7d0cb3/frozendict-2.4.6-cp310-cp310-win_amd64.whl", hash = "sha256:323f1b674a2cc18f86ab81698e22aba8145d7a755e0ac2cccf142ee2db58620d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4a/6f/c22e0266b4c85f58b4613fec024e040e93753880527bf92b0c1bc228c27c/frozendict-2.4.6-cp310-cp310-win_arm64.whl", hash = "sha256:eabd21d8e5db0c58b60d26b4bb9839cac13132e88277e1376970172a85ee04b3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/04/13/d9839089b900fa7b479cce495d62110cddc4bd5630a04d8469916c0e79c5/frozendict-2.4.6-py311-none-any.whl", hash = "sha256:d065db6a44db2e2375c23eac816f1a022feb2fa98cbb50df44a9e83700accbea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ba/d0/d482c39cee2ab2978a892558cf130681d4574ea208e162da8958b31e9250/frozendict-2.4.6-py312-none-any.whl", hash = "sha256:49344abe90fb75f0f9fdefe6d4ef6d4894e640fadab71f11009d52ad97f370b9" }, +] + +[[package]] +name = "frozenlist" +version = "1.7.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615" }, + { url = "https://mirrors.aliyun.com/pypi/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56" }, + { url = "https://mirrors.aliyun.com/pypi/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01" }, + { url = "https://mirrors.aliyun.com/pypi/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e" }, ] [[package]] name = "fsspec" -version = "2024.12.0" +version = "2025.3.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ee/11/de70dee31455c546fbc88301971ec03c328f3d1138cfba14263f651e9551/fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/34/f4/5721faf47b8c499e776bc34c6a8fc17efdf7fdef0b00f398128bc5dcb4ac/fsspec-2025.3.0.tar.gz", hash = "sha256:a935fd1ea872591f2b5148907d103488fc523295e6c64b835cfad8c3eca44972" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/de/86/5486b0188d08aa643e127774a99bac51ffa6cf343e3deb0583956dca5b22/fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/56/53/eb690efa8513166adef3e0669afd31e95ffde69fb3c52ec2ac7223ed6018/fsspec-2025.3.0-py3-none-any.whl", hash = "sha256:efb87af3efa9103f94ca91a7f8cb7a4df91af9f74fc106c9c7ea0efd7277c1b3" }, ] [package.optional-dependencies] @@ -1749,7 +1855,7 @@ wheels = [ [[package]] name = "google-api-core" -version = "2.24.2" +version = "2.25.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "google-auth" }, @@ -1758,9 +1864,9 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/09/5c/085bcb872556934bb119e5e09de54daa07873f6866b8f0303c49e72287f7/google_api_core-2.24.2.tar.gz", hash = "sha256:81718493daf06d96d6bc76a91c23874dbf2fac0adbbf542831b805ee6e974696" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/dc/21/e9d043e88222317afdbdb567165fdbc3b0aad90064c7e0c9eb0ad9955ad8/google_api_core-2.25.1.tar.gz", hash = "sha256:d2aaa0b13c78c61cb3f4282c464c046e45fbd75755683c9c525e6e8f7ed0a5e8" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/46/95/f472d85adab6e538da2025dfca9e976a0d125cc0af2301f190e77b76e51c/google_api_core-2.24.2-py3-none-any.whl", hash = "sha256:810a63ac95f3c441b7c0e43d344e372887f62ce9071ba972eacf32672e072de9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/4b/ead00905132820b623732b175d66354e9d3e69fcf2a5dcdab780664e7896/google_api_core-2.25.1-py3-none-any.whl", hash = "sha256:8a2a56c1fef82987a524371f99f3bd0143702fecc670c72e600c1cda6bf8dbb7" }, ] [package.optional-dependencies] @@ -1771,7 +1877,7 @@ grpc = [ [[package]] name = "google-api-python-client" -version = "2.165.0" +version = "2.177.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "google-api-core" }, @@ -1780,23 +1886,23 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d5/b5/46e6a866407e1d620d6722e7f5e076c3908801b6bc122e0908ea92b9d78f/google_api_python_client-2.165.0.tar.gz", hash = "sha256:0d2aee76727a104705630bebbc43669c864b766924e9329051ef7b7e2468eb72" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7a/75/a89cad519fa8910132e3b08571d0e682ae1163643da6f963f1930f3dc788/google_api_python_client-2.177.0.tar.gz", hash = "sha256:9ffd2b57d68f5afa7e6ac64e2c440534eaa056cbb394812a62ff94723c31b50e" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/9d/dc/432b2b61e2335dc20196f543b5c84400d246c8cdfb8169fea183e7a0c52d/google_api_python_client-2.165.0-py2.py3-none-any.whl", hash = "sha256:4eaab7d4a20be0d3d1dde462fa95e9e0ccc2a3e177a656701bf73fe738ddef7d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/f5/121248e18ca605a11720c81ae1b52a5a8cb690af9f01887c56de23cd9a5a/google_api_python_client-2.177.0-py3-none-any.whl", hash = "sha256:f2f50f11105ab883eb9b6cf38ec54ea5fd4b429249f76444bec90deba5be79b3" }, ] [[package]] name = "google-auth" -version = "2.38.0" +version = "2.40.3" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "cachetools" }, { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c6/eb/d504ba1daf190af6b204a9d4714d457462b486043744901a6eeea711f913/google_auth-2.38.0.tar.gz", hash = "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/9e/9b/e92ef23b84fa10a64ce4831390b7a4c2e53c0132568d99d4ae61d04c8855/google_auth-2.40.3.tar.gz", hash = "sha256:500c3a29adedeb36ea9cf24b8d10858e152f2412e3ca37829b3fa18e33d63b77" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/9d/47/603554949a37bca5b7f894d51896a9c534b9eab808e2520a748e081669d0/google_auth-2.38.0-py2.py3-none-any.whl", hash = "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/63/b19553b658a1692443c62bd07e5868adaa0ad746a0751ba62c59568cd45b/google_auth-2.40.3-py2.py3-none-any.whl", hash = "sha256:1370d4593e86213563547f97a92752fc658456fe4514c809544f330fed45a7ca" }, ] [[package]] @@ -1836,7 +1942,7 @@ wheels = [ [[package]] name = "google-cloud-bigquery" -version = "3.30.0" +version = "3.35.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "google-api-core", extra = ["grpc"] }, @@ -1847,9 +1953,9 @@ dependencies = [ { name = "python-dateutil" }, { name = "requests" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f1/2f/3dda76b3ec029578838b1fe6396e6b86eb574200352240e23dea49265bb7/google_cloud_bigquery-3.30.0.tar.gz", hash = "sha256:7e27fbafc8ed33cc200fe05af12ecd74d279fe3da6692585a3cef7aee90575b6" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/44/e4/9cf03fa81fefd1b9811a7cd6e398804ae0de3b6a4edef810e2acd45cabbc/google_cloud_bigquery-3.35.1.tar.gz", hash = "sha256:599f26cacf190acfe88000f6cc5f4bc9e6baac7899e4f406ca054f1906f71960" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0c/6d/856a6ca55c1d9d99129786c929a27dd9d31992628ebbff7f5d333352981f/google_cloud_bigquery-3.30.0-py2.py3-none-any.whl", hash = "sha256:f4d28d846a727f20569c9b2d2f4fa703242daadcb2ec4240905aa485ba461877" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/50/96fe9bc5b83d3a421e91ed8edc2535de45957e9af398273e3ecb5c3a1094/google_cloud_bigquery-3.35.1-py3-none-any.whl", hash = "sha256:6739a6ba63c6d80735ca2b34b1df2090ff473b80c1a62354caa2debe6dbbd961" }, ] [[package]] @@ -1900,35 +2006,35 @@ wheels = [ [[package]] name = "google-crc32c" -version = "1.7.0" +version = "1.7.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fd/c6/bd09366753b49353895ed73bad74574d9086b26b53bb5b9213962009719a/google_crc32c-1.7.0.tar.gz", hash = "sha256:c8c15a04b290c7556f277acc55ad98503a8bc0893ea6860fd5b5d210f3f558ce" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/19/ae/87802e6d9f9d69adfaedfcfd599266bf386a54d0be058b532d04c794f76d/google_crc32c-1.7.1.tar.gz", hash = "sha256:2bff2305f98846f3e825dbeec9ee406f89da7962accdb29356e4eadc251bd472" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/fb/4b/3aad7dfd25a5541120c74d80256b79506f3c2c6eecd37c3b4c92f2ff719c/google_crc32c-1.7.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:18f1dfc6baeb3b28b1537d54b3622363352f75fcb2d4b6ffcc37584fe431f122" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b6/92/1acee90aec27235ac6054552b8e895e9df5324ed3cfcaf416e1af6e54923/google_crc32c-1.7.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:732378dc4ca08953eac0d13d1c312d99a54d5b483c90b4a5a536132669ed1c24" }, - { url = "https://mirrors.aliyun.com/pypi/packages/89/85/0c66e6b90d74990a9aee1008429ea3e87d31a3bd7d8029b6c85ea07efe1a/google_crc32c-1.7.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14fdac94aa60d5794652f8ea6c2fcc532032e31f9050698b7ecdc6d4c3a61784" }, - { url = "https://mirrors.aliyun.com/pypi/packages/87/3b/a0b220e47b0867e5d39fb6cd633b4c6171bd6869598c18616f579ea63299/google_crc32c-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bc14187a7fe5c61024c0dd1b578d7f9391df55459bf373c07f66426e09353b6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1e/b7/1c35c2bb03244a91b9f9116a4d7a0859cdf5527fdf0fc42ccbb738234ac3/google_crc32c-1.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54af59a98a427d0f98b6b0446df52ad286948ab7745da80a1edeb32ad633b3ae" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cd/ba/ee3e3534db570f023dcae03324e6f48a4c82239c452b43a7b68ed48f9591/google_crc32c-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:2515aa89e46c6fa99190ec29bf27f33457ff98e5ca5c6c05602f74e0fb005752" }, - { url = "https://mirrors.aliyun.com/pypi/packages/15/e6/41a5f08bd93c572bb38af3840cc524f78702e06a03b9287a19990db4b299/google_crc32c-1.7.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:96e33b249776f5aa7017a494b78994cf3cc8461291d460b46e75f6bc6cc40dc8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/68/df/7fb83b89075086cb3af128f9452a4f3666024f1adbe6e11198b2d5d1f5e8/google_crc32c-1.7.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:c2dc799827990dd06b777067e27f57c2a552ddde4c4cd2d883b1b615ee92f9cf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c4/6d/d6ea742127029644575baed5c48ab4f112a5759fdde8fab0c3d87bfe2454/google_crc32c-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c29f7718f48e32810a41b17126e0ca588a0ae6158b4da2926d8074241a155d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7f/27/e7d365804e7562a2d6ccf1410b8f16b6e5496b88a2d7aa87c1ce7ea5e289/google_crc32c-1.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f30548e65291a4658c9e56f6f516159663f2b4a2c991b9af5846f0084ea25d4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5a/16/041eafb94a14902c820ca8ca090ec20f614ed0ba6d9a0619e5f676959c19/google_crc32c-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:9754f9eaa5ff82166512908f02745d5e883650d7b04d1732b5df3335986ad359" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1d/e9/696a1b43fbe048a8ec246a6af2926662aec083d228a36bc17e800d3942ec/google_crc32c-1.7.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:11b3b2f16a534c76ce3c9503800c7c2578c13a56e8e409eac273330e25b5c521" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/84/355dad7a19758bcf34f0dbfcb2666c5d519cb9c9c6b1d5ea5c23201c5462/google_crc32c-1.7.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:fd3afea81a7c7b95f98c065edc5a0fdb58f1fea5960e166962b142ec037fe5e0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bb/38/affe1fa727763a03728eac51e038760c606999c6faa7c0e02924ec99a414/google_crc32c-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d07ad3ff51f26cef5bbad66622004eca3639271230cfc2443845ec4650e1c57" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2b/05/138347cbd18fb7e49c76ed8ef80ff2fdaebde675a3f2b8c7ad273b735065/google_crc32c-1.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af6e80f83d882b247eef2c0366ec72b1ffb89433b9f35dc621d79190840f1ea6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/88/2b/7a01e7b60ef5c4ac39301b9951bcc516001b5d30e9aced440f96d8f49994/google_crc32c-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:10721764a9434546b7961194fbb1f80efbcaf45b8498ed379d64f8891d4c155b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/9e/0fca77ec4a5d4651e33662c62d44418cb1c37bd04b22f6368a0f7a7abefa/google_crc32c-1.7.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8f48dddd1451026a517d7eb1f8c4ee2491998bfa383abb5fdebf32b0aa333e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/30/11/6372577447239a1791bd1121003971b044509176e09b43775cfd630179d2/google_crc32c-1.7.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60f89e06ce462a65dd4d14a97bd29d92730713316b8b89720f9b2bb1aef270f7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e4/ce/2ceb7c6400d07e6ec6b783f0dda230ee1ea5337c5c32243cf7e97fa4fb15/google_crc32c-1.7.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1277c27428a6cc89a51f5afbc04b81fae0288fb631117383f0de4f2bf78ffad6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ff/8b/f8f4af175f99ad209cac2787592322ab711eff0ea67777be938557a89d5c/google_crc32c-1.7.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:731921158ef113bf157b8e65f13303d627fb540f173a410260f2fb7570af644c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/69/b1b05cf415df0d86691d6a8b4b7e60ab3a6fb6efb783ee5cd3ed1382bfd3/google_crc32c-1.7.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:b07d48faf8292b4db7c3d64ab86f950c2e94e93a11fd47271c28ba458e4a0d76" }, + { url = "https://mirrors.aliyun.com/pypi/packages/44/3d/92f8928ecd671bd5b071756596971c79d252d09b835cdca5a44177fa87aa/google_crc32c-1.7.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:7cc81b3a2fbd932a4313eb53cc7d9dde424088ca3a0337160f35d91826880c1d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/42/c2d15a73df79d45ed6b430b9e801d0bd8e28ac139a9012d7d58af50a385d/google_crc32c-1.7.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c67ca0a1f5b56162951a9dae987988679a7db682d6f97ce0f6381ebf0fbea4c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/ea/ac59c86a3c694afd117bb669bde32aaf17d0de4305d01d706495f09cbf19/google_crc32c-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc5319db92daa516b653600794d5b9f9439a9a121f3e162f94b0e1891c7933cb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/60/44/87e77e8476767a4a93f6cf271157c6d948eacec63688c093580af13b04be/google_crc32c-1.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcdf5a64adb747610140572ed18d011896e3b9ae5195f2514b7ff678c80f1603" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/bf/21ac7bb305cd7c1a6de9c52f71db0868e104a5b573a4977cd9d0ff830f82/google_crc32c-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:754561c6c66e89d55754106739e22fdaa93fafa8da7221b29c8b8e8270c6ec8a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/94/220139ea87822b6fdfdab4fb9ba81b3fff7ea2c82e2af34adc726085bffc/google_crc32c-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6fbab4b935989e2c3610371963ba1b86afb09537fd0c633049be82afe153ac06" }, + { url = "https://mirrors.aliyun.com/pypi/packages/94/97/789b23bdeeb9d15dc2904660463ad539d0318286d7633fe2760c10ed0c1c/google_crc32c-1.7.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:ed66cbe1ed9cbaaad9392b5259b3eba4a9e565420d734e6238813c428c3336c9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/b8/976a2b843610c211e7ccb3e248996a61e87dbb2c09b1499847e295080aec/google_crc32c-1.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee6547b657621b6cbed3562ea7826c3e11cab01cd33b74e1f677690652883e77" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/16/a3842c2cf591093b111d4a5e2bfb478ac6692d02f1b386d2a33283a19dc9/google_crc32c-1.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d68e17bad8f7dd9a49181a1f5a8f4b251c6dbc8cc96fb79f1d321dfd57d66f53" }, + { url = "https://mirrors.aliyun.com/pypi/packages/04/17/ed9aba495916fcf5fe4ecb2267ceb851fc5f273c4e4625ae453350cfd564/google_crc32c-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:6335de12921f06e1f774d0dd1fbea6bf610abe0887a1638f64d694013138be5d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dd/b7/787e2453cf8639c94b3d06c9d61f512234a82e1d12d13d18584bd3049904/google_crc32c-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2d73a68a653c57281401871dd4aeebbb6af3191dcac751a76ce430df4d403194" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ed/b4/6042c2b0cbac3ec3a69bb4c49b28d2f517b7a0f4a0232603c42c58e22b44/google_crc32c-1.7.1-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:22beacf83baaf59f9d3ab2bbb4db0fb018da8e5aebdce07ef9f09fce8220285e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/29/ad/01e7a61a5d059bc57b702d9ff6a18b2585ad97f720bd0a0dbe215df1ab0e/google_crc32c-1.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19eafa0e4af11b0a4eb3974483d55d2d77ad1911e6cf6f832e1574f6781fd337" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/a5/7279055cf004561894ed3a7bfdf5bf90a53f28fadd01af7cd166e88ddf16/google_crc32c-1.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d86616faaea68101195c6bdc40c494e4d76f41e07a37ffdef270879c15fb65" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0f/d6/77060dbd140c624e42ae3ece3df53b9d811000729a5c821b9fd671ceaac6/google_crc32c-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:b7491bdc0c7564fcf48c0179d2048ab2f7c7ba36b84ccd3a3e1c3f7a72d3bba6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/43/31e57ce04530794917dfe25243860ec141de9fadf4aa9783dffe7dac7c39/google_crc32c-1.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8e9afc74168b0b2232fb32dd202c93e46b7d5e4bf03e66ba5dc273bb3559589" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/f3/8b84cd4e0ad111e63e30eb89453f8dd308e3ad36f42305cf8c202461cdf0/google_crc32c-1.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa8136cc14dd27f34a3221c0f16fd42d8a40e4778273e61a3c19aedaa44daf6b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/1b/1693372bf423ada422f80fd88260dbfd140754adb15cbc4d7e9a68b1cb8e/google_crc32c-1.7.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85fef7fae11494e747c9fd1359a527e5970fc9603c90764843caabd3a16a0a48" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fd/3c/2a19a60a473de48717b4efb19398c3f914795b64a96cf3fbe82588044f78/google_crc32c-1.7.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6efb97eb4369d52593ad6f75e7e10d053cf00c48983f7a973105bc70b0ac4d82" }, ] [[package]] name = "google-generativeai" -version = "0.8.4" +version = "0.8.5" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "google-ai-generativelanguage" }, @@ -1941,7 +2047,7 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/9b/b0/6c6af327a8a6ef3be6fe79be1d6f1e2914d6c363aa6b081b93396f4460a7/google_generativeai-0.8.4-py3-none-any.whl", hash = "sha256:e987b33ea6decde1e69191ddcaec6ef974458864d243de7191db50c21a7c5b82" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/40/c42ff9ded9f09ec9392879a8e6538a00b2dc185e834a3392917626255419/google_generativeai-0.8.5-py3-none-any.whl", hash = "sha256:22b420817fb263f8ed520b33285f45976d5b21e904da32b80d4fd20c055123a2" }, ] [[package]] @@ -1967,14 +2073,14 @@ sdist = { url = "https://mirrors.aliyun.com/pypi/packages/77/30/b3a6f6a2e00f8153 [[package]] name = "googleapis-common-protos" -version = "1.69.2" +version = "1.70.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1b/d7/ee9d56af4e6dbe958562b5020f46263c8a4628e7952070241fc0e9b182ae/googleapis_common_protos-1.69.2.tar.gz", hash = "sha256:3e1b904a27a33c821b4b749fd31d334c0c9c30e6113023d495e48979a3dc9c5f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/39/24/33db22342cf4a2ea27c9955e6713140fedd51e8b141b5ce5260897020f1a/googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/f9/53/d35476d547a286506f0a6a634ccf1e5d288fffd53d48f0bd5fef61d68684/googleapis_common_protos-1.69.2-py3-none-any.whl", hash = "sha256:0b30452ff9c7a27d80bfc5718954063e8ab53dd3697093d3bc99581f5fd24212" }, + { url = "https://mirrors.aliyun.com/pypi/packages/86/f1/62a193f0227cf15a920390abe675f386dec35f7ae3ffe6da582d3ade42c7/googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8" }, ] [package.optional-dependencies] @@ -2006,7 +2112,8 @@ dependencies = [ { name = "hyppo" }, { name = "joblib" }, { name = "matplotlib" }, - { name = "networkx" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://mirrors.aliyun.com/pypi/simple" }, marker = "python_full_version < '3.11'" }, + { name = "networkx", version = "3.5", source = { registry = "https://mirrors.aliyun.com/pypi/simple" }, marker = "python_full_version >= '3.11'" }, { name = "numpy" }, { name = "pot" }, { name = "scikit-learn" }, @@ -2023,13 +2130,14 @@ wheels = [ [[package]] name = "graspologic-native" -version = "1.2.3" +version = "1.2.5" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d3/49/9b36ff58f951b631fdf1d4504bc099cf5007770b88d2ab5e6e8f23462067/graspologic_native-1.2.3.tar.gz", hash = "sha256:7c059f7b580248abc3fee8828b9e97ac48ac9a9554fdeafaa35862871ac5113a" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/25/2d/62b30d89533643ccf4778a18eb023f291b8877b5d85de3342f07b2d363a7/graspologic_native-1.2.5.tar.gz", hash = "sha256:27ea7e01fa44466c0b4cdd678d4561e5d3dc0cb400015683b7ae1386031257a0" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7c/16/3043a7c39f6c322a8671d09d91ed4172ad9c429cac23cf579e68ec8bb450/graspologic_native-1.2.3-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b2fe41f24fa826dc0c134c7e3c8781090c3056a0000e74ac927b34caca8b3c6b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e3/c0/58e3a2fc283a18b5ba7f751560d3f38e6286b23eceb0295f21dc20e4a18b/graspologic_native-1.2.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b25c75c31f7650905b75a7fe01f89bf8e89667bf6fcb1c733b0260599df2d00" }, - { url = "https://mirrors.aliyun.com/pypi/packages/30/5b/6e29934429e3f3c8afeb38da8060a58fe9cec4256ca90e9975d73db2660b/graspologic_native-1.2.3-cp38-abi3-win_amd64.whl", hash = "sha256:57ded2c8532878ff662888c0397f4909d70fdf0e98d808de707238c67857ab5c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ae/86/10748f4c474b0c8f6060dd379bb0c4da5d42779244bb13a58656ffb44a03/graspologic_native-1.2.5-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:bf05f2e162ae2a2a8d6e8cfccbe3586d1faa0b808159ff950478348df557c61e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/42/cc/b75ea35755340bedda29727e5388390c639ea533f55b9249f5ac3003f656/graspologic_native-1.2.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7fff06ed49c3875cf351bb09a92ae7cbc169ce92dcc4c3439e28e801f822ae" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8e/55/15e6e4f18bf249b529ac4cd1522b03f5c9ef9284a2f7bfaa1fd1f96464fe/graspologic_native-1.2.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e7e993e7d70fe0d860773fc62812fbb8cb4ef2d11d8661a1f06f8772593915" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/51/21097af79f3d68626539ab829bdbf6cc42933f020e161972927d916e394c/graspologic_native-1.2.5-cp38-abi3-win_amd64.whl", hash = "sha256:c3ef2172d774083d7e2c8e77daccd218571ddeebeb2c1703cebb1a2cc4c56e07" }, ] [[package]] @@ -2100,63 +2208,63 @@ wheels = [ [[package]] name = "grpcio" -version = "1.71.0" +version = "1.74.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1c/95/aa11fc09a85d91fbc7dd405dcb2a1e0256989d67bf89fa65ae24b3ba105a/grpcio-1.71.0.tar.gz", hash = "sha256:2b85f7820475ad3edec209d3d89a7909ada16caab05d3f2e08a7e8ae3200a55c" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/38/b4/35feb8f7cab7239c5b94bd2db71abb3d6adb5f335ad8f131abb6060840b6/grpcio-1.74.0.tar.gz", hash = "sha256:80d1f4fbb35b0742d3e3d3bb654b7381cd5f015f8497279a1e9c21ba623e01b1" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7c/c5/ef610b3f988cc0cc67b765f72b8e2db06a1db14e65acb5ae7810a6b7042e/grpcio-1.71.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:c200cb6f2393468142eb50ab19613229dcc7829b5ccee8b658a36005f6669fdd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/de/c84293c961622df302c0d5d07ec6e2d4cd3874ea42f602be2df09c4ad44f/grpcio-1.71.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b2266862c5ad664a380fbbcdbdb8289d71464c42a8c29053820ee78ba0119e5d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/38/04c9e0dc8c904570c80faa1f1349b190b63e45d6b2782ec8567b050efa9d/grpcio-1.71.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0ab8b2864396663a5b0b0d6d79495657ae85fa37dcb6498a2669d067c65c11ea" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/96/e7be331d1298fa605ea7c9ceafc931490edd3d5b33c4f695f1a0667f3491/grpcio-1.71.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c30f393f9d5ff00a71bb56de4aa75b8fe91b161aeb61d39528db6b768d7eac69" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5d/b7/7e7b7bb6bb18baf156fd4f2f5b254150dcdd6cbf0def1ee427a2fb2bfc4d/grpcio-1.71.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f250ff44843d9a0615e350c77f890082102a0318d66a99540f54769c8766ab73" }, - { url = "https://mirrors.aliyun.com/pypi/packages/13/aa/5fb756175995aeb47238d706530772d9a7ac8e73bcca1b47dc145d02c95f/grpcio-1.71.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6d8de076528f7c43a2f576bc311799f89d795aa6c9b637377cc2b1616473804" }, - { url = "https://mirrors.aliyun.com/pypi/packages/54/93/172783e01eed61f7f180617b7fa4470f504e383e32af2587f664576a7101/grpcio-1.71.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9b91879d6da1605811ebc60d21ab6a7e4bae6c35f6b63a061d61eb818c8168f6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/99/62654b220a27ed46d3313252214f4bc66261143dc9b58004085cd0646753/grpcio-1.71.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f71574afdf944e6652203cd1badcda195b2a27d9c83e6d88dc1ce3cfb73b31a5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/68/35/96116de833b330abe4412cc94edc68f99ed2fa3e39d8713ff307b3799e81/grpcio-1.71.0-cp310-cp310-win32.whl", hash = "sha256:8997d6785e93308f277884ee6899ba63baafa0dfb4729748200fcc537858a509" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b7/09/f32ef637e386f3f2c02effac49699229fa560ce9007682d24e9e212d2eb4/grpcio-1.71.0-cp310-cp310-win_amd64.whl", hash = "sha256:7d6ac9481d9d0d129224f6d5934d5832c4b1cddb96b59e7eba8416868909786a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/63/04/a085f3ad4133426f6da8c1becf0749872a49feb625a407a2e864ded3fb12/grpcio-1.71.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:d6aa986318c36508dc1d5001a3ff169a15b99b9f96ef5e98e13522c506b37eef" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b4/d5/0bc53ed33ba458de95020970e2c22aa8027b26cc84f98bea7fcad5d695d1/grpcio-1.71.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:d2c170247315f2d7e5798a22358e982ad6eeb68fa20cf7a820bb74c11f0736e7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e3/6d/ce334f7e7a58572335ccd61154d808fe681a4c5e951f8a1ff68f5a6e47ce/grpcio-1.71.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:e6f83a583ed0a5b08c5bc7a3fe860bb3c2eac1f03f1f63e0bc2091325605d2b7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/05/4a/80befd0b8b1dc2b9ac5337e57473354d81be938f87132e147c4a24a581bd/grpcio-1.71.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be74ddeeb92cc87190e0e376dbc8fc7736dbb6d3d454f2fa1f5be1dee26b9d7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c7/67/cbd63c485051eb78663355d9efd1b896cfb50d4a220581ec2cb9a15cd750/grpcio-1.71.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd0dfbe4d5eb1fcfec9490ca13f82b089a309dc3678e2edabc144051270a66e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/98/4b/7a11aa4326d7faa499f764eaf8a9b5a0eb054ce0988ee7ca34897c2b02ae/grpcio-1.71.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a2242d6950dc892afdf9e951ed7ff89473aaf744b7d5727ad56bdaace363722b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/eb/a2/cdae2d0e458b475213a011078b0090f7a1d87f9a68c678b76f6af7c6ac8c/grpcio-1.71.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0fa05ee31a20456b13ae49ad2e5d585265f71dd19fbd9ef983c28f926d45d0a7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/27/df/f345c8daaa8d8574ce9869f9b36ca220c8845923eb3087e8f317eabfc2a8/grpcio-1.71.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3d081e859fb1ebe176de33fc3adb26c7d46b8812f906042705346b314bde32c3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f2/2c/cd488dc52a1d0ae1bad88b0d203bc302efbb88b82691039a6d85241c5781/grpcio-1.71.0-cp311-cp311-win32.whl", hash = "sha256:d6de81c9c00c8a23047136b11794b3584cdc1460ed7cbc10eada50614baa1444" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ee/3f/cf92e7e62ccb8dbdf977499547dfc27133124d6467d3a7d23775bcecb0f9/grpcio-1.71.0-cp311-cp311-win_amd64.whl", hash = "sha256:24e867651fc67717b6f896d5f0cac0ec863a8b5fb7d6441c2ab428f52c651c6b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4c/83/bd4b6a9ba07825bd19c711d8b25874cd5de72c2a3fbf635c3c344ae65bd2/grpcio-1.71.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:0ff35c8d807c1c7531d3002be03221ff9ae15712b53ab46e2a0b4bb271f38537" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/ea/2e0d90c0853568bf714693447f5c73272ea95ee8dad107807fde740e595d/grpcio-1.71.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:b78a99cd1ece4be92ab7c07765a0b038194ded2e0a26fd654591ee136088d8d7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ac/bc/07a3fd8af80467390af491d7dc66882db43884128cdb3cc8524915e0023c/grpcio-1.71.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc1a1231ed23caac1de9f943d031f1bc38d0f69d2a3b243ea0d664fc1fbd7fec" }, - { url = "https://mirrors.aliyun.com/pypi/packages/16/af/21f22ea3eed3d0538b6ef7889fce1878a8ba4164497f9e07385733391e2b/grpcio-1.71.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6beeea5566092c5e3c4896c6d1d307fb46b1d4bdf3e70c8340b190a69198594" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/9d/e12ddc726dc8bd1aa6cba67c85ce42a12ba5b9dd75d5042214a59ccf28ce/grpcio-1.71.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5170929109450a2c031cfe87d6716f2fae39695ad5335d9106ae88cc32dc84c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d9/e9/38713d6d67aedef738b815763c25f092e0454dc58e77b1d2a51c9d5b3325/grpcio-1.71.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5b08d03ace7aca7b2fadd4baf291139b4a5f058805a8327bfe9aece7253b6d67" }, - { url = "https://mirrors.aliyun.com/pypi/packages/80/da/4813cd7adbae6467724fa46c952d7aeac5e82e550b1c62ed2aeb78d444ae/grpcio-1.71.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f903017db76bf9cc2b2d8bdd37bf04b505bbccad6be8a81e1542206875d0e9db" }, - { url = "https://mirrors.aliyun.com/pypi/packages/52/ca/c0d767082e39dccb7985c73ab4cf1d23ce8613387149e9978c70c3bf3b07/grpcio-1.71.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:469f42a0b410883185eab4689060a20488a1a0a00f8bbb3cbc1061197b4c5a79" }, - { url = "https://mirrors.aliyun.com/pypi/packages/00/61/7b2c8ec13303f8fe36832c13d91ad4d4ba57204b1c723ada709c346b2271/grpcio-1.71.0-cp312-cp312-win32.whl", hash = "sha256:ad9f30838550695b5eb302add33f21f7301b882937460dd24f24b3cc5a95067a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/7c/1e429c5fb26122055d10ff9a1d754790fb067d83c633ff69eddcf8e3614b/grpcio-1.71.0-cp312-cp312-win_amd64.whl", hash = "sha256:652350609332de6dac4ece254e5d7e1ff834e203d6afb769601f286886f6f3a8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/66/54/68e51a90797ad7afc5b0a7881426c337f6a9168ebab73c3210b76aa7c90d/grpcio-1.74.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:85bd5cdf4ed7b2d6438871adf6afff9af7096486fcf51818a81b77ef4dd30907" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/2a/af817c7e9843929e93e54d09c9aee2555c2e8d81b93102a9426b36e91833/grpcio-1.74.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:68c8ebcca945efff9d86d8d6d7bfb0841cf0071024417e2d7f45c5e46b5b08eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/94/d67756638d7bb07750b07d0826c68e414124574b53840ba1ff777abcd388/grpcio-1.74.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:e154d230dc1bbbd78ad2fdc3039fa50ad7ffcf438e4eb2fa30bce223a70c7486" }, + { url = "https://mirrors.aliyun.com/pypi/packages/35/f5/c5e4853bf42148fea8532d49e919426585b73eafcf379a712934652a8de9/grpcio-1.74.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8978003816c7b9eabe217f88c78bc26adc8f9304bf6a594b02e5a49b2ef9c11" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fd/75/a1991dd64b331d199935e096cc9daa3415ee5ccbe9f909aa48eded7bba34/grpcio-1.74.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3d7bd6e3929fd2ea7fbc3f562e4987229ead70c9ae5f01501a46701e08f1ad9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/a4/7cef3dbb3b073d0ce34fd507efc44ac4c9442a0ef9fba4fb3f5c551efef5/grpcio-1.74.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:136b53c91ac1d02c8c24201bfdeb56f8b3ac3278668cbb8e0ba49c88069e1bdc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/d3/587920f882b46e835ad96014087054655312400e2f1f1446419e5179a383/grpcio-1.74.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fe0f540750a13fd8e5da4b3eaba91a785eea8dca5ccd2bc2ffe978caa403090e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/95/c70a3b15a0bc83334b507e3d2ae20ee8fa38d419b8758a4d838f5c2a7d32/grpcio-1.74.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4e4181bfc24413d1e3a37a0b7889bea68d973d4b45dd2bc68bb766c140718f82" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4b/06/2e7042d06247d668ae69ea6998eca33f475fd4e2855f94dcb2aa5daef334/grpcio-1.74.0-cp310-cp310-win32.whl", hash = "sha256:1733969040989f7acc3d94c22f55b4a9501a30f6aaacdbccfaba0a3ffb255ab7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/20/e02b9dcca3ee91124060b65bbf5b8e1af80b3b76a30f694b44b964ab4d71/grpcio-1.74.0-cp310-cp310-win_amd64.whl", hash = "sha256:9e912d3c993a29df6c627459af58975b2e5c897d93287939b9d5065f000249b5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/77/b2f06db9f240a5abeddd23a0e49eae2b6ac54d85f0e5267784ce02269c3b/grpcio-1.74.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:69e1a8180868a2576f02356565f16635b99088da7df3d45aaa7e24e73a054e31" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/99/0ac8678a819c28d9a370a663007581744a9f2a844e32f0fa95e1ddda5b9e/grpcio-1.74.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8efe72fde5500f47aca1ef59495cb59c885afe04ac89dd11d810f2de87d935d4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/45/c6/a2d586300d9e14ad72e8dc211c7aecb45fe9846a51e558c5bca0c9102c7f/grpcio-1.74.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a8f0302f9ac4e9923f98d8e243939a6fb627cd048f5cd38595c97e38020dffce" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/57/5f338bf56a7f22584e68d669632e521f0de460bb3749d54533fc3d0fca4f/grpcio-1.74.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f609a39f62a6f6f05c7512746798282546358a37ea93c1fcbadf8b2fed162e3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/82/ea/a4820c4c44c8b35b1903a6c72a5bdccec92d0840cf5c858c498c66786ba5/grpcio-1.74.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c98e0b7434a7fa4e3e63f250456eaef52499fba5ae661c58cc5b5477d11e7182" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a4/17/0537630a921365928f5abb6d14c79ba4dcb3e662e0dbeede8af4138d9dcf/grpcio-1.74.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:662456c4513e298db6d7bd9c3b8df6f75f8752f0ba01fb653e252ed4a59b5a5d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/a6/85ca6cb9af3f13e1320d0a806658dca432ff88149d5972df1f7b51e87127/grpcio-1.74.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3d14e3c4d65e19d8430a4e28ceb71ace4728776fd6c3ce34016947474479683f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/a7/fe2beab970a1e25d2eff108b3cf4f7d9a53c185106377a3d1989216eba45/grpcio-1.74.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bf949792cee20d2078323a9b02bacbbae002b9e3b9e2433f2741c15bdeba1c4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/c2/2f9c945c8a248cebc3ccda1b7a1bf1775b9d7d59e444dbb18c0014e23da6/grpcio-1.74.0-cp311-cp311-win32.whl", hash = "sha256:55b453812fa7c7ce2f5c88be3018fb4a490519b6ce80788d5913f3f9d7da8c7b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/d1/a9cf9c94b55becda2199299a12b9feef0c79946b0d9d34c989de6d12d05d/grpcio-1.74.0-cp311-cp311-win_amd64.whl", hash = "sha256:86ad489db097141a907c559988c29718719aa3e13370d40e20506f11b4de0d11" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4c/5d/e504d5d5c4469823504f65687d6c8fb97b7f7bf0b34873b7598f1df24630/grpcio-1.74.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8533e6e9c5bd630ca98062e3a1326249e6ada07d05acf191a77bc33f8948f3d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/43/01/730e37056f96f2f6ce9f17999af1556df62ee8dab7fa48bceeaab5fd3008/grpcio-1.74.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:2918948864fec2a11721d91568effffbe0a02b23ecd57f281391d986847982f6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/3d/09fd100473ea5c47083889ca47ffd356576173ec134312f6aa0e13111dee/grpcio-1.74.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:60d2d48b0580e70d2e1954d0d19fa3c2e60dd7cbed826aca104fff518310d1c5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/99/12d2cca0a63c874c6d3d195629dcd85cdf5d6f98a30d8db44271f8a97b93/grpcio-1.74.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3601274bc0523f6dc07666c0e01682c94472402ac2fd1226fd96e079863bfa49" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/2c/930b0e7a2f1029bbc193443c7bc4dc2a46fedb0203c8793dcd97081f1520/grpcio-1.74.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:176d60a5168d7948539def20b2a3adcce67d72454d9ae05969a2e73f3a0feee7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/db/d5/ff8a2442180ad0867717e670f5ec42bfd8d38b92158ad6bcd864e6d4b1ed/grpcio-1.74.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e759f9e8bc908aaae0412642afe5416c9f983a80499448fcc7fab8692ae044c3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/ba/b361d390451a37ca118e4ec7dccec690422e05bc85fba2ec72b06cefec9f/grpcio-1.74.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9e7c4389771855a92934b2846bd807fc25a3dfa820fd912fe6bd8136026b2707" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/0c/3a5fa47d2437a44ced74141795ac0251bbddeae74bf81df3447edd767d27/grpcio-1.74.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cce634b10aeab37010449124814b05a62fb5f18928ca878f1bf4750d1f0c815b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ae/95/ab64703b436d99dc5217228babc76047d60e9ad14df129e307b5fec81fd0/grpcio-1.74.0-cp312-cp312-win32.whl", hash = "sha256:885912559974df35d92219e2dc98f51a16a48395f37b92865ad45186f294096c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/84/59/900aa2445891fc47a33f7d2f76e00ca5d6ae6584b20d19af9c06fa09bf9a/grpcio-1.74.0-cp312-cp312-win_amd64.whl", hash = "sha256:42f8fee287427b94be63d916c90399ed310ed10aadbf9e2e5538b3e497d269bc" }, ] [[package]] name = "grpcio-status" -version = "1.71.0" +version = "1.71.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "googleapis-common-protos" }, { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d7/53/a911467bece076020456401f55a27415d2d70d3bc2c37af06b44ea41fc5c/grpcio_status-1.71.0.tar.gz", hash = "sha256:11405fed67b68f406b3f3c7c5ae5104a79d2d309666d10d61b152e91d28fb968" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fd/d1/b6e9877fedae3add1afdeae1f89d1927d296da9cf977eca0eb08fb8a460e/grpcio_status-1.71.2.tar.gz", hash = "sha256:c7a97e176df71cdc2c179cd1847d7fc86cca5832ad12e9798d7fed6b7a1aab50" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ad/d6/31fbc43ff097d8c4c9fc3df741431b8018f67bf8dfbe6553a555f6e5f675/grpcio_status-1.71.0-py3-none-any.whl", hash = "sha256:843934ef8c09e3e858952887467f8256aac3910c55f077a359a65b2b3cde3e68" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/58/317b0134129b556a93a3b0afe00ee675b5657f0155509e22fcb853bafe2d/grpcio_status-1.71.2-py3-none-any.whl", hash = "sha256:803c98cb6a8b7dc6dbb785b1111aed739f241ab5e9da0bba96888aa74704cfd3" }, ] [[package]] name = "h11" -version = "0.14.0" +version = "0.16.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" }, + { url = "https://mirrors.aliyun.com/pypi/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86" }, ] [[package]] @@ -2242,15 +2350,15 @@ wheels = [ [[package]] name = "httpcore" -version = "1.0.7" +version = "1.0.9" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55" }, ] [[package]] @@ -2283,11 +2391,11 @@ wheels = [ [[package]] name = "httpx-sse" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6e/fa/66bd985dd0b7c109a3bcb89272ee0bfb7e2b4d06309ad7b38ff866734b2a/httpx_sse-0.4.1.tar.gz", hash = "sha256:8f44d34414bc7b21bf3602713005c5df4917884f76072479b21f68befa4ea26e" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/25/0a/6269e3473b09aed2dab8aa1a600c70f31f00ae1349bee30658f7e358a159/httpx_sse-0.4.1-py3-none-any.whl", hash = "sha256:cba42174344c3a5b06f255ce65b350880f962d99ead85e776f23c6618a377a37" }, ] [[package]] @@ -2331,16 +2439,16 @@ wheels = [ [[package]] name = "hypothesis" -version = "6.132.0" +version = "6.136.6" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "attrs" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "sortedcontainers" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/35/ff/8a67f7217f86d0bc597a2d8c958b273729592d5b2cb40430506b8fb4acbd/hypothesis-6.132.0.tar.gz", hash = "sha256:55868060add41baa6176ed9c3456655678d140c74e3514bdf03381dae6391403" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e2/d6/6c45c56cdc532f25a354cf2c93a3bebc21b91b6a48125e3acfd364161447/hypothesis-6.136.6.tar.gz", hash = "sha256:2ad2e4f2012be4d41c6515b0628d84d48af6e6c38b4db50840bd9ac0899f5856" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/36/16/92696e0da87d9799e22742afdd44978440c7a5738191929def39fc8115ac/hypothesis-6.132.0-py3-none-any.whl", hash = "sha256:9d11f81664c0688d27d37c871cee8baf4349383cf9ef9938ef6b3ae836962595" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/e2/7fd1a9b12740b3472349f7e3c216e94b1b2e03d32c9d842284b57eb5a3f8/hypothesis-6.136.6-py3-none-any.whl", hash = "sha256:1d6296dde36d42263bd44a084c74e91467e78186676e410167f920aa0374a9e7" }, ] [[package]] @@ -2369,48 +2477,55 @@ wheels = [ [[package]] name = "ijson" -version = "3.3.0" +version = "3.4.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6c/83/28e9e93a3a61913e334e3a2e78ea9924bb9f9b1ac45898977f9d9dd6133f/ijson-3.3.0.tar.gz", hash = "sha256:7f172e6ba1bee0d4c8f8ebd639577bfe429dee0f3f96775a067b8bae4492d8a0" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a3/4f/1cfeada63f5fce87536651268ddf5cca79b8b4bbb457aee4e45777964a0a/ijson-3.4.0.tar.gz", hash = "sha256:5f74dcbad9d592c428d3ca3957f7115a42689ee7ee941458860900236ae9bb13" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ad/89/96e3608499b4a500b9bc27aa8242704e675849dd65bdfa8682b00a92477e/ijson-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7f7a5250599c366369fbf3bc4e176f5daa28eb6bc7d6130d02462ed335361675" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e4/7e/1098503500f5316c5f7912a51c91aca5cbc609c09ce4ecd9c4809983c560/ijson-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f87a7e52f79059f9c58f6886c262061065eb6f7554a587be7ed3aa63e6b71b34" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/f7/27b8c27a285628719ff55b68507581c86b551eb162ce810fe51e3e1a25f2/ijson-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b73b493af9e947caed75d329676b1b801d673b17481962823a3e55fe529c8b8b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0c/c5/1698094cb6a336a223c30e1167cc1b15cdb4bfa75399c1a2eb82fa76cc3c/ijson-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5576415f3d76290b160aa093ff968f8bf6de7d681e16e463a0134106b506f49" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4b/21/c206dda0945bd832cc9b0894596b0efc2cb1819a0ac61d8be1429ac09494/ijson-3.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e9ffe358d5fdd6b878a8a364e96e15ca7ca57b92a48f588378cef315a8b019e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f4/f5/2d733e64577109a9b255d14d031e44a801fa20df9ccc58b54a31e8ecf9e6/ijson-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8643c255a25824ddd0895c59f2319c019e13e949dc37162f876c41a283361527" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8d/a8/78bfee312aa23417b86189a65f30b0edbceaee96dc6a616cc15f611187d1/ijson-3.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df3ab5e078cab19f7eaeef1d5f063103e1ebf8c26d059767b26a6a0ad8b250a3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5d/a4/aff410f7d6aa1a77ee2ab2d6a2d2758422726270cb149c908a9baf33cf58/ijson-3.3.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3dc1fb02c6ed0bae1b4bf96971258bf88aea72051b6e4cebae97cff7090c0607" }, - { url = "https://mirrors.aliyun.com/pypi/packages/77/ee/2b5122dc4713f5a954267147da36e7156240ca21b04ed5295bc0cabf0fbe/ijson-3.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e9afd97339fc5a20f0542c971f90f3ca97e73d3050cdc488d540b63fae45329a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b3/d7/ad3b266490b60c6939e8a07fd8e4b7e2002aea08eaa9572a016c3e3a9129/ijson-3.3.0-cp310-cp310-win32.whl", hash = "sha256:844c0d1c04c40fd1b60f148dc829d3f69b2de789d0ba239c35136efe9a386529" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0b/68/b9e1c743274c8a23dddb12d2ed13b5f021f6d21669d51ff7fa2e9e6c19df/ijson-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:d654d045adafdcc6c100e8e911508a2eedbd2a1b5f93f930ba13ea67d7704ee9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/df/565ba72a6f4b2c833d051af8e2228cfa0b1fef17bb44995c00ad27470c52/ijson-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:501dce8eaa537e728aa35810656aa00460a2547dcb60937c8139f36ec344d7fc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f0/42/1361eaa57ece921d0239881bae6a5e102333be5b6e0102a05ec3caadbd5a/ijson-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:658ba9cad0374d37b38c9893f4864f284cdcc7d32041f9808fba8c7bcaadf134" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f5/b0/143dbfe12e1d1303ea8d8cd6f40e95cea8f03bcad5b79708614a7856c22e/ijson-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2636cb8c0f1023ef16173f4b9a233bcdb1df11c400c603d5f299fac143ca8d70" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0d/80/b3b60c5e5be2839365b03b915718ca462c544fdc71e7a79b7262837995ef/ijson-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd174b90db68c3bcca273e9391934a25d76929d727dc75224bf244446b28b03b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8d/eb/7560fafa4d40412efddf690cb65a9bf2d3429d6035e544103acbf5561dc4/ijson-3.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97a9aea46e2a8371c4cf5386d881de833ed782901ac9f67ebcb63bb3b7d115af" }, - { url = "https://mirrors.aliyun.com/pypi/packages/51/2b/5a34c7841388dce161966e5286931518de832067cd83e6f003d93271e324/ijson-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c594c0abe69d9d6099f4ece17763d53072f65ba60b372d8ba6de8695ce6ee39e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3e/b7/1d64fbec0d0a7b0c02e9ad988a89614532028ead8bb52a2456c92e6ee35a/ijson-3.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e0ff16c224d9bfe4e9e6bd0395826096cda4a3ef51e6c301e1b61007ee2bd24" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d4/b9/01044f09850bc545ffc85b35aaec473d4f4ca2b6667299033d252c1b60dd/ijson-3.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0015354011303175eae7e2ef5136414e91de2298e5a2e9580ed100b728c07e51" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fb/0d/53856b61f3d952d299d1695c487e8e28058d01fa2adfba3d6d4b4660c242/ijson-3.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034642558afa57351a0ffe6de89e63907c4cf6849070cc10a3b2542dccda1afe" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/2d/5bd86e2307dd594840ee51c4e32de953fee837f028acf0f6afb08914cd06/ijson-3.3.0-cp311-cp311-win32.whl", hash = "sha256:192e4b65495978b0bce0c78e859d14772e841724d3269fc1667dc6d2f53cc0ea" }, - { url = "https://mirrors.aliyun.com/pypi/packages/55/e1/4ba2b65b87f67fb19d698984d92635e46d9ce9dd748ce7d009441a586710/ijson-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:72e3488453754bdb45c878e31ce557ea87e1eb0f8b4fc610373da35e8074ce42" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8a/4d/3992f7383e26a950e02dc704bc6c5786a080d5c25fe0fc5543ef477c1883/ijson-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:988e959f2f3d59ebd9c2962ae71b97c0df58323910d0b368cc190ad07429d1bb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1b/cc/3d4372e0d0b02a821b982f1fdf10385512dae9b9443c1597719dd37769a9/ijson-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b2f73f0d0fce5300f23a1383d19b44d103bb113b57a69c36fd95b7c03099b181" }, - { url = "https://mirrors.aliyun.com/pypi/packages/02/de/970d48b1ff9da5d9513c86fdd2acef5cb3415541c8069e0d92a151b84adb/ijson-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0ee57a28c6bf523d7cb0513096e4eb4dac16cd935695049de7608ec110c2b751" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5e/a0/4537722c8b3b05e82c23dfe09a3a64dd1e44a013a5ca58b1e77dfe48b2f1/ijson-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0155a8f079c688c2ccaea05de1ad69877995c547ba3d3612c1c336edc12a3a5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b2/96/54956062a99cf49f7a7064b573dcd756da0563ce57910dc34e27a473d9b9/ijson-3.3.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ab00721304af1ae1afa4313ecfa1bf16b07f55ef91e4a5b93aeaa3e2bd7917c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/07/74/795319531c5b5504508f595e631d592957f24bed7ff51a15bc4c61e7b24c/ijson-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40ee3821ee90be0f0e95dcf9862d786a7439bd1113e370736bfdf197e9765bfb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/69/6a/e0cec06fbd98851d5d233b59058c1dc2ea767c9bb6feca41aa9164fff769/ijson-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3b6987a0bc3e6d0f721b42c7a0198ef897ae50579547b0345f7f02486898f5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2a/4f/82c0d896d8dcb175f99ced7d87705057bcd13523998b48a629b90139a0dc/ijson-3.3.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:63afea5f2d50d931feb20dcc50954e23cef4127606cc0ecf7a27128ed9f9a9e6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2b/b6/8973474eba4a917885e289d9e138267d3d1f052c2d93b8c968755661a42d/ijson-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b5c3e285e0735fd8c5a26d177eca8b52512cdd8687ca86ec77a0c66e9c510182" }, - { url = "https://mirrors.aliyun.com/pypi/packages/94/25/00e66af887adbbe70002e0479c3c2340bdfa17a168e25d4ab5a27b53582d/ijson-3.3.0-cp312-cp312-win32.whl", hash = "sha256:907f3a8674e489abdcb0206723e5560a5cb1fa42470dcc637942d7b10f28b695" }, - { url = "https://mirrors.aliyun.com/pypi/packages/25/a2/e187beee237808b2c417109ae0f4f7ee7c81ecbe9706305d6ac2a509cc45/ijson-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8f890d04ad33262d0c77ead53c85f13abfb82f2c8f078dfbf24b78f59534dfdd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c3/28/2e1cf00abe5d97aef074e7835b86a94c9a06be4629a0e2c12600792b51ba/ijson-3.3.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2af323a8aec8a50fa9effa6d640691a30a9f8c4925bd5364a1ca97f1ac6b9b5c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/04/d2/8c541c28da4f931bac8177e251efe2b6902f7c486d2d4bdd669eed4ff5c0/ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f64f01795119880023ba3ce43072283a393f0b90f52b66cc0ea1a89aa64a9ccb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d0/02/8fec0b9037a368811dba7901035e8e0973ebda308f57f30c42101a16a5f7/ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a716e05547a39b788deaf22725490855337fc36613288aa8ae1601dc8c525553" }, - { url = "https://mirrors.aliyun.com/pypi/packages/47/23/90c61f978c83647112460047ea0137bde9c7fe26600ce255bb3e17ea7a21/ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473f5d921fadc135d1ad698e2697025045cd8ed7e5e842258295012d8a3bc702" }, - { url = "https://mirrors.aliyun.com/pypi/packages/20/af/aab1a36072590af62d848f03981f1c587ca40a391fc61e418e388d8b0d46/ijson-3.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd26b396bc3a1e85f4acebeadbf627fa6117b97f4c10b177d5779577c6607744" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/6b/a247ba44004154aaa71f9e6bd9f05ba412f490cc4043618efb29314f035e/ijson-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e27e50f6dcdee648f704abc5d31b976cd2f90b4642ed447cf03296d138433d09" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/1d/8d2009d74373b7dec2a49b1167e396debb896501396c70a674bb9ccc41ff/ijson-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a753be681ac930740a4af9c93cfb4edc49a167faed48061ea650dc5b0f406f1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a7/b2/a85a21ebaba81f64a326c303a94625fb94b84890c52d9efdd8acb38b6312/ijson-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a07c47aed534e0ec198e6a2d4360b259d32ac654af59c015afc517ad7973b7fb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b1/35/273dfa1f27c38eeaba105496ecb54532199f76c0120177b28315daf5aec3/ijson-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c55f48181e11c597cd7146fb31edc8058391201ead69f8f40d2ecbb0b3e4fc6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4d/37/9d3bb0e200a103ca9f8e9315c4d96ecaca43a3c1957c1ac069ea9dc9c6ba/ijson-3.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd5669f96f79d8a2dd5ae81cbd06770a4d42c435fd4a75c74ef28d9913b697d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/54/8f015c4df30200fd14435dec9c67bf675dff0fee44a16c084a8ec0f82922/ijson-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e3ddd46d16b8542c63b1b8af7006c758d4e21cc1b86122c15f8530fae773461" }, + { url = "https://mirrors.aliyun.com/pypi/packages/88/01/46a0540ad3461332edcc689a8874fa13f0a4c00f60f02d155b70e36f5e0b/ijson-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1504cec7fe04be2bb0cc33b50c9dd3f83f98c0540ad4991d4017373b7853cfe6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/da/8f8df42f3fd7ef279e20eae294738eed62d41ed5b6a4baca5121abc7cf0f/ijson-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2f2ff456adeb216603e25d7915f10584c1b958b6eafa60038d76d08fc8a5fb06" }, + { url = "https://mirrors.aliyun.com/pypi/packages/82/0a/a410d9d3b082cc2ec9738d54935a589974cbe54c0f358e4d17465594d660/ijson-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ab00d75d61613a125fbbb524551658b1ad6919a52271ca16563ca5bc2737bb1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/c6/a3e2a446b8bd2cf91cb4ca7439f128d2b379b5a79794d0ea25e379b0f4f3/ijson-3.4.0-cp310-cp310-win32.whl", hash = "sha256:ada421fd59fe2bfa4cfa64ba39aeba3f0753696cdcd4d50396a85f38b1d12b01" }, + { url = "https://mirrors.aliyun.com/pypi/packages/18/7c/e6620603df42d2ef8a92076eaa5cd2b905366e86e113adf49e7b79970bd3/ijson-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:8c75e82cec05d00ed3a4af5f4edf08f59d536ed1a86ac7e84044870872d82a33" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/0d/3e2998f4d7b7d2db2d511e4f0cf9127b6e2140c325c3cb77be46ae46ff1d/ijson-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e369bf5a173ca51846c243002ad8025d32032532523b06510881ecc8723ee54" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/7b/afef2b08af2fee5ead65fcd972fadc3e31f9ae2b517fe2c378d50a9bf79b/ijson-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:26e7da0a3cd2a56a1fde1b34231867693f21c528b683856f6691e95f9f39caec" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/4a/39f583a2a13096f5063028bb767622f09cafc9ec254c193deee6c80af59f/ijson-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c28c7f604729be22aa453e604e9617b665fa0c24cd25f9f47a970e8130c571a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/58/5b80efd54b093e479c98d14b31d7794267281f6a8729f2c94fbfab661029/ijson-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bed8bcb84d3468940f97869da323ba09ae3e6b950df11dea9b62e2b231ca1e3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/f5/f37659b1647ecc3992216277cd8a45e2194e84e8818178f77c99e1d18463/ijson-3.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:296bc824f4088f2af814aaf973b0435bc887ce3d9f517b1577cc4e7d1afb1cb7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ee/2f/4c580ac4bb5eda059b672ad0a05e4bafdae5182a6ec6ab43546763dafa91/ijson-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8145f8f40617b6a8aa24e28559d0adc8b889e56a203725226a8a60fa3501073f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6d/9e/64ec39718609faab6ed6e1ceb44f9c35d71210ad9c87fff477c03503e8f8/ijson-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b674a97bd503ea21bc85103e06b6493b1b2a12da3372950f53e1c664566a33a4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/b2/f0bf0e4a0962845597996de6de59c0078bc03a1f899e03908220039f4cf6/ijson-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8bc731cf1c3282b021d3407a601a5a327613da9ad3c4cecb1123232623ae1826" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/83/4a2e3611e2b4842b413ec84d2e54adea55ab52e4408ea0f1b1b927e19536/ijson-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:42ace5e940e0cf58c9de72f688d6829ddd815096d07927ee7e77df2648006365" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/75/2d332911ac765b44cd7da0cb2b06143521ad5e31dfcc8d8587e6e6168bc8/ijson-3.4.0-cp311-cp311-win32.whl", hash = "sha256:5be39a0df4cd3f02b304382ea8885391900ac62e95888af47525a287c50005e9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/ba/4ad571f9f7fcf5906b26e757b130c1713c5f0198a1e59568f05d53a0816c/ijson-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:0b1be1781792291e70d2e177acf564ec672a7907ba74f313583bdf39fe81f9b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/ec/317ee5b2d13e50448833ead3aa906659a32b376191f6abc2a7c6112d2b27/ijson-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:956b148f88259a80a9027ffbe2d91705fae0c004fbfba3e5a24028fbe72311a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/43/b06c96ced30cacecc5d518f89b0fd1c98c294a30ff88848b70ed7b7f72a1/ijson-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06b89960f5c721106394c7fba5760b3f67c515b8eb7d80f612388f5eca2f4621" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/df/b4aeafb7ecde463130840ee9be36130823ec94a00525049bf700883378b8/ijson-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a0bb591cf250dd7e9dfab69d634745a7f3272d31cfe879f9156e0a081fd97ee" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/7c/a80b8e361641609507f62022089626d4b8067f0826f51e1c09e4ba86eba8/ijson-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72e92de999977f4c6b660ffcf2b8d59604ccd531edcbfde05b642baf283e0de8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/44/fa416347b9a802e3646c6ff377fc3278bd7d6106e17beb339514b6a3184e/ijson-3.4.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e9602157a5b869d44b6896e64f502c712a312fcde044c2e586fccb85d3e316e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/c6/41a9ad4d42df50ff6e70fdce79b034f09b914802737ebbdc141153d8d791/ijson-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e83660edb931a425b7ff662eb49db1f10d30ca6d4d350e5630edbed098bc01" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/6f/7d01efda415b8502dce67e067ed9e8a124f53e763002c02207e542e1a2f1/ijson-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:49bf8eac1c7b7913073865a859c215488461f7591b4fa6a33c14b51cb73659d0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/95/6c/0d67024b9ecb57916c5e5ab0350251c9fe2f86dc9c8ca2b605c194bdad6a/ijson-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:160b09273cb42019f1811469508b0a057d19f26434d44752bde6f281da6d3f32" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/43/e10edcc1c6a3b619294de835e7678bfb3a1b8a75955f3689fd66a1e9e7b4/ijson-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2019ff4e6f354aa00c76c8591bd450899111c61f2354ad55cc127e2ce2492c44" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/84/1cbeee8e8190a1ebe6926569a92cf1fa80ddb380c129beb6f86559e1bb24/ijson-3.4.0-cp312-cp312-win32.whl", hash = "sha256:931c007bf6bb8330705429989b2deed6838c22b63358a330bf362b6e458ba0bf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/66/13/530802bc391c95be6fe9f96e9aa427d94067e7c0b7da7a9092344dc44c4b/ijson-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:71523f2b64cb856a820223e94d23e88369f193017ecc789bb4de198cc9d349eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a7/22/da919f16ca9254f8a9ea0ba482d2c1d012ce6e4c712dcafd8adb16b16c63/ijson-3.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:54e989c35dba9cf163d532c14bcf0c260897d5f465643f0cd1fba9c908bed7ef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6d/54/c2afd289e034d11c4909f4ea90c9dae55053bed358064f310c3dd5033657/ijson-3.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:494eeb8e87afef22fbb969a4cb81ac2c535f30406f334fb6136e9117b0bb5380" }, + { url = "https://mirrors.aliyun.com/pypi/packages/43/d6/18799b0fca9ecb8a47e22527eedcea3267e95d4567b564ef21d0299e2d12/ijson-3.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81603de95de1688958af65cd2294881a4790edae7de540b70c65c8253c5dc44a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/d6/c58032c69e9e977bf6d954f22cad0cd52092db89c454ea98926744523665/ijson-3.4.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8524be12c1773e1be466034cc49c1ecbe3d5b47bb86217bd2a57f73f970a6c19" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/03/07c6840454d5d228bb5b4509c9a7ac5b9c0b8258e2b317a53f97372be1eb/ijson-3.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17994696ec895d05e0cfa21b11c68c920c82634b4a3d8b8a1455d6fe9fdee8f7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/c7/da58a9840380308df574dfdb0276c9d802b12f6125f999e92bcef36db552/ijson-3.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0b67727aaee55d43b2e82b6a866c3cbcb2b66a5e9894212190cbd8773d0d9857" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a3/9b/0bc0594d357600c03c3b5a3a34043d764fc3ad3f0757d2f3aae5b28f6c1c/ijson-3.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cdc8c5ca0eec789ed99db29c68012dda05027af0860bb360afd28d825238d69d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/1f/506cf2574673da1adcc8a794ebb85bf857cabe6294523978637e646814de/ijson-3.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8e6b44b6ec45d5b1a0ee9d97e0e65ab7f62258727004cbbe202bf5f198bc21f7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dc/3d/a7cd8d8a6de0f3084fe4d457a8f76176e11b013867d1cad16c67d25e8bec/ijson-3.4.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b51e239e4cb537929796e840d349fc731fdc0d58b1a0683ce5465ad725321e0f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/51/aa30abc02aabfc41c95887acf5f1f88da569642d7197fbe5aa105545226d/ijson-3.4.0-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed05d43ec02be8ddb1ab59579761f6656b25d241a77fd74f4f0f7ec09074318a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c7/37/7773659b8d8d98b34234e1237352f6b446a3c12941619686c7d4a8a5c69c/ijson-3.4.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfeca1aaa59d93fd0a3718cbe5f7ef0effff85cf837e0bceb71831a47f39cc14" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cd/1f/dd52a84ed140e31a5d226cd47d98d21aa559aead35ef7bae479eab4c494c/ijson-3.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:7ca72ca12e9a1dd4252c97d952be34282907f263f7e28fcdff3a01b83981e837" }, ] [[package]] @@ -2424,14 +2539,14 @@ wheels = [ [[package]] name = "importlib-metadata" -version = "8.6.1" +version = "8.7.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "zipp" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd" }, ] [[package]] @@ -2494,7 +2609,7 @@ wheels = [ [[package]] name = "ir-datasets" -version = "0.5.10" +version = "0.5.11" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "beautifulsoup4" }, @@ -2513,9 +2628,9 @@ dependencies = [ { name = "warc3-wet-clueweb09" }, { name = "zlib-state" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b9/08/90386cd976de3ec62e279d861f2c61973621d36194566653af6750bde7af/ir_datasets-0.5.10.tar.gz", hash = "sha256:fefabe352ab4bf14f9b5f224df17c4e61053be6f53840b35b0f7f51452b3da5b" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/80/c6/f02811c51fec845ee87a10bb3675516a2d71935b203e5ddb80b7eb59b1da/ir_datasets-0.5.11.tar.gz", hash = "sha256:06c90af634ae5063c813286b35065debca1a974d26e136403d899f3ecd7ad463" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/f7/10/d922a20a8310105762352b93670b77626ed7104058dfd86cf6daf77e3af2/ir_datasets-0.5.10-py3-none-any.whl", hash = "sha256:019fc0e7d0b3768c9366bcc984c37ad843a89a14cc2067e78d8acd81813b5dd0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/38/73fa582d6997362d9b4901b2a8ba1177b2d2896aa59ab8d069a3884e2e0d/ir_datasets-0.5.11-py3-none-any.whl", hash = "sha256:ae78549e5a7fa45e50462b7acb9f0765fc344fec6054108bf3dd063050555206" }, ] [[package]] @@ -2550,46 +2665,46 @@ wheels = [ [[package]] name = "jiter" -version = "0.9.0" +version = "0.10.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1e/c2/e4562507f52f0af7036da125bb699602ead37a2332af0788f8e0a3417f36/jiter-0.9.0.tar.gz", hash = "sha256:aadba0964deb424daa24492abc3d229c60c4a31bfee205aedbf1acc7639d7893" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ee/9d/ae7ddb4b8ab3fb1b51faf4deb36cb48a4fbbd7cb36bad6a5fca4741306f7/jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/b0/82/39f7c9e67b3b0121f02a0b90d433626caa95a565c3d2449fea6bcfa3f5f5/jiter-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:816ec9b60fdfd1fec87da1d7ed46c66c44ffec37ab2ef7de5b147b2fce3fd5ad" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/07/7bf6022c5a152fca767cf5c086bb41f7c28f70cf33ad259d023b53c0b858/jiter-0.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b1d3086f8a3ee0194ecf2008cf81286a5c3e540d977fa038ff23576c023c0ea" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6c/b2/de3f3446ecba7c48f317568e111cc112613da36c7b29a6de45a1df365556/jiter-0.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1339f839b91ae30b37c409bf16ccd3dc453e8b8c3ed4bd1d6a567193651a4a51" }, - { url = "https://mirrors.aliyun.com/pypi/packages/13/cf/6485a4012af5d407689c91296105fcdb080a3538e0658d2abf679619c72f/jiter-0.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ffba79584b3b670fefae66ceb3a28822365d25b7bf811e030609a3d5b876f538" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0d/f7/4a491c568f005553240b486f8e05c82547340572d5018ef79414b4449327/jiter-0.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cfc7d0a8e899089d11f065e289cb5b2daf3d82fbe028f49b20d7b809193958d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d3/ca/f4263ecbce7f5e6bded8f52a9f1a66540b270c300b5c9f5353d163f9ac61/jiter-0.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e00a1a2bbfaaf237e13c3d1592356eab3e9015d7efd59359ac8b51eb56390a12" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ac/a2/522039e522a10bac2f2194f50e183a49a360d5f63ebf46f6d890ef8aa3f9/jiter-0.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1d9870561eb26b11448854dce0ff27a9a27cb616b632468cafc938de25e9e51" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b1/67/306a5c5abc82f2e32bd47333a1c9799499c1c3a415f8dde19dbf876f00cb/jiter-0.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9872aeff3f21e437651df378cb75aeb7043e5297261222b6441a620218b58708" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0f/89/c12fe7b65a4fb74f6c0d7b5119576f1f16c79fc2953641f31b288fad8a04/jiter-0.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1fd19112d1049bdd47f17bfbb44a2c0001061312dcf0e72765bfa8abd4aa30e5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c4/2b/d57900c5c06e6273fbaa76a19efa74dbc6e70c7427ab421bf0095dfe5d4a/jiter-0.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6ef5da104664e526836070e4a23b5f68dec1cc673b60bf1edb1bfbe8a55d0678" }, - { url = "https://mirrors.aliyun.com/pypi/packages/89/05/d8b90bfb21e58097d5a4e0224f2940568366f68488a079ae77d4b2653500/jiter-0.9.0-cp310-cp310-win32.whl", hash = "sha256:cb12e6d65ebbefe5518de819f3eda53b73187b7089040b2d17f5b39001ff31c4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2c/1d/5767f23f88e4f885090d74bbd2755518050a63040c0f59aa059947035711/jiter-0.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:c43ca669493626d8672be3b645dbb406ef25af3f4b6384cfd306da7eb2e70322" }, - { url = "https://mirrors.aliyun.com/pypi/packages/23/44/e241a043f114299254e44d7e777ead311da400517f179665e59611ab0ee4/jiter-0.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6c4d99c71508912a7e556d631768dcdef43648a93660670986916b297f1c54af" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fb/1b/a7e5e42db9fa262baaa9489d8d14ca93f8663e7f164ed5e9acc9f467fc00/jiter-0.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f60fb8ce7df529812bf6c625635a19d27f30806885139e367af93f6e734ef58" }, - { url = "https://mirrors.aliyun.com/pypi/packages/60/bf/8ebdfce77bc04b81abf2ea316e9c03b4a866a7d739cf355eae4d6fd9f6fe/jiter-0.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51c4e1a4f8ea84d98b7b98912aa4290ac3d1eabfde8e3c34541fae30e9d1f08b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a8/4e/754ebce77cff9ab34d1d0fa0fe98f5d42590fd33622509a3ba6ec37ff466/jiter-0.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f4c677c424dc76684fea3e7285a7a2a7493424bea89ac441045e6a1fb1d7b3b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/32/2c/6019587e6f5844c612ae18ca892f4cd7b3d8bbf49461ed29e384a0f13d98/jiter-0.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2221176dfec87f3470b21e6abca056e6b04ce9bff72315cb0b243ca9e835a4b5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/da/e9/c9e6546c817ab75a1a7dab6dcc698e62e375e1017113e8e983fccbd56115/jiter-0.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c7adb66f899ffa25e3c92bfcb593391ee1947dbdd6a9a970e0d7e713237d572" }, - { url = "https://mirrors.aliyun.com/pypi/packages/be/bd/976b458add04271ebb5a255e992bd008546ea04bb4dcadc042a16279b4b4/jiter-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c98d27330fdfb77913c1097a7aab07f38ff2259048949f499c9901700789ac15" }, - { url = "https://mirrors.aliyun.com/pypi/packages/07/51/fe59e307aaebec9265dbad44d9d4381d030947e47b0f23531579b9a7c2df/jiter-0.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eda3f8cc74df66892b1d06b5d41a71670c22d95a1ca2cbab73654745ce9d0419" }, - { url = "https://mirrors.aliyun.com/pypi/packages/db/55/5dcd2693794d8e6f4889389ff66ef3be557a77f8aeeca8973a97a7c00557/jiter-0.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dd5ab5ddc11418dce28343123644a100f487eaccf1de27a459ab36d6cca31043" }, - { url = "https://mirrors.aliyun.com/pypi/packages/54/d5/9f51dc90985e9eb251fbbb747ab2b13b26601f16c595a7b8baba964043bd/jiter-0.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:42f8a68a69f047b310319ef8e2f52fdb2e7976fb3313ef27df495cf77bcad965" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a6/e5/4e385945179bcf128fa10ad8dca9053d717cbe09e258110e39045c881fe5/jiter-0.9.0-cp311-cp311-win32.whl", hash = "sha256:a25519efb78a42254d59326ee417d6f5161b06f5da827d94cf521fed961b1ff2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4c/47/5e0b94c603d8e54dd1faab439b40b832c277d3b90743e7835879ab663757/jiter-0.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:923b54afdd697dfd00d368b7ccad008cccfeb1efb4e621f32860c75e9f25edbd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/af/d7/c55086103d6f29b694ec79156242304adf521577530d9031317ce5338c59/jiter-0.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7b46249cfd6c48da28f89eb0be3f52d6fdb40ab88e2c66804f546674e539ec11" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b0/01/f775dfee50beb420adfd6baf58d1c4d437de41c9b666ddf127c065e5a488/jiter-0.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:609cf3c78852f1189894383cf0b0b977665f54cb38788e3e6b941fa6d982c00e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ab/b8/09b73a793714726893e5d46d5c534a63709261af3d24444ad07885ce87cb/jiter-0.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d726a3890a54561e55a9c5faea1f7655eda7f105bd165067575ace6e65f80bb2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/6f/b8f89ec5398b2b0d344257138182cc090302854ed63ed9c9051e9c673441/jiter-0.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e89dc075c1fef8fa9be219e249f14040270dbc507df4215c324a1839522ea75" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9b/ca/978cc3183113b8e4484cc7e210a9ad3c6614396e7abd5407ea8aa1458eef/jiter-0.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04e8ffa3c353b1bc4134f96f167a2082494351e42888dfcf06e944f2729cbe1d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/13/3a/72861883e11a36d6aa314b4922125f6ae90bdccc225cd96d24cc78a66385/jiter-0.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:203f28a72a05ae0e129b3ed1f75f56bc419d5f91dfacd057519a8bd137b00c42" }, - { url = "https://mirrors.aliyun.com/pypi/packages/87/67/22728a86ef53589c3720225778f7c5fdb617080e3deaed58b04789418212/jiter-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fca1a02ad60ec30bb230f65bc01f611c8608b02d269f998bc29cca8619a919dc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/69/b9/f39728e2e2007276806d7a6609cda7fac44ffa28ca0d02c49a4f397cc0d9/jiter-0.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:237e5cee4d5d2659aaf91bbf8ec45052cc217d9446070699441a91b386ae27dc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/eb/8f/8a708bc7fd87b8a5d861f1c118a995eccbe6d672fe10c9753e67362d0dd0/jiter-0.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:528b6b71745e7326eed73c53d4aa57e2a522242320b6f7d65b9c5af83cf49b6e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/1e/65680c7488bd2365dbd2980adaf63c562d3d41d3faac192ebc7ef5b4ae25/jiter-0.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9f48e86b57bc711eb5acdfd12b6cb580a59cc9a993f6e7dcb6d8b50522dcd50d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/f3/fdc43547a9ee6e93c837685da704fb6da7dba311fc022e2766d5277dfde5/jiter-0.9.0-cp312-cp312-win32.whl", hash = "sha256:699edfde481e191d81f9cf6d2211debbfe4bd92f06410e7637dffb8dd5dfde06" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cd/9d/742b289016d155f49028fe1bfbeb935c9bf0ffeefdf77daf4a63a42bb72b/jiter-0.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:099500d07b43f61d8bd780466d429c45a7b25411b334c60ca875fa775f68ccb0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/7e/4011b5c77bec97cb2b572f566220364e3e21b51c48c5bd9c4a9c26b41b67/jiter-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd2fb72b02478f06a900a5782de2ef47e0396b3e1f7d5aba30daeb1fce66f303" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/4f/144c1b57c39692efc7ea7d8e247acf28e47d0912800b34d0ad815f6b2824/jiter-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32bb468e3af278f095d3fa5b90314728a6916d89ba3d0ffb726dd9bf7367285e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/1f/db977336d332a9406c0b1f0b82be6f71f72526a806cbb2281baf201d38e3/jiter-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8b3e0068c26ddedc7abc6fac37da2d0af16b921e288a5a613f4b86f050354f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/1c/aa30a4a775e8a672ad7f21532bdbfb269f0706b39c6ff14e1f86bdd9e5ff/jiter-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:286299b74cc49e25cd42eea19b72aa82c515d2f2ee12d11392c56d8701f52224" }, + { url = "https://mirrors.aliyun.com/pypi/packages/35/df/f8257abc4207830cb18880781b5f5b716bad5b2a22fb4330cfd357407c5b/jiter-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ed5649ceeaeffc28d87fb012d25a4cd356dcd53eff5acff1f0466b831dda2a7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/76/9e1516fd7b4278aa13a2cc7f159e56befbea9aa65c71586305e7afa8b0b3/jiter-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ab0051160cb758a70716448908ef14ad476c3774bd03ddce075f3c1f90a3d6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6d/64/67750672b4354ca20ca18d3d1ccf2c62a072e8a2d452ac3cf8ced73571ef/jiter-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03997d2f37f6b67d2f5c475da4412be584e1cec273c1cfc03d642c46db43f8cf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/4d/5c4e36d48f169a54b53a305114be3efa2bbffd33b648cd1478a688f639c1/jiter-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c404a99352d839fed80d6afd6c1d66071f3bacaaa5c4268983fc10f769112e90" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/de/ce4a6166a78810bd83763d2fa13f85f73cbd3743a325469a4a9289af6dae/jiter-0.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66e989410b6666d3ddb27a74c7e50d0829704ede652fd4c858e91f8d64b403d0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a2/a6/3bc9acce53466972964cf4ad85efecb94f9244539ab6da1107f7aed82934/jiter-0.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b532d3af9ef4f6374609a3bcb5e05a1951d3bf6190dc6b176fdb277c9bbf15ee" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b4/d8/243c2ab8426a2a4dea85ba2a2ba43df379ccece2145320dfd4799b9633c5/jiter-0.10.0-cp310-cp310-win32.whl", hash = "sha256:da9be20b333970e28b72edc4dff63d4fec3398e05770fb3205f7fb460eb48dd4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/7a/8021bd615ef7788b98fc76ff533eaac846322c170e93cbffa01979197a45/jiter-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:f59e533afed0c5b0ac3eba20d2548c4a550336d8282ee69eb07b37ea526ee4e5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/dd/6cefc6bd68b1c3c979cecfa7029ab582b57690a31cd2f346c4d0ce7951b6/jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/cf/fc33f5159ce132be1d8dd57251a1ec7a631c7df4bd11e1cd198308c6ae32/jiter-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:558cc7e44fd8e507a236bee6a02fa17199ba752874400a0ca6cd6e2196cdb7dc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/68/a4/da3f150cf1d51f6c472616fb7650429c7ce053e0c962b41b68557fdf6379/jiter-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d613e4b379a07d7c8453c5712ce7014e86c6ac93d990a0b8e7377e18505e98d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/84/34/6e8d412e60ff06b186040e77da5f83bc158e9735759fcae65b37d681f28b/jiter-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f62cf8ba0618eda841b9bf61797f21c5ebd15a7a1e19daab76e4e4b498d515b2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fb/d9/9ee86173aae4576c35a2f50ae930d2ccb4c4c236f6cb9353267aa1d626b7/jiter-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:919d139cdfa8ae8945112398511cb7fca58a77382617d279556b344867a37e61" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/2c/f955de55e74771493ac9e188b0f731524c6a995dffdcb8c255b89c6fb74b/jiter-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ddbc6ae311175a3b03bd8994881bc4635c923754932918e18da841632349db" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/5a/0e73541b6edd3f4aada586c24e50626c7815c561a7ba337d6a7eb0a915b4/jiter-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c440ea003ad10927a30521a9062ce10b5479592e8a70da27f21eeb457b4a9c5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/c0/61eeec33b8c75b31cae42be14d44f9e6fe3ac15a4e58010256ac3abf3638/jiter-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc347c87944983481e138dea467c0551080c86b9d21de6ea9306efb12ca8f606" }, + { url = "https://mirrors.aliyun.com/pypi/packages/41/22/5beb5ee4ad4ef7d86f5ea5b4509f680a20706c4a7659e74344777efb7739/jiter-0.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:13252b58c1f4d8c5b63ab103c03d909e8e1e7842d302473f482915d95fefd605" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ea/10/768e8818538e5817c637b0df52e54366ec4cebc3346108a4457ea7a98f32/jiter-0.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d1bbf3c465de4a24ab12fb7766a0003f6f9bce48b8b6a886158c4d569452dc5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/73/6d/29b7c2dc76ce93cbedabfd842fc9096d01a0550c52692dfc33d3cc889815/jiter-0.10.0-cp311-cp311-win32.whl", hash = "sha256:db16e4848b7e826edca4ccdd5b145939758dadf0dc06e7007ad0e9cfb5928ae7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/c9/d394706deb4c660137caf13e33d05a031d734eb99c051142e039d8ceb794/jiter-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c9c1d5f10e18909e993f9641f12fe1c77b3e9b533ee94ffa970acc14ded3812" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6d/b5/348b3313c58f5fbfb2194eb4d07e46a35748ba6e5b3b3046143f3040bafa/jiter-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1e274728e4a5345a6dde2d343c8da018b9d4bd4350f5a472fa91f66fda44911b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/4a/6a2397096162b21645162825f058d1709a02965606e537e3304b02742e9b/jiter-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7202ae396446c988cb2a5feb33a543ab2165b786ac97f53b59aafb803fef0744" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2a/85/1ce02cade7516b726dd88f59a4ee46914bf79d1676d1228ef2002ed2f1c9/jiter-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ba7722d6748b6920ed02a8f1726fb4b33e0fd2f3f621816a8b486c66410ab2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/d0/bb6b4f209a77190ce10ea8d7e50bf3725fc16d3372d0a9f11985a2b23eff/jiter-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:371eab43c0a288537d30e1f0b193bc4eca90439fc08a022dd83e5e07500ed026" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a0/f5/a61787da9b8847a601e6827fbc42ecb12be2c925ced3252c8ffcb56afcaf/jiter-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c675736059020365cebc845a820214765162728b51ab1e03a1b7b3abb70f74c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/12/e4/6f906272810a7b21406c760a53aadbe52e99ee070fc5c0cb191e316de30b/jiter-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c5867d40ab716e4684858e4887489685968a47e3ba222e44cde6e4a2154f959" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/ba/77013b0b8ba904bf3762f11e0129b8928bff7f978a81838dfcc958ad5728/jiter-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395bb9a26111b60141757d874d27fdea01b17e8fac958b91c20128ba8f4acc8a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/27/c62568e3ccb03368dbcc44a1ef3a423cb86778a4389e995125d3d1aaa0a4/jiter-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6842184aed5cdb07e0c7e20e5bdcfafe33515ee1741a6835353bb45fe5d1bd95" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c0/72/0d6b7e31fc17a8fdce76164884edef0698ba556b8eb0af9546ae1a06b91d/jiter-0.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62755d1bcea9876770d4df713d82606c8c1a3dca88ff39046b85a048566d56ea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/09/bc1661fbbcbeb6244bd2904ff3a06f340aa77a2b94e5a7373fd165960ea3/jiter-0.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533efbce2cacec78d5ba73a41756beff8431dfa1694b6346ce7af3a12c42202b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/84/5a5d5400e9d4d54b8004c9673bbe4403928a00d28529ff35b19e9d176b19/jiter-0.10.0-cp312-cp312-win32.whl", hash = "sha256:8be921f0cadd245e981b964dfbcd6fd4bc4e254cdc069490416dd7a2632ecc01" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9b/52/7ec47455e26f2d6e5f2ea4951a0652c06e5b995c291f723973ae9e724a65/jiter-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7c7d785ae9dda68c2678532a5a1581347e9c15362ae9f6e68f3fdbfb64f2e49" }, ] [[package]] @@ -2603,11 +2718,11 @@ wheels = [ [[package]] name = "joblib" -version = "1.4.2" +version = "1.5.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/64/33/60135848598c076ce4b231e1b1895170f45fbcaeaa2c9d5e38b04db70c35/joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/dc/fe/0f5a938c54105553436dbff7a61dc4fed4b1b2c98852f8833beaf4d5968f/joblib-1.5.1.tar.gz", hash = "sha256:f4f86e351f39fe3d0d32a9f2c3d8af1ee4cec285aafcb27003dda5205576b444" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/4f/1195bbac8e0c2acc5f740661631d8d750dc38d4a32b23ee5df3cde6f4e0d/joblib-1.5.1-py3-none-any.whl", hash = "sha256:4719a31f054c7d766948dcd83e9613686b27114f190f717cec7eaa2084f8a74a" }, ] [[package]] @@ -2627,7 +2742,7 @@ sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cf/a1/693351acd0a9edca [[package]] name = "jsonschema" -version = "4.23.0" +version = "4.25.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "attrs" }, @@ -2635,21 +2750,21 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d5/00/a297a868e9d0784450faa7365c2172a7d6110c763e30ba861867c32ae6a9/jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716" }, ] [[package]] name = "jsonschema-specifications" -version = "2024.10.1" +version = "2025.4.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af" }, ] [[package]] @@ -2722,21 +2837,22 @@ wheels = [ [[package]] name = "langfuse" -version = "2.60.1" +version = "3.2.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "anyio" }, { name = "backoff" }, { name = "httpx" }, - { name = "idna" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp" }, + { name = "opentelemetry-sdk" }, { name = "packaging" }, { name = "pydantic" }, { name = "requests" }, { name = "wrapt" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ee/03/0eb9cb8abe4ea7f77636e6fe06361c8bbc43b2e4eed51750d4bc792dff0b/langfuse-2.60.1.tar.gz", hash = "sha256:9801337b35d992630b4a15be20b7926d5abc114023260f1fb7151715f524fb91" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/61/0d/8fc51099cf337fb3b56cb7d305074bc0223c62e1ccabf80cc6285ccf5b31/langfuse-3.2.1.tar.gz", hash = "sha256:f79b0380dfcf52c7525bb5d7f8e9d8786a6fc8b37867def047bb388930a7beb3" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/41/d1/8b61f332f37b89770ef93ebbf8649ce2ae1c07d5f2acba5c15ea1a7dcf6c/langfuse-2.60.1-py3-none-any.whl", hash = "sha256:0147c0b74a88c57fb73f486cc9ab0c30aacd30963fefa23723611274c3fda900" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/b0/8f08df3f0fa584c4132937690c6dd33e0a116f963ecf2b35567f614e0ca7/langfuse-3.2.1-py3-none-any.whl", hash = "sha256:07a84e8c1eed6ac8e149bdda1431fd866e4aee741b66124316336fb2bc7e6a32" }, ] [[package]] @@ -2864,40 +2980,46 @@ wheels = [ [[package]] name = "lxml-html-clean" -version = "0.4.1" +version = "0.4.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "lxml" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/81/f2/fe319e3c5cb505a361b95d1e0d0d793fe28d4dcc2fc39d3cae9324dc4233/lxml_html_clean-0.4.1.tar.gz", hash = "sha256:40c838bbcf1fc72ba4ce811fbb3135913017b27820d7c16e8bc412ae1d8bc00b" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/79/b6/466e71db127950fb8d172026a8f0a9f0dc6f64c8e78e2ca79f252e5790b8/lxml_html_clean-0.4.2.tar.gz", hash = "sha256:91291e7b5db95430abf461bc53440964d58e06cc468950f9e47db64976cebcb3" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/f7/ba/2af7a60b45bf21375e111c1e2d5d721108d06c80e3d9a3cc1d767afe1731/lxml_html_clean-0.4.1-py3-none-any.whl", hash = "sha256:b704f2757e61d793b1c08bf5ad69e4c0b68d6696f4c3c1429982caf90050bcaf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4e/0b/942cb7278d6caad79343ad2ddd636ed204a47909b969d19114a3097f5aa3/lxml_html_clean-0.4.2-py3-none-any.whl", hash = "sha256:74ccfba277adcfea87a1e9294f47dd86b05d65b4da7c5b07966e3d5f3be8a505" }, ] [[package]] name = "lz4" -version = "4.4.3" +version = "4.4.4" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cc/bc/b2e79af05be82841706ddd7d78059e5f78e6ca5828f92034394b54e303b7/lz4-4.4.3.tar.gz", hash = "sha256:91ed5b71f9179bf3dbfe85d92b52d4b53de2e559aa4daa3b7de18e0dd24ad77d" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c6/5a/945f5086326d569f14c84ac6f7fcc3229f0b9b1e8cc536b951fd53dfb9e1/lz4-4.4.4.tar.gz", hash = "sha256:070fd0627ec4393011251a094e08ed9fdcc78cb4e7ab28f507638eee4e39abda" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/05/39/fce9812fff331f22a22624d88fbb02ee5de807005e4e4115ebebff52107a/lz4-4.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1ebf23ffd36b32b980f720a81990fcfdeadacafe7498fbeff7a8e058259d4e58" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f6/25/11620e915333a116637041f87e19939d0d660fb4dcc0c8e8a225b47ab5da/lz4-4.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8fe3caea61427057a9e3697c69b2403510fdccfca4483520d02b98ffae74531e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3f/86/512a52a0016b622dea4aed24098259cd90da0a1dc46e1388a75e89958aa7/lz4-4.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e86c7fbe46f6e2e9dfb5377ee690fb8987e8e8363f435886ab91012b88f08a26" }, - { url = "https://mirrors.aliyun.com/pypi/packages/66/97/2756e8af2e3c2116f74197136acef206fe1137db3c4325adbf0b9517d657/lz4-4.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a46f48740584eab3194fbee91c61f7fa396dbb1c5e7aa76ca08165d4e63fb40f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fb/33/dc799d86bef9db36a708f80d87dce3f693a946baf55b395999bc55b94dd2/lz4-4.4.3-cp310-cp310-win32.whl", hash = "sha256:434a1d1547a0547164866f1ccc31bbda235ac5b9087f24a84956756b52371f40" }, - { url = "https://mirrors.aliyun.com/pypi/packages/10/a4/47e2bd8f071e52f58b557228c7b930a6aa34977d31ccb32498a9463debff/lz4-4.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:0aea6f283abd6acb1883b70d7a117b913e20c770845559f9421394bc9c522b24" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6e/28/9b72434d3f41f49637138ff4545e3900b34ece8771e20b84d268b28f4d11/lz4-4.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b1b98f0a4137d01b84c680813eef6198e1e00f1f28bc20ce7b5c436459a0d146" }, - { url = "https://mirrors.aliyun.com/pypi/packages/27/08/ab9008c869ad16f158255514e1870156cebf9c2bf0509aadfddeb5dc2183/lz4-4.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20e385cb8bd8321593788f11101d8c89a823a56191978e427e3c5141e129f14b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/3c/00115af6394c26bb54f863eba5680fdb7962747944db0b1df6c757a61054/lz4-4.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c9e32989df06c57f10aa09ad9b30e8a25baf1aefe850e13b0ea5de600477d6a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e1/6d/693b58fe1fcb2118a5bb858417212bcc6b24794ccf3e9ffb4ccaab7ddf1c/lz4-4.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c3d2d5df5476b065aae9d1ad551fdc7b17c151b84e8edd9212108946b2337c66" }, - { url = "https://mirrors.aliyun.com/pypi/packages/80/c6/05179ce2968c434208f2a816de2ebef86b04249d77c694fdd7c8fba0d12b/lz4-4.4.3-cp311-cp311-win32.whl", hash = "sha256:e365850166729fa82be618f476966161d5c47ea081eafc4febfc542bc85bac5d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/b3/26e04a07a9f5d3f4682853d0bd4ebf1fc83ceb3c72cc55c50bbfbe15a0a2/lz4-4.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:7f5c05bd4b0909b682608c453acc31f1a9170d55f56d27cd701213e0683fc66a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7e/40/9a6db39950ba872c3b75ccf4826288a46b109ded1d20508d6044cc36e33c/lz4-4.4.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:43461e439ef71d49bb0ee3a1719494cd952a58d205496698e0cde866f22006bc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b7/25/edd77ac155e167f0d183f0a30be1665ab581f77108ca6e19d628cd381e42/lz4-4.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ae50a175fb7b900f7aa42575f4fe99c32ca0ff57e5a8c1fd25e1243e67409db" }, - { url = "https://mirrors.aliyun.com/pypi/packages/55/59/80673123358c0e0b2b773b74ac3d14717e35cfcceac5243b61f88e08b883/lz4-4.4.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38df5929ffefa9dda120ba1790a2e94fda81916c5aaa1ee652f4b1e515ebb9ed" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/69/24a3d8609f9a05d93b407d93842d35e953bebf625cb4d128a9105c983d59/lz4-4.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b45914f25d916324531d0259072b402c5f99b67c6e9ac8cbc3d49935aeb1d97" }, - { url = "https://mirrors.aliyun.com/pypi/packages/88/6e/680d0fc3dbec31aaffcad23d2e429b2974253ffda4636ea8a7e2cce5461c/lz4-4.4.3-cp312-cp312-win32.whl", hash = "sha256:848c5b040d2cfe35097b1d65d1095d83a3f86374ce879e189533f61405d8763b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d4/c9/8fcaf3445d3dc2973861b1a1a27090e23952807facabcf092a587ff77754/lz4-4.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:b1d179bdefd9ddb8d11d7de7825e73fb957511b722a8cb484e417885c210e68c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/80/4054e99cda2e003097f59aeb3ad470128f3298db5065174a84564d2d6983/lz4-4.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f170abb8416c4efca48e76cac2c86c3185efdf841aecbe5c190121c42828ced0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dd/4e/f92424d5734e772b05ddbeec739e2566e2a2336995b36a180e1dd9411e9a/lz4-4.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d33a5105cd96ebd32c3e78d7ece6123a9d2fb7c18b84dec61f27837d9e0c496c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a2/70/71ffd496067cba6ba352e10b89c0e9cee3e4bc4717ba866b6aa350f4c7ac/lz4-4.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ebbc5b76b4f0018988825a7e9ce153be4f0d4eba34e6c1f2fcded120573e88" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/59/cf34d1e232b11e1ae7122300be00529f369a7cd80f74ac351d58c4c4eedf/lz4-4.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc64d6dfa7a89397529b22638939e70d85eaedc1bd68e30a29c78bfb65d4f715" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f9/f6/3a00a98ff5b872d572cc6e9c88e0f6275bea0f3ed1dc1b8f8b736c85784c/lz4-4.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a355223a284f42a723c120ce68827de66d5cb872a38732b3d5abbf544fa2fe26" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/de/6aeb602786174bad290609c0c988afb1077b74a80eaea23ebc3b5de6e2fa/lz4-4.4.4-cp310-cp310-win32.whl", hash = "sha256:b28228197775b7b5096898851d59ef43ccaf151136f81d9c436bc9ba560bc2ba" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e4/b5/1f52c8b17d02ae637f85911c0135ca08be1c9bbdfb3e7de1c4ae7af0bac6/lz4-4.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:45e7c954546de4f85d895aa735989d77f87dd649f503ce1c8a71a151b092ed36" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/e7/123587e7dae6cdba48393e4fdad2b9412f43f51346afe9ca6f697029de11/lz4-4.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:e3fc90f766401684740978cd781d73b9685bd81b5dbf7257542ef9de4612e4d2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/28/e8/63843dc5ecb1529eb38e1761ceed04a0ad52a9ad8929ab8b7930ea2e4976/lz4-4.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ddfc7194cd206496c445e9e5b0c47f970ce982c725c87bd22de028884125b68f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e4/94/c53de5f07c7dc11cf459aab2a1d754f5df5f693bfacbbe1e4914bfd02f1e/lz4-4.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:714f9298c86f8e7278f1c6af23e509044782fa8220eb0260f8f8f1632f820550" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/59/c22d516dd0352f2a3415d1f665ccef2f3e74ecec3ca6a8f061a38f97d50d/lz4-4.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8474c91de47733856c6686df3c4aca33753741da7e757979369c2c0d32918ba" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/af/665685072e71f3f0e626221b7922867ec249cd8376aca761078c8f11f5da/lz4-4.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80dd27d7d680ea02c261c226acf1d41de2fd77af4fb2da62b278a9376e380de0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/90/04/b4557ae381d3aa451388a29755cc410066f5e2f78c847f66f154f4520a68/lz4-4.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b7d6dddfd01b49aedb940fdcaf32f41dc58c926ba35f4e31866aeec2f32f4f4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7b/e4/03636979f4e8bf92c557f998ca98ee4e6ef92e92eaf0ed6d3c7f2524e790/lz4-4.4.4-cp311-cp311-win32.whl", hash = "sha256:4134b9fd70ac41954c080b772816bb1afe0c8354ee993015a83430031d686a4c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/f0/9efe53b4945441a5d2790d455134843ad86739855b7e6199977bf6dc8898/lz4-4.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:f5024d3ca2383470f7c4ef4d0ed8eabad0b22b23eeefde1c192cf1a38d5e9f78" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/c8/1675527549ee174b9e1db089f7ddfbb962a97314657269b1e0344a5eaf56/lz4-4.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:6ea715bb3357ea1665f77874cf8f55385ff112553db06f3742d3cdcec08633f7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/2d/5523b4fabe11cd98f040f715728d1932eb7e696bfe94391872a823332b94/lz4-4.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:23ae267494fdd80f0d2a131beff890cf857f1b812ee72dbb96c3204aab725553" }, + { url = "https://mirrors.aliyun.com/pypi/packages/91/06/1a5bbcacbfb48d8ee5b6eb3fca6aa84143a81d92946bdb5cd6b005f1863e/lz4-4.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fff9f3a1ed63d45cb6514bfb8293005dc4141341ce3500abdfeb76124c0b9b2e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/08/39eb7ac907f73e11a69a11576a75a9e36406b3241c0ba41453a7eb842abb/lz4-4.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ea7f07329f85a8eda4d8cf937b87f27f0ac392c6400f18bea2c667c8b7f8ecc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/26/05840fbd4233e8d23e88411a066ab19f1e9de332edddb8df2b6a95c7fddc/lz4-4.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ccab8f7f7b82f9fa9fc3b0ba584d353bd5aa818d5821d77d5b9447faad2aaad" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b7/5d/5f2db18c298a419932f3ab2023deb689863cf8fd7ed875b1c43492479af2/lz4-4.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43e9d48b2daf80e486213128b0763deed35bbb7a59b66d1681e205e1702d735" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c4/e6/736ab5f128694b0f6aac58343bcf37163437ac95997276cd0be3ea4c3342/lz4-4.4.4-cp312-cp312-win32.whl", hash = "sha256:33e01e18e4561b0381b2c33d58e77ceee850a5067f0ece945064cbaac2176962" }, + { url = "https://mirrors.aliyun.com/pypi/packages/40/b8/243430cb62319175070e06e3a94c4c7bd186a812e474e22148ae1290d47d/lz4-4.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d21d1a2892a2dcc193163dd13eaadabb2c1b803807a5117d8f8588b22eaf9f12" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6c/e1/0686c91738f3e6c2e1a243e0fdd4371667c4d2e5009b0a3605806c2aa020/lz4-4.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:2f4f2965c98ab254feddf6b5072854a6935adab7bc81412ec4fe238f07b85f62" }, ] [[package]] @@ -2970,10 +3092,11 @@ wheels = [ [[package]] name = "matplotlib" -version = "3.10.1" +version = "3.10.3" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "contourpy" }, + { name = "contourpy", version = "1.3.2", source = { registry = "https://mirrors.aliyun.com/pypi/simple" }, marker = "python_full_version < '3.11'" }, + { name = "contourpy", version = "1.3.3", source = { registry = "https://mirrors.aliyun.com/pypi/simple" }, marker = "python_full_version >= '3.11'" }, { name = "cycler" }, { name = "fonttools" }, { name = "kiwisolver" }, @@ -2983,49 +3106,51 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/2f/08/b89867ecea2e305f408fbb417139a8dd941ecf7b23a2e02157c36da546f0/matplotlib-3.10.1.tar.gz", hash = "sha256:e8d2d0e3881b129268585bf4765ad3ee73a4591d77b9a18c214ac7e3a79fb2ba" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/26/91/d49359a21893183ed2a5b6c76bec40e0b1dcbf8ca148f864d134897cfc75/matplotlib-3.10.3.tar.gz", hash = "sha256:2f82d2c5bb7ae93aaaa4cd42aca65d76ce6376f83304fa3a630b569aca274df0" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ee/b1/f70e27cf1cd76ce2a5e1aa5579d05afe3236052c6d9b9a96325bc823a17e/matplotlib-3.10.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ff2ae14910be903f4a24afdbb6d7d3a6c44da210fc7d42790b87aeac92238a16" }, - { url = "https://mirrors.aliyun.com/pypi/packages/26/af/5ec3d4636106718bb62503a03297125d4514f98fe818461bd9e6b9d116e4/matplotlib-3.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0721a3fd3d5756ed593220a8b86808a36c5031fce489adb5b31ee6dbb47dd5b2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a1/3d/07f9003a71b698b848c9925d05979ffa94a75cd25d1a587202f0bb58aa81/matplotlib-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0673b4b8f131890eb3a1ad058d6e065fb3c6e71f160089b65f8515373394698" }, - { url = "https://mirrors.aliyun.com/pypi/packages/12/87/9472d4513ff83b7cd864311821793ab72234fa201ab77310ec1b585d27e2/matplotlib-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e875b95ac59a7908978fe307ecdbdd9a26af7fa0f33f474a27fcf8c99f64a19" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/9e/fe74d237d2963adae8608faeb21f778cf246dbbf4746cef87cffbc82c4b6/matplotlib-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2589659ea30726284c6c91037216f64a506a9822f8e50592d48ac16a2f29e044" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b6/1b/025d3e59e8a4281ab463162ad7d072575354a1916aba81b6a11507dfc524/matplotlib-3.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a97ff127f295817bc34517255c9db6e71de8eddaab7f837b7d341dee9f2f587f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a5/14/a1b840075be247bb1834b22c1e1d558740b0f618fe3a823740181ca557a1/matplotlib-3.10.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:057206ff2d6ab82ff3e94ebd94463d084760ca682ed5f150817b859372ec4401" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0a/e4/300b08e3e08f9c98b0d5635f42edabf2f7a1d634e64cb0318a71a44ff720/matplotlib-3.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a144867dd6bf8ba8cb5fc81a158b645037e11b3e5cf8a50bd5f9917cb863adfe" }, - { url = "https://mirrors.aliyun.com/pypi/packages/75/f9/8d99ff5a2498a5f1ccf919fb46fb945109623c6108216f10f96428f388bc/matplotlib-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56c5d9fcd9879aa8040f196a235e2dcbdf7dd03ab5b07c0696f80bc6cf04bedd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/40/b8/53fa08a5eaf78d3a7213fd6da1feec4bae14a81d9805e567013811ff0e85/matplotlib-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f69dc9713e4ad2fb21a1c30e37bd445d496524257dfda40ff4a8efb3604ab5c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/40/87/4397d2ce808467af86684a622dd112664553e81752ea8bf61bdd89d24a41/matplotlib-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c59af3e8aca75d7744b68e8e78a669e91ccbcf1ac35d0102a7b1b46883f1dd7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d7/68/0d03098b3feb786cbd494df0aac15b571effda7f7cbdec267e8a8d398c16/matplotlib-3.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:11b65088c6f3dae784bc72e8d039a2580186285f87448babb9ddb2ad0082993a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/1d/5e0dc3b59c034e43de16f94deb68f4ad8a96b3ea00f4b37c160b7474928e/matplotlib-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:66e907a06e68cb6cfd652c193311d61a12b54f56809cafbed9736ce5ad92f107" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7a/81/dae7e14042e74da658c3336ab9799128e09a1ee03964f2d89630b5d12106/matplotlib-3.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b4bb156abb8fa5e5b2b460196f7db7264fc6d62678c03457979e7d5254b7be" }, - { url = "https://mirrors.aliyun.com/pypi/packages/21/c4/22516775dcde10fc9c9571d155f90710761b028fc44f660508106c363c97/matplotlib-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1985ad3d97f51307a2cbfc801a930f120def19ba22864182dacef55277102ba6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/63/23/c0615001f67ce7c96b3051d856baedc0c818a2ed84570b9bf9bde200f85d/matplotlib-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c96f2c2f825d1257e437a1482c5a2cf4fee15db4261bd6fc0750f81ba2b4ba3d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ca/c0/a07939a82aed77770514348f4568177d7dadab9787ebc618a616fe3d665e/matplotlib-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35e87384ee9e488d8dd5a2dd7baf471178d38b90618d8ea147aced4ab59c9bea" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a6/b6/a9405484fb40746fdc6ae4502b16a9d6e53282ba5baaf9ebe2da579f68c4/matplotlib-3.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfd414bce89cc78a7e1d25202e979b3f1af799e416010a20ab2b5ebb3a02425c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/f6/10adb696d8cbeed2ab4c2e26ecf1c80dd3847bbf3891f4a0c362e0e08a5a/matplotlib-3.10.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:648406f1899f9a818cef8c0231b44dcfc4ff36f167101c3fd1c9151f24220fdc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3f/84/0603d917406072763e7f9bb37747d3d74d7ecd4b943a8c947cc3ae1cf7af/matplotlib-3.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:02582304e352f40520727984a5a18f37e8187861f954fea9be7ef06569cf85b4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/7d/6a8b31dd07ed856b3eae001c9129670ef75c4698fa1c2a6ac9f00a4a7054/matplotlib-3.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3809916157ba871bcdd33d3493acd7fe3037db5daa917ca6e77975a94cef779" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/ea/2bba25d289d389c7451f331ecd593944b3705f06ddf593fa7be75037d308/matplotlib-3.10.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:213fadd6348d106ca7db99e113f1bea1e65e383c3ba76e8556ba4a3054b65ae7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/41/81/cc70b5138c926604e8c9ed810ed4c79e8116ba72e02230852f5c12c87ba2/matplotlib-3.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3bec61cb8221f0ca6313889308326e7bb303d0d302c5cc9e523b2f2e6c73deb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4a/9a/0ff45b6bfa42bb16de597e6058edf2361c298ad5ef93b327728145161bbf/matplotlib-3.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c21ae75651c0231b3ba014b6d5e08fb969c40cdb5a011e33e99ed0c9ea86ecb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/c7/1866e972fed6d71ef136efbc980d4d1854ab7ef1ea8152bbd995ca231c81/matplotlib-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e39755580b08e30e3620efc659330eac5d6534ab7eae50fa5e31f53ee4e30" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5d/b9/748f6626d534ab7e255bdc39dc22634d337cf3ce200f261b5d65742044a1/matplotlib-3.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cf4636203e1190871d3a73664dea03d26fb019b66692cbfd642faafdad6208e8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/78/8bf07bd8fb67ea5665a6af188e70b57fcb2ab67057daa06b85a08e59160a/matplotlib-3.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:fd5641a9bb9d55f4dd2afe897a53b537c834b9012684c8444cc105895c8c16fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/bd/af9f655456f60fe1d575f54fb14704ee299b16e999704817a7645dfce6b0/matplotlib-3.10.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0ef061f74cd488586f552d0c336b2f078d43bc00dc473d2c3e7bfee2272f3fa8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/86/e1c86690610661cd716eda5f9d0b35eaf606ae6c9b6736687cfc8f2d0cd8/matplotlib-3.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d96985d14dc5f4a736bbea4b9de9afaa735f8a0fc2ca75be2fa9e96b2097369d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/51/a9f8e49af3883dacddb2da1af5fca1f7468677f1188936452dd9aaaeb9ed/matplotlib-3.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c5f0283da91e9522bdba4d6583ed9d5521566f63729ffb68334f86d0bb98049" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/e3/c82963a3b86d6e6d5874cbeaa390166458a7f1961bab9feb14d3d1a10f02/matplotlib-3.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdfa07c0ec58035242bc8b2c8aae37037c9a886370eef6850703d7583e19964b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/34/24da1027e7fcdd9e82da3194c470143c551852757a4b473a09a012f5b945/matplotlib-3.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c0b9849a17bce080a16ebcb80a7b714b5677d0ec32161a2cc0a8e5a6030ae220" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/da/948a017c3ea13fd4a97afad5fdebe2f5bbc4d28c0654510ce6fd6b06b7bd/matplotlib-3.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:eef6ed6c03717083bc6d69c2d7ee8624205c29a8e6ea5a31cd3492ecdbaee1e1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/43/6b80eb47d1071f234ef0c96ca370c2ca621f91c12045f1401b5c9b28a639/matplotlib-3.10.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ab1affc11d1f495ab9e6362b8174a25afc19c081ba5b0775ef00533a4236eea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0f/70/d61a591958325c357204870b5e7b164f93f2a8cca1dc6ce940f563909a13/matplotlib-3.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2a818d8bdcafa7ed2eed74487fdb071c09c1ae24152d403952adad11fa3c65b4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/75/70c9d2306203148cc7902a961240c5927dd8728afedf35e6a77e105a2985/matplotlib-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748ebc3470c253e770b17d8b0557f0aa85cf8c63fd52f1a61af5b27ec0b7ffee" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c4/91/ba0ae1ff4b3f30972ad01cd4a8029e70a0ec3b8ea5be04764b128b66f763/matplotlib-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed70453fd99733293ace1aec568255bc51c6361cb0da94fa5ebf0649fdb2150a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/88/d636041eb54a84b889e11872d91f7cbf036b3b0e194a70fa064eb8b04f7a/matplotlib-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dbed9917b44070e55640bd13419de83b4c918e52d97561544814ba463811cbc7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b1/79/0d1c165eac44405a86478082e225fce87874f7198300bbebc55faaf6d28d/matplotlib-3.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:cf37d8c6ef1a48829443e8ba5227b44236d7fcaf7647caa3178a4ff9f7a5be05" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/d1/f54d43e95384b312ffa4a74a4326c722f3b8187aaaa12e9a84cdf3037131/matplotlib-3.10.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:86ab63d66bbc83fdb6733471d3bff40897c1e9921cba112accd748eee4bce5e4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/a4/fbfc00c2346177c95b353dcf9b5a004106abe8730a62cb6f27e79df0a698/matplotlib-3.10.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a48f9c08bf7444b5d2391a83e75edb464ccda3c380384b36532a0962593a1751" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/b9/59e120d24a2ec5fc2d30646adb2efb4621aab3c6d83d66fb2a7a182db032/matplotlib-3.10.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb73d8aa75a237457988f9765e4dfe1c0d2453c5ca4eabc897d4309672c8e014" }, ] [[package]] name = "mcp" -version = "1.9.4" +version = "1.12.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "anyio" }, { name = "httpx" }, { name = "httpx-sse" }, + { name = "jsonschema" }, { name = "pydantic" }, { name = "pydantic-settings" }, { name = "python-multipart" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, { name = "sse-starlette" }, { name = "starlette" }, { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/06/f2/dc2450e566eeccf92d89a00c3e813234ad58e2ba1e31d11467a09ac4f3b9/mcp-1.9.4.tar.gz", hash = "sha256:cfb0bcd1a9535b42edaef89947b9e18a8feb49362e1cc059d6e7fc636f2cb09f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/66/85/f36d538b1286b7758f35c1b69d93f2719d2df90c01bd074eadd35f6afc35/mcp-1.12.2.tar.gz", hash = "sha256:a4b7c742c50ce6ed6d6a6c096cca0e3893f5aecc89a59ed06d47c4e6ba41edcc" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/97/fc/80e655c955137393c443842ffcc4feccab5b12fa7cb8de9ced90f90e6998/mcp-1.9.4-py3-none-any.whl", hash = "sha256:7fcf36b62936adb8e63f89346bccca1268eeca9bf6dfb562ee10b1dfbda9dac0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/cf/3fd38cfe43962452e4bfadc6966b2ea0afaf8e0286cb3991c247c8c33ebd/mcp-1.12.2-py3-none-any.whl", hash = "sha256:b86d584bb60193a42bd78aef01882c5c42d614e416cbf0480149839377ab5a5f" }, ] [[package]] @@ -3161,16 +3286,16 @@ wheels = [ [[package]] name = "msal" -version = "1.32.0" +version = "1.33.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "cryptography" }, { name = "pyjwt", extra = ["crypto"] }, { name = "requests" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/aa/5f/ef42ef25fba682e83a8ee326a1a788e60c25affb58d014495349e37bce50/msal-1.32.0.tar.gz", hash = "sha256:5445fe3af1da6be484991a7ab32eaa82461dc2347de105b76af92c610c3335c2" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d5/da/81acbe0c1fd7e9e4ec35f55dadeba9833a847b9a6ba2e2d1e4432da901dd/msal-1.33.0.tar.gz", hash = "sha256:836ad80faa3e25a7d71015c990ce61f704a87328b1e73bcbb0623a18cbf17510" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/93/5a/2e663ef56a5d89eba962941b267ebe5be8c5ea340a9929d286e2f5fac505/msal-1.32.0-py3-none-any.whl", hash = "sha256:9dbac5384a10bbbf4dae5c7ea0d707d14e087b92c5aa4954b3feaa2d1aa0bcb7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/86/5b/fbc73e91f7727ae1e79b21ed833308e99dc11cc1cd3d4717f579775de5e9/msal-1.33.0-py3-none-any.whl", hash = "sha256:c0cd41cecf8eaed733ee7e3be9e040291eba53b0f262d3ae9c58f38b04244273" }, ] [[package]] @@ -3216,59 +3341,68 @@ wheels = [ [[package]] name = "multidict" -version = "6.2.0" +version = "6.6.3" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/82/4a/7874ca44a1c9b23796c767dd94159f6c17e31c0e7d090552a1c623247d82/multidict-6.2.0.tar.gz", hash = "sha256:0085b0afb2446e57050140240a8595846ed64d1cbd26cef936bfab3192c673b8" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3d/2c/5dad12e82fbdf7470f29bff2171484bf07cb3b16ada60a6589af8f376440/multidict-6.6.3.tar.gz", hash = "sha256:798a9eb12dab0a6c2e29c1de6f3468af5cb2da6053a20dfa3344907eed0937cc" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/2d/ca/3ae4d9c9ba78e7bcb63e3f12974b8fa16b9a20de44e9785f5d291ccb823c/multidict-6.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b9f6392d98c0bd70676ae41474e2eecf4c7150cb419237a41f8f96043fcb81d1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/25/a4/55e595d2df586e442c85b2610542d1e14def4c6f641761125d35fb38f87c/multidict-6.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3501621d5e86f1a88521ea65d5cad0a0834c77b26f193747615b7c911e5422d2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/6f/09bc361a34bbf953e9897f69823f9c4b46aec0aaed6ec94ce63093ede317/multidict-6.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32ed748ff9ac682eae7859790d3044b50e3076c7d80e17a44239683769ff485e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b6/c7/5b51816f7c38049fc50786f46e63c009e6fecd1953fbbafa8bfe4e2eb39d/multidict-6.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc826b9a8176e686b67aa60fd6c6a7047b0461cae5591ea1dc73d28f72332a8a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1a/21/c51aca665afa93b397d2c47369f6c267193977611a55a7c9d8683dc095bc/multidict-6.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:214207dcc7a6221d9942f23797fe89144128a71c03632bf713d918db99bd36de" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2e/9b/a7b91f8ed63314e7a3c276b4ca90ae5d0267a584ca2e42106baa728622d6/multidict-6.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:05fefbc3cddc4e36da209a5e49f1094bbece9a581faa7f3589201fd95df40e5d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/84/4b590a121b1009fe79d1ae5875b4aa9339d37d23e368dd3bcf5e36d27452/multidict-6.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e851e6363d0dbe515d8de81fd544a2c956fdec6f8a049739562286727d4a00c3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b8/de/831be406b5ab0dc0d25430ddf597c6ce1a2e23a4991363f1ca48f16fb817/multidict-6.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32c9b4878f48be3e75808ea7e499d6223b1eea6d54c487a66bc10a1871e3dc6a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fa/2f/892334f4d3efc7cd11e3a64dc922a85611627380ee2de3d0627ac159a975/multidict-6.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7243c5a6523c5cfeca76e063efa5f6a656d1d74c8b1fc64b2cd1e84e507f7e2a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6c/53/bf91c5fdede9406247dcbceaa9d7e7fa08e4d0e27fa3c76a0dab126bc6b2/multidict-6.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0e5a644e50ef9fb87878d4d57907f03a12410d2aa3b93b3acdf90a741df52c49" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d4/7a/f98e1c5d14c1bbbb83025a69da9a37344f7556c09fef39979cf62b464d60/multidict-6.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0dc25a3293c50744796e87048de5e68996104d86d940bb24bc3ec31df281b191" }, - { url = "https://mirrors.aliyun.com/pypi/packages/dd/c9/af0ab78b53d5b769bc1fa751e53cc7356cef422bd1cf38ed653985a46ddf/multidict-6.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a49994481b99cd7dedde07f2e7e93b1d86c01c0fca1c32aded18f10695ae17eb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c9/53/28cc971b17e25487a089bcf720fe284478f264a6fc619427ddf7145fcb2b/multidict-6.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641cf2e3447c9ecff2f7aa6e9eee9eaa286ea65d57b014543a4911ff2799d08a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b6/9a/d7637fbe1d5928b9f6a33ce36c2ff37e0aab9aa22f5fc9552fd75fe7f364/multidict-6.2.0-cp310-cp310-win32.whl", hash = "sha256:0c383d28857f66f5aebe3e91d6cf498da73af75fbd51cedbe1adfb85e90c0460" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4e/11/04758cc18a51227dbb350a8a25c7db0620d63fb23db5b8d1f87762f05cbe/multidict-6.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:a33273a541f1e1a8219b2a4ed2de355848ecc0254264915b9290c8d2de1c74e1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/97/aa/879cf5581bd56c19f1bd2682ee4ecfd4085a404668d4ee5138b0a08eaf2a/multidict-6.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84e87a7d75fa36839a3a432286d719975362d230c70ebfa0948549cc38bd5b46" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9e/d8/e6d47c166c13c48be8efb9720afe0f5cdc4da4687547192cbc3c03903041/multidict-6.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8de4d42dffd5ced9117af2ce66ba8722402541a3aa98ffdf78dde92badb68932" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a4/20/f3f0a2ca142c81100b6d4cbf79505961b54181d66157615bba3955304442/multidict-6.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7d91a230c7f8af86c904a5a992b8c064b66330544693fd6759c3d6162382ecf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ab/2d/1724972c7aeb7aa1916a3276cb32f9c39e186456ee7ed621504e7a758322/multidict-6.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f6cad071960ba1914fa231677d21b1b4a3acdcce463cee41ea30bc82e6040cf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1a/08/ea54e7e245aaf0bb1c758578e5afba394ffccb8bd80d229a499b9b83f2b1/multidict-6.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f74f2fc51555f4b037ef278efc29a870d327053aba5cb7d86ae572426c7cccc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/97/76/960dee0424f38c71eda54101ee1ca7bb47c5250ed02f7b3e8e50b1ce0603/multidict-6.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14ed9ed1bfedd72a877807c71113deac292bf485159a29025dfdc524c326f3e1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d0/35/969fd792e2e72801d80307f0a14f5b19c066d4a51d34dded22c71401527d/multidict-6.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac3fcf9a2d369bd075b2c2965544036a27ccd277fc3c04f708338cc57533081" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a4/b8/f96657a2f744d577cfda5a7edf9da04a731b80d3239eafbfe7ca4d944695/multidict-6.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fc6af8e39f7496047c7876314f4317736eac82bf85b54c7c76cf1a6f8e35d98" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/9d/97696d052297d8e2e08195a25c7aae873a6186c147b7635f979edbe3acde/multidict-6.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f8cb1329f42fadfb40d6211e5ff568d71ab49be36e759345f91c69d1033d633" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/a0/5c106e28d42f20288c10049bc6647364287ba049dc00d6ae4f1584eb1bd1/multidict-6.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5389445f0173c197f4a3613713b5fb3f3879df1ded2a1a2e4bc4b5b9c5441b7e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/55/57/d5c60c075fef73422ae3b8f914221485b9ff15000b2db657c03bd190aee0/multidict-6.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:94a7bb972178a8bfc4055db80c51efd24baefaced5e51c59b0d598a004e8305d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/eb/56/a23f599c697a455bf65ecb0f69a5b052d6442c567d380ed423f816246824/multidict-6.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da51d8928ad8b4244926fe862ba1795f0b6e68ed8c42cd2f822d435db9c2a8f4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/34/3a/a06ff9b5899090f4bbdbf09e237964c76cecfe75d2aa921e801356314017/multidict-6.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:063be88bd684782a0715641de853e1e58a2f25b76388538bd62d974777ce9bc2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d6/28/489c0eca1df3800cb5d0a66278d5dd2a4deae747a41d1cf553e6a4c0a984/multidict-6.2.0-cp311-cp311-win32.whl", hash = "sha256:52b05e21ff05729fbea9bc20b3a791c3c11da61649ff64cce8257c82a020466d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d0/b5/c7cd5ba9581add40bc743980f82426b90d9f42db0b56502011f1b3c929df/multidict-6.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1e2a2193d3aa5cbf5758f6d5680a52aa848e0cf611da324f71e5e48a9695cc86" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a4/e2/0153a8db878aef9b2397be81e62cbc3b32ca9b94e0f700b103027db9d506/multidict-6.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:437c33561edb6eb504b5a30203daf81d4a9b727e167e78b0854d9a4e18e8950b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bb/9d/5ccb3224a976d1286f360bb4e89e67b7cdfb87336257fc99be3c17f565d7/multidict-6.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9f49585f4abadd2283034fc605961f40c638635bc60f5162276fec075f2e37a4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/62/32/ef20037f51b84b074a89bab5af46d4565381c3f825fc7cbfc19c1ee156be/multidict-6.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5dd7106d064d05896ce28c97da3f46caa442fe5a43bc26dfb258e90853b39b44" }, - { url = "https://mirrors.aliyun.com/pypi/packages/97/81/b0a7560bfc3ec72606232cd7e60159e09b9cf29e66014d770c1315868fa2/multidict-6.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e25b11a0417475f093d0f0809a149aff3943c2c56da50fdf2c3c88d57fe3dfbd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/3b/768bfc0e41179fbccd3a22925329a11755b7fdd53bec66dbf6b8772f0bce/multidict-6.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac380cacdd3b183338ba63a144a34e9044520a6fb30c58aa14077157a033c13e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/71/ac/fd2be3fe98ff54e7739448f771ba730d42036de0870737db9ae34bb8efe9/multidict-6.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61d5541f27533f803a941d3a3f8a3d10ed48c12cf918f557efcbf3cd04ef265c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/93/76/1657047da771315911a927b364a32dafce4135b79b64208ce4ac69525c56/multidict-6.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:facaf11f21f3a4c51b62931feb13310e6fe3475f85e20d9c9fdce0d2ea561b87" }, - { url = "https://mirrors.aliyun.com/pypi/packages/19/a5/9f07ffb9bf68b8aaa406c2abee27ad87e8b62a60551587b8e59ee91aea84/multidict-6.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:095a2eabe8c43041d3e6c2cb8287a257b5f1801c2d6ebd1dd877424f1e89cf29" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/23/b5ce3318d9d6c8f105c3679510f9d7202980545aad8eb4426313bd8da3ee/multidict-6.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a0cc398350ef31167e03f3ca7c19313d4e40a662adcb98a88755e4e861170bdd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ce/5c/02cffec58ffe120873dce520af593415b91cc324be0345f534ad3637da4e/multidict-6.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7c611345bbe7cb44aabb877cb94b63e86f2d0db03e382667dbd037866d44b4f8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/f3/3b19a83f4ebf53a3a2a0435f3e447aa227b242ba3fd96a92404b31fb3543/multidict-6.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8cd1a0644ccaf27e9d2f6d9c9474faabee21f0578fe85225cc5af9a61e1653df" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cc/1a/c916b54fb53168c24cb6a3a0795fd99d0a59a0ea93fa9f6edeff5565cb20/multidict-6.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:89b3857652183b8206a891168af47bac10b970d275bba1f6ee46565a758c078d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ef/1a/dcb7fb18f64b3727c61f432c1e1a0d52b3924016124e4bbc8a7d2e4fa57b/multidict-6.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:125dd82b40f8c06d08d87b3510beaccb88afac94e9ed4a6f6c71362dc7dbb04b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fb/02/7695485375106f5c542574f70e1968c391f86fa3efc9f1fd76aac0af7237/multidict-6.2.0-cp312-cp312-win32.whl", hash = "sha256:76b34c12b013d813e6cb325e6bd4f9c984db27758b16085926bbe7ceeaace626" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3c/f5/f147000fe1f4078160157b15b0790fff0513646b0f9b7404bf34007a9b44/multidict-6.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:0b183a959fb88ad1be201de2c4bdf52fa8e46e6c185d76201286a97b6f5ee65c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/fd/b247aec6add5601956d440488b7f23151d8343747e82c038af37b28d6098/multidict-6.2.0-py3-none-any.whl", hash = "sha256:5d26547423e5e71dcc562c4acdc134b900640a39abd9066d7326a7cc2324c530" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/67/414933982bce2efce7cbcb3169eaaf901e0f25baec69432b4874dfb1f297/multidict-6.6.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a2be5b7b35271f7fff1397204ba6708365e3d773579fe2a30625e16c4b4ce817" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/fe/d8a3ee1fad37dc2ef4f75488b0d9d4f25bf204aad8306cbab63d97bff64a/multidict-6.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12f4581d2930840295c461764b9a65732ec01250b46c6b2c510d7ee68872b140" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/e0/265d89af8c98240265d82b8cbcf35897f83b76cd59ee3ab3879050fd8c45/multidict-6.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dd7793bab517e706c9ed9d7310b06c8672fd0aeee5781bfad612f56b8e0f7d14" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/05/6b759379f7e8e04ccc97cfb2a5dcc5cdbd44a97f072b2272dc51281e6a40/multidict-6.6.3-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:72d8815f2cd3cf3df0f83cac3f3ef801d908b2d90409ae28102e0553af85545a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4e/f5/8d5a15488edd9a91fa4aad97228d785df208ed6298580883aa3d9def1959/multidict-6.6.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:531e331a2ee53543ab32b16334e2deb26f4e6b9b28e41f8e0c87e99a6c8e2d69" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/b5/a8f317d47d0ac5bb746d6d8325885c8967c2a8ce0bb57be5399e3642cccb/multidict-6.6.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:42ca5aa9329a63be8dc49040f63817d1ac980e02eeddba763a9ae5b4027b9c9c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/88/18b2a0d5e80515fa22716556061189c2853ecf2aa2133081ebbe85ebea38/multidict-6.6.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:208b9b9757060b9faa6f11ab4bc52846e4f3c2fb8b14d5680c8aac80af3dc751" }, + { url = "https://mirrors.aliyun.com/pypi/packages/62/bf/ebfcfd6b55a1b05ef16d0775ae34c0fe15e8dab570d69ca9941073b969e7/multidict-6.6.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:acf6b97bd0884891af6a8b43d0f586ab2fcf8e717cbd47ab4bdddc09e20652d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/44/11/780615a98fd3775fc309d0234d563941af69ade2df0bb82c91dda6ddaea1/multidict-6.6.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:68e9e12ed00e2089725669bdc88602b0b6f8d23c0c95e52b95f0bc69f7fe9b55" }, + { url = "https://mirrors.aliyun.com/pypi/packages/28/3d/35f33045e21034b388686213752cabc3a1b9d03e20969e6fa8f1b1d82db1/multidict-6.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:05db2f66c9addb10cfa226e1acb363450fab2ff8a6df73c622fefe2f5af6d4e7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/cc/ff84c03b95b430015d2166d9aae775a3985d757b94f6635010d0038d9241/multidict-6.6.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:0db58da8eafb514db832a1b44f8fa7906fdd102f7d982025f816a93ba45e3dcb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/f0/8cd49a0b37bdea673a4b793c2093f2f4ba8e7c9d6d7c9bd672fd6d38cd11/multidict-6.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:14117a41c8fdb3ee19c743b1c027da0736fdb79584d61a766da53d399b71176c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/19/5d9a0cfdafe65d82b616a45ae950975820289069f885328e8185e64283c2/multidict-6.6.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:877443eaaabcd0b74ff32ebeed6f6176c71850feb7d6a1d2db65945256ea535c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/dc/c90066151da87d1e489f147b9b4327927241e65f1876702fafec6729c014/multidict-6.6.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:70b72e749a4f6e7ed8fb334fa8d8496384840319512746a5f42fa0aec79f4d61" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ec/39/458afb0cccbb0ee9164365273be3e039efddcfcb94ef35924b7dbdb05db0/multidict-6.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43571f785b86afd02b3855c5ac8e86ec921b760298d6f82ff2a61daf5a35330b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/35/38/0016adac3990426610a081787011177e661875546b434f50a26319dc8372/multidict-6.6.3-cp310-cp310-win32.whl", hash = "sha256:20c5a0c3c13a15fd5ea86c42311859f970070e4e24de5a550e99d7c271d76318" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f3/d2/17897a8f3f2c5363d969b4c635aa40375fe1f09168dc09a7826780bfb2a4/multidict-6.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab0a34a007704c625e25a9116c6770b4d3617a071c8a7c30cd338dfbadfe6485" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2d/5f/d4a717c1e457fe44072e33fa400d2b93eb0f2819c4d669381f925b7cba1f/multidict-6.6.3-cp310-cp310-win_arm64.whl", hash = "sha256:769841d70ca8bdd140a715746199fc6473414bd02efd678d75681d2d6a8986c5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/08/f0/1a39863ced51f639c81a5463fbfa9eb4df59c20d1a8769ab9ef4ca57ae04/multidict-6.6.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18f4eba0cbac3546b8ae31e0bbc55b02c801ae3cbaf80c247fcdd89b456ff58c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/0e/a7cfa451c7b0365cd844e90b41e21fab32edaa1e42fc0c9f68461ce44ed7/multidict-6.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef43b5dd842382329e4797c46f10748d8c2b6e0614f46b4afe4aee9ac33159df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c6/bb/a14a4efc5ee748cc1904b0748be278c31b9295ce5f4d2ef66526f410b94d/multidict-6.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bd1fd5eec01494e0f2e8e446a74a85d5e49afb63d75a9934e4a5423dba21d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/f8/410677d563c2d55e063ef74fe578f9d53fe6b0a51649597a5861f83ffa15/multidict-6.6.3-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5bd8d6f793a787153956cd35e24f60485bf0651c238e207b9a54f7458b16d539" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fd/df/2b787f80059314a98e1ec6a4cc7576244986df3e56b3c755e6fc7c99e038/multidict-6.6.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bf99b4daf908c73856bd87ee0a2499c3c9a3d19bb04b9c6025e66af3fd07462" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/f2/f9117089151b9a8ab39f9019620d10d9718eec2ac89e7ca9d30f3ec78e96/multidict-6.6.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b9e59946b49dafaf990fd9c17ceafa62976e8471a14952163d10a7a630413a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/2d/7115300ec5b699faa152c56799b089a53ed69e399c3c2d528251f0aeda1a/multidict-6.6.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e2db616467070d0533832d204c54eea6836a5e628f2cb1e6dfd8cd6ba7277cb7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/15/ea/ff4bab367623e39c20d3b07637225c7688d79e4f3cc1f3b9f89867677f9a/multidict-6.6.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7394888236621f61dcdd25189b2768ae5cc280f041029a5bcf1122ac63df79f9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/74/07/2c9246cda322dfe08be85f1b8739646f2c4c5113a1422d7a407763422ec4/multidict-6.6.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f114d8478733ca7388e7c7e0ab34b72547476b97009d643644ac33d4d3fe1821" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/62/279c13d584207d5697a752a66ffc9bb19355a95f7659140cb1b3cf82180e/multidict-6.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cdf22e4db76d323bcdc733514bf732e9fb349707c98d341d40ebcc6e9318ef3d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/69/cc/e06636f48c6d51e724a8bc8d9e1db5f136fe1df066d7cafe37ef4000f86a/multidict-6.6.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e995a34c3d44ab511bfc11aa26869b9d66c2d8c799fa0e74b28a473a692532d6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/a4/66c9d8fb9acf3b226cdd468ed009537ac65b520aebdc1703dd6908b19d33/multidict-6.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:766a4a5996f54361d8d5a9050140aa5362fe48ce51c755a50c0bc3706460c430" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cf/01/c69e0317be556e46257826d5449feb4e6aa0d18573e567a48a2c14156f1f/multidict-6.6.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3893a0d7d28a7fe6ca7a1f760593bc13038d1d35daf52199d431b61d2660602b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c0/da/9cc1da0299762d20e626fe0042e71b5694f9f72d7d3f9678397cbaa71b2b/multidict-6.6.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:934796c81ea996e61914ba58064920d6cad5d99140ac3167901eb932150e2e56" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/91/b22756afec99cc31105ddd4a52f95ab32b1a4a58f4d417979c570c4a922e/multidict-6.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9ed948328aec2072bc00f05d961ceadfd3e9bfc2966c1319aeaf7b7c21219183" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/f1/adcc185b878036a20399d5be5228f3cbe7f823d78985d101d425af35c800/multidict-6.6.3-cp311-cp311-win32.whl", hash = "sha256:9f5b28c074c76afc3e4c610c488e3493976fe0e596dd3db6c8ddfbb0134dcac5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e0/d4/27652c1c6526ea6b4f5ddd397e93f4232ff5de42bea71d339bc6a6cc497f/multidict-6.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc7f6fbc61b1c16050a389c630da0b32fc6d4a3d191394ab78972bf5edc568c2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/18/23f4932019804e56d3c2413e237f866444b774b0263bcb81df2fdecaf593/multidict-6.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:d4e47d8faffaae822fb5cba20937c048d4f734f43572e7079298a6c39fb172cb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/a0/6b57988ea102da0623ea814160ed78d45a2645e4bbb499c2896d12833a70/multidict-6.6.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:056bebbeda16b2e38642d75e9e5310c484b7c24e3841dc0fb943206a72ec89d6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/7a/d1e92665b0850c6c0508f101f9cf0410c1afa24973e1115fe9c6a185ebf7/multidict-6.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e5f481cccb3c5c5e5de5d00b5141dc589c1047e60d07e85bbd7dea3d4580d63f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/52/6f/dd104490e01be6ef8bf9573705d8572f8c2d2c561f06e3826b081d9e6591/multidict-6.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:10bea2ee839a759ee368b5a6e47787f399b41e70cf0c20d90dfaf4158dfb4e55" }, + { url = "https://mirrors.aliyun.com/pypi/packages/44/fe/06e0e01b1b0611e6581b7fd5a85b43dacc08b6cea3034f902f383b0873e5/multidict-6.6.3-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:2334cfb0fa9549d6ce2c21af2bfbcd3ac4ec3646b1b1581c88e3e2b1779ec92b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/71/4f0e558fb77696b89c233c1ee2d92f3e1d5459070a0e89153c9e9e804186/multidict-6.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8fee016722550a2276ca2cb5bb624480e0ed2bd49125b2b73b7010b9090e888" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/25/cca0e68228addad24903801ed1ab42e21307a1b4b6dd2cf63da5d3ae082a/multidict-6.6.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5511cb35f5c50a2db21047c875eb42f308c5583edf96bd8ebf7d770a9d68f6d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/a3/46f2d420d86bbcb8fe660b26a10a219871a0fbf4d43cb846a4031533f3e0/multidict-6.6.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:712b348f7f449948e0a6c4564a21c7db965af900973a67db432d724619b3c680" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/73/1c743542fe00794a2ec7466abd3f312ccb8fad8dff9f36d42e18fb1ec33e/multidict-6.6.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e4e15d2138ee2694e038e33b7c3da70e6b0ad8868b9f8094a72e1414aeda9c1a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a4/11/6ec9dcbe2264b92778eeb85407d1df18812248bf3506a5a1754bc035db0c/multidict-6.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8df25594989aebff8a130f7899fa03cbfcc5d2b5f4a461cf2518236fe6f15961" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9b/2b/631b1e2afeb5f1696846d747d36cda075bfdc0bc7245d6ba5c319278d6c4/multidict-6.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:159ca68bfd284a8860f8d8112cf0521113bffd9c17568579e4d13d1f1dc76b65" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/0e/7e3b93f79efeb6111d3bf9a1a69e555ba1d07ad1c11bceb56b7310d0d7ee/multidict-6.6.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e098c17856a8c9ade81b4810888c5ad1914099657226283cab3062c0540b0643" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ad/9e/086846c1d6601948e7de556ee464a2d4c85e33883e749f46b9547d7b0704/multidict-6.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:67c92ed673049dec52d7ed39f8cf9ebbadf5032c774058b4406d18c8f8fe7063" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8c/7b/86ec260118e522f1a31550e87b23542294880c97cfbf6fb18cc67b044c66/multidict-6.6.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:bd0578596e3a835ef451784053cfd327d607fc39ea1a14812139339a18a0dbc3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8c/bd/22ce8f47abb0be04692c9fc4638508b8340987b18691aa7775d927b73f72/multidict-6.6.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:346055630a2df2115cd23ae271910b4cae40f4e336773550dca4889b12916e75" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/9c/91b7ac1691be95cd1f4a26e36a74b97cda6aa9820632d31aab4410f46ebd/multidict-6.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:555ff55a359302b79de97e0468e9ee80637b0de1fce77721639f7cd9440b3a10" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6f/5c/4d7adc739884f7a9fbe00d1eac8c034023ef8bad71f2ebe12823ca2e3649/multidict-6.6.3-cp312-cp312-win32.whl", hash = "sha256:73ab034fb8d58ff85c2bcbadc470efc3fafeea8affcf8722855fb94557f14cc5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/a3/0fbc7afdf7cb1aa12a086b02959307848eb6bcc8f66fcb66c0cb57e2a2c1/multidict-6.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:04cbcce84f63b9af41bad04a54d4cc4e60e90c35b9e6ccb130be2d75b71f8c17" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b8/95/8c825bd70ff9b02462dc18d1295dd08d3e9e4eb66856d292ffa62cfe1920/multidict-6.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:0f1130b896ecb52d2a1e615260f3ea2af55fa7dc3d7c3003ba0c3121a759b18b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a" }, ] [[package]] @@ -3291,12 +3425,9 @@ wheels = [ [[package]] name = "multitasking" -version = "0.0.11" +version = "0.0.12" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6f/75/345e196762fc51fb5b4e9504631972b1271a0cb2ba1ce2afe5b185c95b64/multitasking-0.0.11.tar.gz", hash = "sha256:4d6bc3cc65f9b2dca72fb5a787850a88dae8f620c2b36ae9b55248e51bcd6026" } -wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/3e/8a/bb3160e76e844db9e69a413f055818969c8acade64e1a9ac5ce9dfdcf6c1/multitasking-0.0.11-py3-none-any.whl", hash = "sha256:1e5b37a5f8fc1e6cfaafd1a82b6b1cc6d2ed20037d3b89c25a84f499bd7b3dd4" }, -] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/17/0d/74f0293dfd7dcc3837746d0138cbedd60b31701ecc75caec7d3f281feba0/multitasking-0.0.12.tar.gz", hash = "sha256:2fba2fa8ed8c4b85e227c5dd7dc41c7d658de3b6f247927316175a57349b84d1" } [[package]] name = "mygene" @@ -3323,11 +3454,33 @@ wheels = [ name = "networkx" version = "3.4.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +resolution-markers = [ + "python_full_version < '3.11' and sys_platform == 'darwin'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", +] sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1" } wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f" }, ] +[[package]] +name = "networkx" +version = "3.5" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'darwin'", + "python_full_version >= '3.12' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version >= '3.12' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version == '3.11.*' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec" }, +] + [[package]] name = "nltk" version = "3.9.1" @@ -3345,29 +3498,29 @@ wheels = [ [[package]] name = "numba" -version = "0.61.0" +version = "0.61.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "llvmlite" }, { name = "numpy" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3c/88/c13a935f200fda51384411e49840a8e7f70c9cb1ee8d809dd0f2477cf7ef/numba-0.61.0.tar.gz", hash = "sha256:888d2e89b8160899e19591467e8fdd4970e07606e1fbc248f239c89818d5f925" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1c/a0/e21f57604304aa03ebb8e098429222722ad99176a4f979d34af1d1ee80da/numba-0.61.2.tar.gz", hash = "sha256:8750ee147940a6637b80ecf7f95062185ad8726c8c28a2295b8ec1160a196f7d" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/77/97/8568a025b9ab8b4d53491e70d4206d5f3fc71fbe94f3097058e01ad8e7ff/numba-0.61.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:9cab9783a700fa428b1a54d65295122bc03b3de1d01fb819a6b9dbbddfdb8c43" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8c/ab/a88c20755f66543ee01c85c98b866595b92e1bd0ed80565a4889e22929a8/numba-0.61.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46c5ae094fb3706f5adf9021bfb7fc11e44818d61afee695cdee4eadfed45e98" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ae/f4/b357913089ecec1a9ddc6adc04090396928f36a484a5ab9e71b24ddba4cd/numba-0.61.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6fb74e81aa78a2303e30593d8331327dfc0d2522b5db05ac967556a26db3ef87" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/60/0e21bcf3baaf10e39d48cd224618e46a6b75d3394f465c37ce57bf98cbfa/numba-0.61.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:0ebbd4827091384ab8c4615ba1b3ca8bc639a3a000157d9c37ba85d34cd0da1b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a0/08/45c136ab59e6b11e61ce15a0d17ef03fd89eaccb0db05ad67912aaf5218a/numba-0.61.0-cp310-cp310-win_amd64.whl", hash = "sha256:43aa4d7d10c542d3c78106b8481e0cbaaec788c39ee8e3d7901682748ffdf0b4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/63/8f/f983a7c859ccad73d3cc3f86fbba94f16e137cd1ee464631d61b624363b2/numba-0.61.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:bf64c2d0f3d161af603de3825172fb83c2600bcb1d53ae8ea568d4c53ba6ac08" }, - { url = "https://mirrors.aliyun.com/pypi/packages/be/1b/c33dc847d475d5b647b4ad5aefc38df7a72283763f4cda47745050375a81/numba-0.61.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:de5aa7904741425f28e1028b85850b31f0a245e9eb4f7c38507fb893283a066c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/14/91/18b9f64b34ff318a14d072251480547f89ebfb864b2b7168e5dc5f64f502/numba-0.61.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21c2fe25019267a608e2710a6a947f557486b4b0478b02e45a81cf606a05a7d4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f2/97/1a38030c2a331e273ace1de2b61988e33d80878fda8a5eedee0cd78399d3/numba-0.61.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:74250b26ed6a1428763e774dc5b2d4e70d93f73795635b5412b8346a4d054574" }, - { url = "https://mirrors.aliyun.com/pypi/packages/df/a7/56f547de8fc197963f238fd62beb5f1d2cace047602d0577956bf6840970/numba-0.61.0-cp311-cp311-win_amd64.whl", hash = "sha256:b72bbc8708e98b3741ad0c63f9929c47b623cc4ee86e17030a4f3e301e8401ac" }, - { url = "https://mirrors.aliyun.com/pypi/packages/63/c9/c61881e7f2e253e745209f078bbd428ce23b6cf901f7d93afe166720ff95/numba-0.61.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:152146ecdbb8d8176f294e9f755411e6f270103a11c3ff50cecc413f794e52c8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e1/28/ddec0147a4933f86ceaca580aa9bb767d5632ecdb1ece6cfb3eab4ac78e5/numba-0.61.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5cafa6095716fcb081618c28a8d27bf7c001e09696f595b41836dec114be2905" }, - { url = "https://mirrors.aliyun.com/pypi/packages/18/74/6a9f0e6c76c088f8a6aa702eab31734068061dca5cc0f34e8bc1eb447de1/numba-0.61.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ffe9fe373ed30638d6e20a0269f817b2c75d447141f55a675bfcf2d1fe2e87fb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/68/d7c31e53f08e6b4669c9b5a3cd7c5fb9097220c5ef388bc099ca8ab9749f/numba-0.61.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9f25f7fef0206d55c1cfb796ad833cbbc044e2884751e56e798351280038484c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/94/4f/8357a99a14f331b865a42cb4756ae37da85599b9c95e01277ea10361e91a/numba-0.61.0-cp312-cp312-win_amd64.whl", hash = "sha256:550d389573bc3b895e1ccb18289feea11d937011de4d278b09dc7ed585d1cdcb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/ca/f470be59552ccbf9531d2d383b67ae0b9b524d435fb4a0d229fef135116e/numba-0.61.2-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:cf9f9fc00d6eca0c23fc840817ce9f439b9f03c8f03d6246c0e7f0cb15b7162a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/13/3bdf52609c80d460a3b4acfb9fdb3817e392875c0d6270cf3fd9546f138b/numba-0.61.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ea0247617edcb5dd61f6106a56255baab031acc4257bddaeddb3a1003b4ca3fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/7d/bfb2805bcfbd479f04f835241ecf28519f6e3609912e3a985aed45e21370/numba-0.61.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae8c7a522c26215d5f62ebec436e3d341f7f590079245a2f1008dfd498cc1642" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/27/797b2004745c92955470c73c82f0e300cf033c791f45bdecb4b33b12bdea/numba-0.61.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd1e74609855aa43661edffca37346e4e8462f6903889917e9f41db40907daa2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b1/c6/c2fb11e50482cb310afae87a997707f6c7d8a48967b9696271347441f650/numba-0.61.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae45830b129c6137294093b269ef0a22998ccc27bf7cf096ab8dcf7bca8946f9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3f/97/c99d1056aed767503c228f7099dc11c402906b42a4757fec2819329abb98/numba-0.61.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:efd3db391df53aaa5cfbee189b6c910a5b471488749fd6606c3f33fc984c2ae2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/95/9e/63c549f37136e892f006260c3e2613d09d5120672378191f2dc387ba65a2/numba-0.61.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49c980e4171948ffebf6b9a2520ea81feed113c1f4890747ba7f59e74be84b1b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/97/c8/8740616c8436c86c1b9a62e72cb891177d2c34c2d24ddcde4c390371bf4c/numba-0.61.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3945615cd73c2c7eba2a85ccc9c1730c21cd3958bfcf5a44302abae0fb07bb60" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fc/06/66e99ae06507c31d15ff3ecd1f108f2f59e18b6e08662cd5f8a5853fbd18/numba-0.61.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbfdf4eca202cebade0b7d43896978e146f39398909a42941c9303f82f403a18" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0f/a4/2b309a6a9f6d4d8cfba583401c7c2f9ff887adb5d54d8e2e130274c0973f/numba-0.61.2-cp311-cp311-win_amd64.whl", hash = "sha256:76bcec9f46259cedf888041b9886e257ae101c6268261b19fda8cfbc52bec9d1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b4/a0/c6b7b9c615cfa3b98c4c63f4316e3f6b3bbe2387740277006551784218cd/numba-0.61.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:34fba9406078bac7ab052efbf0d13939426c753ad72946baaa5bf9ae0ebb8dd2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/4a/fe4e3c2ecad72d88f5f8cd04e7f7cff49e718398a2fac02d2947480a00ca/numba-0.61.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ddce10009bc097b080fc96876d14c051cc0c7679e99de3e0af59014dab7dfe8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9a/2d/e518df036feab381c23a624dac47f8445ac55686ec7f11083655eb707da3/numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b1bb509d01f23d70325d3a5a0e237cbc9544dd50e50588bc581ba860c213546" }, + { url = "https://mirrors.aliyun.com/pypi/packages/10/0f/23cced68ead67b75d77cfcca3df4991d1855c897ee0ff3fe25a56ed82108/numba-0.61.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48a53a3de8f8793526cbe330f2a39fe9a6638efcbf11bd63f3d2f9757ae345cd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/68/1d/ddb3e704c5a8fb90142bf9dc195c27db02a08a99f037395503bfbc1d14b3/numba-0.61.2-cp312-cp312-win_amd64.whl", hash = "sha256:97cf4f12c728cf77c9c1d7c23707e4d8fb4632b46275f8f3397de33e5877af18" }, ] [[package]] @@ -3404,69 +3557,81 @@ wheels = [ [[package]] name = "nvidia-cublas-cu12" -version = "12.4.5.8" +version = "12.6.4.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ae/71/1c91302526c45ab494c23f61c7a84aa568b8c1f9d196efa5993957faf906/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2fc8da60df463fdefa81e323eef2e36489e1c94335b5358bcb38360adf75ac9b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/eb/ff4b8c503fa1f1796679dce648854d58751982426e4e4b37d6fce49d259c/nvidia_cublas_cu12-12.6.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08ed2686e9875d01b58e3cb379c6896df8e76c75e0d4a7f7dace3d7b6d9ef8eb" }, ] [[package]] name = "nvidia-cuda-cupti-cu12" -version = "12.4.127" +version = "12.6.80" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/67/42/f4f60238e8194a3106d06a058d494b18e006c10bb2b915655bd9f6ea4cb1/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9dec60f5ac126f7bb551c055072b69d85392b13311fcc1bcda2202d172df30fb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/49/60/7b6497946d74bcf1de852a21824d63baad12cd417db4195fc1bfe59db953/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6768bad6cab4f19e8292125e5f1ac8aa7d1718704012a0e3272a6f61c4bce132" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73" }, ] [[package]] name = "nvidia-cuda-nvrtc-cu12" -version = "12.4.127" +version = "12.6.77" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/2c/14/91ae57cd4db3f9ef7aa99f4019cfa8d54cb4caa7e00975df6467e9725a9f/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a178759ebb095827bd30ef56598ec182b85547f1508941a3d560eb7ea1fbf338" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/2e/46030320b5a80661e88039f59060d1790298b4718944a65a7f2aeda3d9e9/nvidia_cuda_nvrtc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:35b0cc6ee3a9636d5409133e79273ce1f3fd087abb0532d2d2e8fff1fe9efc53" }, ] [[package]] name = "nvidia-cuda-runtime-cu12" -version = "12.4.127" +version = "12.6.77" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ea/27/1795d86fe88ef397885f2e580ac37628ed058a92ed2c39dc8eac3adf0619/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:64403288fa2136ee8e467cdc9c9427e0434110899d07c779f25b5c068934faa5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e1/23/e717c5ac26d26cf39a27fbc076240fad2e3b817e5889d671b67f4f9f49c5/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ba3b56a4f896141e25e19ab287cd71e52a6a0f4b29d0d31609f60e3b4d5219b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8" }, ] [[package]] name = "nvidia-cudnn-cu12" -version = "9.1.0.70" +version = "9.5.1.17" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2" }, ] [[package]] name = "nvidia-cufft-cu12" -version = "11.2.1.3" +version = "11.3.0.4" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/27/94/3266821f65b92b3138631e9c8e7fe1fb513804ac934485a8d05776e1dd43/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f083fc24912aa410be21fa16d157fed2055dab1cc4b6934a0e03cba69eb242b9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/16/73727675941ab8e6ffd86ca3a4b7b47065edcca7a997920b831f8147c99d/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ccba62eb9cef5559abd5e0d54ceed2d9934030f51163df018532142a8ec533e5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca" }, +] + +[[package]] +name = "nvidia-cufile-cu12" +version = "1.11.1.6" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b2/66/cc9876340ac68ae71b15c743ddb13f8b30d5244af344ec8322b449e35426/nvidia_cufile_cu12-1.11.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc23469d1c7e52ce6c1d55253273d32c565dd22068647f3aa59b3c6b005bf159" }, ] [[package]] name = "nvidia-curand-cu12" -version = "10.3.5.147" +version = "10.3.7.77" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/8a/6d/44ad094874c6f1b9c654f8ed939590bdc408349f137f9b98a3a23ccec411/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a88f583d4e0bb643c49743469964103aa59f7f708d862c3ddb0fc07f851e3b8b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/73/1b/44a01c4e70933637c93e6e1a8063d1e998b50213a6b65ac5a9169c47e98e/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a42cd1344297f70b9e39a1e4f467a4e1c10f1da54ff7a85c12197f6c652c8bdf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4a/aa/2c7ff0b5ee02eaef890c0ce7d4f74bc30901871c5e45dee1ae6d0083cd80/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:99f1a32f1ac2bd134897fc7a203f779303261268a65762a623bf30cc9fe79117" }, ] [[package]] name = "nvidia-cusolver-cu12" -version = "11.6.1.9" +version = "11.7.1.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, @@ -3474,50 +3639,53 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/3a/e1/5b9089a4b2a4790dfdea8b3a006052cfecff58139d5a4e34cb1a51df8d6f/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:19e33fa442bcfd085b3086c4ebf7e8debc07cfe01e11513cc6d332fd918ac260" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/6e/c2cf12c9ff8b872e92b4a5740701e51ff17689c4d726fca91875b07f655d/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9e49843a7707e42022babb9bcfa33c29857a93b88020c4e4434656a655b698c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6" }, ] [[package]] name = "nvidia-cusparse-cu12" -version = "12.3.1.170" +version = "12.5.4.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/db/f7/97a9ea26ed4bbbfc2d470994b8b4f338ef663be97b8f677519ac195e113d/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ea4f11a2904e2a8dc4b1833cc1b5181cde564edd0d5cd33e3c168eff2d1863f1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/1e/b8b7c2f4099a37b96af5c9bb158632ea9e5d9d27d7391d7eb8fc45236674/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7556d9eca156e18184b94947ade0fba5bb47d69cec46bf8660fd2c71a4b48b73" }, + { url = "https://mirrors.aliyun.com/pypi/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f" }, ] [[package]] name = "nvidia-cusparselt-cu12" -version = "0.6.2" +version = "0.6.3" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/78/a8/bcbb63b53a4b1234feeafb65544ee55495e1bb37ec31b999b963cbccfd1d/nvidia_cusparselt_cu12-0.6.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:df2c24502fd76ebafe7457dbc4716b2fec071aabaed4fb7691a201cde03704d9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/9a/72ef35b399b0e183bc2e8f6f558036922d453c4d8237dab26c666a04244b/nvidia_cusparselt_cu12-0.6.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5c8a26c36445dd2e6812f1177978a24e2d37cacce7e090f297a688d1ec44f46" }, ] [[package]] name = "nvidia-nccl-cu12" -version = "2.21.5" +version = "2.26.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/df/99/12cd266d6233f47d00daf3a72739872bdc10267d0383508b0b9c84a18bb6/nvidia_nccl_cu12-2.21.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:8579076d30a8c24988834445f8d633c697d42397e92ffc3f63fa26766d25e0a0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/ca/f42388aed0fddd64ade7493dbba36e1f534d4e6fdbdd355c6a90030ae028/nvidia_nccl_cu12-2.26.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:694cf3879a206553cc9d7dbda76b13efaf610fdb70a50cba303de1b0d1530ac6" }, ] [[package]] name = "nvidia-nvjitlink-cu12" -version = "12.4.127" +version = "12.6.85" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ff/ff/847841bacfbefc97a00036e0fce5a0f086b640756dc38caea5e1bb002655/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/d7/c5383e47c7e9bf1c99d5bd2a8c935af2b6d705ad831a7ec5c97db4d82f4f/nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:eedc36df9e88b682efe4309aa16b5b4e78c2407eac59e8c10a6a47535164369a" }, ] [[package]] name = "nvidia-nvtx-cu12" -version = "12.4.127" +version = "12.6.77" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/87/20/199b8713428322a2f22b722c62b8cc278cc53dffa9705d744484b5035ee9/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:781e950d9b9f60d8241ccea575b32f5105a5baf4c2351cab5256a24869f12a1a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/56/9a/fff8376f8e3d084cd1530e1ef7b879bb7d6d265620c95c1b322725c694f4/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b90bed3df379fa79afbd21be8e04a0314336b8ae16768b58f2d34cb1d04cd7d2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/4e/0d0c945463719429b7bd21dece907ad0bde437a2ff12b9b12fee94722ab0/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6574241a3ec5fdc9334353ab8c479fe75841dbe8f4532a8fc97ce63503330ba1" }, ] [[package]] @@ -3534,29 +3702,32 @@ wheels = [ [[package]] name = "onnx" -version = "1.17.0" +version = "1.18.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "numpy" }, { name = "protobuf" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/9a/54/0e385c26bf230d223810a9c7d06628d954008a5e5e4b73ee26ef02327282/onnx-1.17.0.tar.gz", hash = "sha256:48ca1a91ff73c1d5e3ea2eef20ae5d0e709bb8a2355ed798ffc2169753013fd3" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3d/60/e56e8ec44ed34006e6d4a73c92a04d9eea6163cc12440e35045aec069175/onnx-1.18.0.tar.gz", hash = "sha256:3d8dbf9e996629131ba3aa1afd1d8239b660d1f830c6688dd7e03157cccd6b9c" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/2e/29/57053ba7787788ac75efb095cfc1ae290436b6d3a26754693cd7ed1b4fac/onnx-1.17.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:38b5df0eb22012198cdcee527cc5f917f09cce1f88a69248aaca22bd78a7f023" }, - { url = "https://mirrors.aliyun.com/pypi/packages/75/0d/831807a18db2a5e8f7813848c59272b904a4ef3939fe4d1288cbce9ea735/onnx-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d545335cb49d4d8c47cc803d3a805deb7ad5d9094dc67657d66e568610a36d7d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/dd/5b/c4f95dbe652d14aeba9afaceb177e9ffc48ac3c03048dd3f872f26f07e34/onnx-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3193a3672fc60f1a18c0f4c93ac81b761bc72fd8a6c2035fa79ff5969f07713e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/08/a9/c1f218085043dccc6311460239e253fa6957cf12ee4b0a56b82014938d0b/onnx-1.17.0-cp310-cp310-win32.whl", hash = "sha256:0141c2ce806c474b667b7e4499164227ef594584da432fd5613ec17c1855e311" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0e/d3/d26ebf590a65686dde6b27fef32493026c5be9e42083340d947395f93405/onnx-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:dfd777d95c158437fda6b34758f0877d15b89cbe9ff45affbedc519b35345cf9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e5/a9/8d1b1d53aec70df53e0f57e9f9fcf47004276539e29230c3d5f1f50719ba/onnx-1.17.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:d6fc3a03fc0129b8b6ac03f03bc894431ffd77c7d79ec023d0afd667b4d35869" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7b/e3/cc80110e5996ca61878f7b4c73c7a286cd88918ff35eacb60dc75ab11ef5/onnx-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01a4b63d4e1d8ec3e2f069e7b798b2955810aa434f7361f01bc8ca08d69cce4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b1/2f/91092557ed478e323a2b4471e2081fdf88d1dd52ae988ceaf7db4e4506ff/onnx-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a183c6178be001bf398260e5ac2c927dc43e7746e8638d6c05c20e321f8c949" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ac/59/9ea23fc22d0bb853133f363e6248e31bcbc6c1c90543a3938c00412ac02a/onnx-1.17.0-cp311-cp311-win32.whl", hash = "sha256:081ec43a8b950171767d99075b6b92553901fa429d4bc5eb3ad66b36ef5dbe3a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/51/a5/19b0dfcb567b62e7adf1a21b08b23224f0c2d13842aee4d0abc6f07f9cf5/onnx-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:95c03e38671785036bb704c30cd2e150825f6ab4763df3a4f1d249da48525957" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b4/dd/c416a11a28847fafb0db1bf43381979a0f522eb9107b831058fde012dd56/onnx-1.17.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:0e906e6a83437de05f8139ea7eaf366bf287f44ae5cc44b2850a30e296421f2f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f0/6c/f040652277f514ecd81b7251841f96caa5538365af7df07f86c6018cda2b/onnx-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d955ba2939878a520a97614bcf2e79c1df71b29203e8ced478fa78c9a9c63c2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3d/7c/67f4952d1b56b3f74a154b97d0dd0630d525923b354db117d04823b8b49b/onnx-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f3fb5cc4e2898ac5312a7dc03a65133dd2abf9a5e520e69afb880a7251ec97a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ae/20/6da11042d2ab870dfb4ce4a6b52354d7651b6b4112038b6d2229ab9904c4/onnx-1.17.0-cp312-cp312-win32.whl", hash = "sha256:317870fca3349d19325a4b7d1b5628f6de3811e9710b1e3665c68b073d0e68d7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/55/c4d11bee1fdb0c4bd84b4e3562ff811a19b63266816870ae1f95567aa6e1/onnx-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:659b8232d627a5460d74fd3c96947ae83db6d03f035ac633e20cd69cfa029227" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8e/e3/ab8a09c0af43373e0422de461956a1737581325260659aeffae22a7dad18/onnx-1.18.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:4a3b50d94620e2c7c1404d1d59bc53e665883ae3fecbd856cc86da0639fd0fc3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/04/5b/3cfd183961a0a872fe29c95f8d07264890ec65c75c94b99a4dabc950df29/onnx-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e189652dad6e70a0465035c55cc565c27aa38803dd4f4e74e4b952ee1c2de94b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/52/fa649429016c5790f68c614cdebfbefd3e72ba1c458966305297d540f713/onnx-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb1f271b1523b29f324bfd223f6a4cfbdc5a2f2f16e73563671932d33663365" }, + { url = "https://mirrors.aliyun.com/pypi/packages/42/52/dc166de41a5f72738b0bdfb2a19e0ebe4743cf3ecc9ae381ea3425bcb332/onnx-1.18.0-cp310-cp310-win32.whl", hash = "sha256:e03071041efd82e0317b3c45433b2f28146385b80f26f82039bc68048ac1a7a0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/f9/e766a3b85b7651ddfc5f9648e0e9dc24e88b7e88ea7f8c23187530e818ea/onnx-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:9235b3493951e11e75465d56f4cd97e3e9247f096160dd3466bfabe4cbc938bc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ed/3a/a336dac4db1eddba2bf577191e5b7d3e4c26fcee5ec518a5a5b11d13540d/onnx-1.18.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:735e06d8d0cf250dc498f54038831401063c655a8d6e5975b2527a4e7d24be3e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/02/3a/56475a111120d1e5d11939acbcbb17c92198c8e64a205cd68e00bdfd8a1f/onnx-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73160799472e1a86083f786fecdf864cf43d55325492a9b5a1cfa64d8a523ecc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cf/03/5eb5e9ef446ed9e78c4627faf3c1bc25e0f707116dd00e9811de232a8df5/onnx-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6acafb3823238bbe8f4340c7ac32fb218689442e074d797bee1c5c9a02fdae75" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/4e/70943125729ce453271a6e46bb847b4a612496f64db6cbc6cb1f49f41ce1/onnx-1.18.0-cp311-cp311-win32.whl", hash = "sha256:4c8c4bbda760c654e65eaffddb1a7de71ec02e60092d33f9000521f897c99be9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/44/b0/435fd764011911e8f599e3361f0f33425b1004662c1ea33a0ad22e43db2d/onnx-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5810194f0f6be2e58c8d6dedc6119510df7a14280dd07ed5f0f0a85bd74816a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6c/f0/9e31f4b4626d60f1c034f71b411810bc9fafe31f4e7dd3598effd1b50e05/onnx-1.18.0-cp311-cp311-win_arm64.whl", hash = "sha256:aa1b7483fac6cdec26922174fc4433f8f5c2f239b1133c5625063bb3b35957d0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a7/fe/16228aca685392a7114625b89aae98b2dc4058a47f0f467a376745efe8d0/onnx-1.18.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:521bac578448667cbb37c50bf05b53c301243ede8233029555239930996a625b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1e/77/ba50a903a9b5e6f9be0fa50f59eb2fca4a26ee653375408fbc72c3acbf9f/onnx-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4da451bf1c5ae381f32d430004a89f0405bc57a8471b0bddb6325a5b334aa40" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/23/25ec2ba723ac62b99e8fed6d7b59094dadb15e38d4c007331cc9ae3dfa5f/onnx-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99afac90b4cdb1471432203c3c1f74e16549c526df27056d39f41a9a47cfb4af" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/4d/2c253a36070fb43f340ff1d2c450df6a9ef50b938adcd105693fee43c4ee/onnx-1.18.0-cp312-cp312-win32.whl", hash = "sha256:ee159b41a3ae58d9c7341cf432fc74b96aaf50bd7bb1160029f657b40dc69715" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e8/92/048ba8fafe6b2b9a268ec2fb80def7e66c0b32ab2cae74de886981f05a27/onnx-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:102c04edc76b16e9dfeda5a64c1fccd7d3d2913b1544750c01d38f1ac3c04e05" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a1/66/bbc4ffedd44165dcc407a51ea4c592802a5391ce3dc94aa5045350f64635/onnx-1.18.0-cp312-cp312-win_arm64.whl", hash = "sha256:911b37d724a5d97396f3c2ef9ea25361c55cbc9aa18d75b12a52b620b67145af" }, ] [[package]] @@ -3594,12 +3765,12 @@ name = "onnxruntime-gpu" version = "1.19.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "coloredlogs", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "flatbuffers", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "numpy", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "packaging", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "protobuf", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "sympy", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "coloredlogs" }, + { name = "flatbuffers" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "protobuf" }, + { name = "sympy" }, ] wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/d0/9c/3fa310e0730643051eb88e884f19813a6c8b67d0fbafcda610d960e589db/onnxruntime_gpu-1.19.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a49740e079e7c5215830d30cde3df792e903df007aa0b0fd7aa797937061b27a" }, @@ -3716,50 +3887,167 @@ wheels = [ ] [[package]] -name = "orjson" -version = "3.10.15" +name = "opentelemetry-api" +version = "1.36.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ae/f9/5dea21763eeff8c1590076918a446ea3d6140743e0e36f58f369928ed0f4/orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/27/d2/c782c88b8afbf961d6972428821c302bd1e9e7bc361352172f0ca31296e2/opentelemetry_api-1.36.0.tar.gz", hash = "sha256:9a72572b9c416d004d492cbc6e61962c0501eaf945ece9b5a0f56597d8348aa0" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/52/09/e5ff18ad009e6f97eb7edc5f67ef98b3ce0c189da9c3eaca1f9587cd4c61/orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bd/b8/a75883301fe332bd433d9b0ded7d2bb706ccac679602c3516984f8814fb5/orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/83/4b/22f053e7a364cc9c685be203b1e40fc5f2b3f164a9b2284547504eec682e/orjson-3.10.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c2c79fa308e6edb0ffab0a31fd75a7841bf2a79a20ef08a3c6e3b26814c8ca8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/63/64/1b54fc75ca328b57dd810541a4035fe48c12a161d466e3cf5b11a8c25649/orjson-3.10.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cb85490aa6bf98abd20607ab5c8324c0acb48d6da7863a51be48505646c814" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5e/ff/ff0c5da781807bb0a5acd789d9a7fbcb57f7b0c6e1916595da1f5ce69f3c/orjson-3.10.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763dadac05e4e9d2bc14938a45a2d0560549561287d41c465d3c58aec818b164" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4e/9a/11e2974383384ace8495810d4a2ebef5f55aacfc97b333b65e789c9d362d/orjson-3.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a330b9b4734f09a623f74a7490db713695e13b67c959713b78369f26b3dee6bf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2d/c4/dd9583aea6aefee1b64d3aed13f51d2aadb014028bc929fe52936ec5091f/orjson-3.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a61a4622b7ff861f019974f73d8165be1bd9a0855e1cad18ee167acacabeb061" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/3e/dcf1729230654f5c5594fc752de1f43dcf67e055ac0d300c8cdb1309269a/orjson-3.10.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd271247691574416b3228db667b84775c497b245fa275c6ab90dc1ffbbd2b3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e8/2b/b9759fe704789937705c8a56a03f6c03e50dff7df87d65cba9a20fec5282/orjson-3.10.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4759b109c37f635aa5c5cc93a1b26927bfde24b254bcc0e1149a9fada253d2d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a7/6b/b9dfdbd4b6e20a59238319eb203ae07c3f6abf07eef909169b7a37ae3bba/orjson-3.10.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e992fd5cfb8b9f00bfad2fd7a05a4299db2bbe92e6440d9dd2fab27655b3182" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/b5/40f5bbea619c7caf75eb4d652a9821875a8ed04acc45fe3d3ef054ca69fb/orjson-3.10.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95fb363d79366af56c3f26b71df40b9a583b07bbaaf5b317407c4d58497852e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/38/60/2272514061cbdf4d672edbca6e59c7e01cd1c706e881427d88f3c3e79761/orjson-3.10.15-cp310-cp310-win32.whl", hash = "sha256:f9875f5fea7492da8ec2444839dcc439b0ef298978f311103d0b7dfd775898ab" }, - { url = "https://mirrors.aliyun.com/pypi/packages/11/5d/be1490ff7eafe7fef890eb4527cf5bcd8cfd6117f3efe42a3249ec847b60/orjson-3.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:17085a6aa91e1cd70ca8533989a18b5433e15d29c574582f76f821737c8d5806" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7a/a2/21b25ce4a2c71dbb90948ee81bd7a42b4fbfc63162e57faf83157d5540ae/orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b2/85/2076fc12d8225698a51278009726750c9c65c846eda741e77e1761cfef33/orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef" }, - { url = "https://mirrors.aliyun.com/pypi/packages/06/df/a85a7955f11274191eccf559e8481b2be74a7c6d43075d0a9506aa80284d/orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/b3/94c55625a29b8767c0eed194cb000b3787e3c23b4cdd13be17bae6ccbb4b/orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/ba/c608b1e719971e8ddac2379f290404c2e914cf8e976369bae3cad88768b1/orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b2/c4/c1fb835bb23ad788a39aa9ebb8821d51b1c03588d9a9e4ca7de5b354fdd5/orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/14/bb2b48b26ab3c570b284eb2157d98c1ef331a8397f6c8bd983b270467f5c/orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4a/97/d5b353a5fe532e92c46467aa37e637f81af8468aa894cd77d2ec8a12f99e/orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b5/5d/a067bec55293cca48fea8b9928cfa84c623be0cce8141d47690e64a6ca12/orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/9a/1485b8b05c6b4c4db172c438cf5db5dcfd10e72a9bc23c151a1137e763e0/orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f8/d2/fc67523656e43a0c7eaeae9007c8b02e86076b15d591e9be11554d3d3138/orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/79/42/f58c7bd4e5b54da2ce2ef0331a39ccbbaa7699b7f70206fbf06737c9ed7d/orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/00/f8/bb60a4644287a544ec81df1699d5b965776bc9848d9029d9f9b3402ac8bb/orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/66/85/22fe737188905a71afcc4bf7cc4c79cd7f5bbe9ed1fe0aac4ce4c33edc30/orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/48/b7/2622b29f3afebe938a0a9037e184660379797d5fd5234e5998345d7a5b43/orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ce/8f/0b72a48f4403d0b88b2a41450c535b3e8989e8a2d7800659a967efc7c115/orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/06/ec/acb1a20cd49edb2000be5a0404cd43e3c8aad219f376ac8c60b870518c03/orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/33/e1/f7840a2ea852114b23a52a1c0b2bea0a1ea22236efbcdb876402d799c423/orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fa/da/31543337febd043b8fa80a3b67de627669b88c7b128d9ad4cc2ece005b7a/orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ed/78/66115dc9afbc22496530d2139f2f4455698be444c7c2475cb48f657cefc9/orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514" }, - { url = "https://mirrors.aliyun.com/pypi/packages/22/84/cd4f5fb5427ffcf823140957a47503076184cb1ce15bcc1165125c26c46c/orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17" }, - { url = "https://mirrors.aliyun.com/pypi/packages/93/1f/67596b711ba9f56dd75d73b60089c5c92057f1130bb3a25a0f53fb9a583b/orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7c/0c/6a3b3271b46443d90efb713c3e4fe83fa8cd71cda0d11a0f69a03f437c6e/orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3b/9b/33c58e0bfc788995eccd0d525ecd6b84b40d7ed182dd0751cd4c1322ac62/orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/c1/d577ecd2e9fa393366a1ea0a9267f6510d86e6c4bb1cdfb9877104cac44c/orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ed/eb/a85317ee1732d1034b92d56f89f1de4d7bf7904f5c8fb9dcdd5b1c83917f/orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bb/ee/6b08dde0a022c463b88f55ae81149584b125a42183407dc1045c486cc870/opentelemetry_api-1.36.0-py3-none-any.whl", hash = "sha256:02f20bcacf666e1333b6b1f04e647dc1d5111f86b8e510238fcc56d7762cda8c" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp" +version = "1.36.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "opentelemetry-exporter-otlp-proto-grpc" }, + { name = "opentelemetry-exporter-otlp-proto-http" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/95/7f/d31294ac28d567a14aefd855756bab79fed69c5a75df712f228f10c47e04/opentelemetry_exporter_otlp-1.36.0.tar.gz", hash = "sha256:72f166ea5a8923ac42889337f903e93af57db8893de200369b07401e98e4e06b" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/a0/a2/8966111a285124f3d6156a663ddf2aeddd52843c1a3d6b56cbd9b6c3fd0e/opentelemetry_exporter_otlp-1.36.0-py3-none-any.whl", hash = "sha256:de93b7c45bcc78296998775d52add7c63729e83ef2cd6560730a6b336d7f6494" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.36.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/34/da/7747e57eb341c59886052d733072bc878424bf20f1d8cf203d508bbece5b/opentelemetry_exporter_otlp_proto_common-1.36.0.tar.gz", hash = "sha256:6c496ccbcbe26b04653cecadd92f73659b814c6e3579af157d8716e5f9f25cbf" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/d0/ed/22290dca7db78eb32e0101738366b5bbda00d0407f00feffb9bf8c3fdf87/opentelemetry_exporter_otlp_proto_common-1.36.0-py3-none-any.whl", hash = "sha256:0fc002a6ed63eac235ada9aa7056e5492e9a71728214a61745f6ad04b923f840" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.36.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/72/6f/6c1b0bdd0446e5532294d1d41bf11fbaea39c8a2423a4cdfe4fe6b708127/opentelemetry_exporter_otlp_proto_grpc-1.36.0.tar.gz", hash = "sha256:b281afbf7036b325b3588b5b6c8bb175069e3978d1bd24071f4a59d04c1e5bbf" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/0c/67/5f6bd188d66d0fd8e81e681bbf5822e53eb150034e2611dd2b935d3ab61a/opentelemetry_exporter_otlp_proto_grpc-1.36.0-py3-none-any.whl", hash = "sha256:734e841fc6a5d6f30e7be4d8053adb703c70ca80c562ae24e8083a28fadef211" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.36.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/25/85/6632e7e5700ba1ce5b8a065315f92c1e6d787ccc4fb2bdab15139eaefc82/opentelemetry_exporter_otlp_proto_http-1.36.0.tar.gz", hash = "sha256:dd3637f72f774b9fc9608ab1ac479f8b44d09b6fb5b2f3df68a24ad1da7d356e" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/7f/41/a680d38b34f8f5ddbd78ed9f0042e1cc712d58ec7531924d71cb1e6c629d/opentelemetry_exporter_otlp_proto_http-1.36.0-py3-none-any.whl", hash = "sha256:3d769f68e2267e7abe4527f70deb6f598f40be3ea34c6adc35789bea94a32902" }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.36.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fd/02/f6556142301d136e3b7e95ab8ea6a5d9dc28d879a99f3dd673b5f97dca06/opentelemetry_proto-1.36.0.tar.gz", hash = "sha256:0f10b3c72f74c91e0764a5ec88fd8f1c368ea5d9c64639fb455e2854ef87dd2f" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b3/57/3361e06136225be8180e879199caea520f38026f8071366241ac458beb8d/opentelemetry_proto-1.36.0-py3-none-any.whl", hash = "sha256:151b3bf73a09f94afc658497cf77d45a565606f62ce0c17acb08cd9937ca206e" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.36.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/4c/85/8567a966b85a2d3f971c4d42f781c305b2b91c043724fa08fd37d158e9dc/opentelemetry_sdk-1.36.0.tar.gz", hash = "sha256:19c8c81599f51b71670661ff7495c905d8fdf6976e41622d5245b791b06fa581" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/0b/59/7bed362ad1137ba5886dac8439e84cd2df6d087be7c09574ece47ae9b22c/opentelemetry_sdk-1.36.0-py3-none-any.whl", hash = "sha256:19fe048b42e98c5c1ffe85b569b7073576ad4ce0bcb6e9b4c6a39e890a6c45fb" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.57b0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7e/31/67dfa252ee88476a29200b0255bda8dfc2cf07b56ad66dc9a6221f7dc787/opentelemetry_semantic_conventions-0.57b0.tar.gz", hash = "sha256:609a4a79c7891b4620d64c7aac6898f872d790d75f22019913a660756f27ff32" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/05/75/7d591371c6c39c73de5ce5da5a2cc7b72d1d1cd3f8f4638f553c01c37b11/opentelemetry_semantic_conventions-0.57b0-py3-none-any.whl", hash = "sha256:757f7e76293294f124c827e514c2a3144f191ef175b069ce8d1211e1e38e9e78" }, +] + +[[package]] +name = "orjson" +version = "3.10.18" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/81/0b/fea456a3ffe74e70ba30e01ec183a9b26bec4d497f61dcfce1b601059c60/orjson-3.10.18.tar.gz", hash = "sha256:e8da3947d92123eda795b68228cafe2724815621fe35e8e320a9e9593a4bcd53" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/27/16/2ceb9fb7bc2b11b1e4a3ea27794256e93dee2309ebe297fd131a778cd150/orjson-3.10.18-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a45e5d68066b408e4bc383b6e4ef05e717c65219a9e1390abc6155a520cac402" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/e1/d3c0a2bba5b9906badd121da449295062b289236c39c3a7801f92c4682b0/orjson-3.10.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be3b9b143e8b9db05368b13b04c84d37544ec85bb97237b3a923f076265ec89c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/51/698dd65e94f153ee5ecb2586c89702c9e9d12f165a63e74eb9ea1299f4e1/orjson-3.10.18-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b0aa09745e2c9b3bf779b096fa71d1cc2d801a604ef6dd79c8b1bfef52b2f92" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b3/e5/155ce5a2c43a85e790fcf8b985400138ce5369f24ee6770378ee6b691036/orjson-3.10.18-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53a245c104d2792e65c8d225158f2b8262749ffe64bc7755b00024757d957a13" }, + { url = "https://mirrors.aliyun.com/pypi/packages/46/bb/6141ec3beac3125c0b07375aee01b5124989907d61c72c7636136e4bd03e/orjson-3.10.18-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9495ab2611b7f8a0a8a505bcb0f0cbdb5469caafe17b0e404c3c746f9900469" }, + { url = "https://mirrors.aliyun.com/pypi/packages/77/36/6961eca0b66b7809d33c4ca58c6bd4c23a1b914fb23aba2fa2883f791434/orjson-3.10.18-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73be1cbcebadeabdbc468f82b087df435843c809cd079a565fb16f0f3b23238f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8b/2f/0c646d5fd689d3be94f4d83fa9435a6c4322c9b8533edbb3cd4bc8c5f69a/orjson-3.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8936ee2679e38903df158037a2f1c108129dee218975122e37847fb1d4ac68" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ea/af/65907b40c74ef4c3674ef2bcfa311c695eb934710459841b3c2da212215c/orjson-3.10.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7115fcbc8525c74e4c2b608129bef740198e9a120ae46184dac7683191042056" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c7/d1/68bd20ac6a32cd1f1b10d23e7cc58ee1e730e80624e3031d77067d7150fc/orjson-3.10.18-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:771474ad34c66bc4d1c01f645f150048030694ea5b2709b87d3bda273ffe505d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/31/31/c701ec0bcc3e80e5cb6e319c628ef7b768aaa24b0f3b4c599df2eaacfa24/orjson-3.10.18-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7c14047dbbea52886dd87169f21939af5d55143dad22d10db6a7514f058156a8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/31/5e1aa99a10893a43cfc58009f9da840990cc8a9ebb75aa452210ba18587e/orjson-3.10.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:641481b73baec8db14fdf58f8967e52dc8bda1f2aba3aa5f5c1b07ed6df50b7f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/8c/daba0ac1b8690011d9242a0f37235f7d17df6d0ad941021048523b76674e/orjson-3.10.18-cp310-cp310-win32.whl", hash = "sha256:607eb3ae0909d47280c1fc657c4284c34b785bae371d007595633f4b1a2bbe06" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/62/8b687724143286b63e1d0fab3ad4214d54566d80b0ba9d67c26aaf28a2f8/orjson-3.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:8770432524ce0eca50b7efc2a9a5f486ee0113a5fbb4231526d414e6254eba92" }, + { url = "https://mirrors.aliyun.com/pypi/packages/97/c7/c54a948ce9a4278794f669a353551ce7db4ffb656c69a6e1f2264d563e50/orjson-3.10.18-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e0a183ac3b8e40471e8d843105da6fbe7c070faab023be3b08188ee3f85719b8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/60/a9c674ef1dd8ab22b5b10f9300e7e70444d4e3cda4b8258d6c2488c32143/orjson-3.10.18-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:5ef7c164d9174362f85238d0cd4afdeeb89d9e523e4651add6a5d458d6f7d42d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c1/4e/f7d1bdd983082216e414e6d7ef897b0c2957f99c545826c06f371d52337e/orjson-3.10.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd14c5d99cdc7bf93f22b12ec3b294931518aa019e2a147e8aa2f31fd3240f7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/89/46b9181ba0ea251c9243b0c8ce29ff7c9796fa943806a9c8b02592fce8ea/orjson-3.10.18-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b672502323b6cd133c4af6b79e3bea36bad2d16bca6c1f645903fce83909a7a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ca/dd/7bce6fcc5b8c21aef59ba3c67f2166f0a1a9b0317dcca4a9d5bd7934ecfd/orjson-3.10.18-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51f8c63be6e070ec894c629186b1c0fe798662b8687f3d9fdfa5e401c6bd7679" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/4a/b8aea1c83af805dcd31c1f03c95aabb3e19a016b2a4645dd822c5686e94d/orjson-3.10.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9478ade5313d724e0495d167083c6f3be0dd2f1c9c8a38db9a9e912cdaf947" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/d6/7eb05c85d987b688707f45dcf83c91abc2251e0dd9fb4f7be96514f838b1/orjson-3.10.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:187aefa562300a9d382b4b4eb9694806e5848b0cedf52037bb5c228c61bb66d4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/78/ddd3ee7873f2b5f90f016bc04062713d567435c53ecc8783aab3a4d34915/orjson-3.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da552683bc9da222379c7a01779bddd0ad39dd699dd6300abaf43eadee38334" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8c/09/c8e047f73d2c5d21ead9c180203e111cddeffc0848d5f0f974e346e21c8e/orjson-3.10.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e450885f7b47a0231979d9c49b567ed1c4e9f69240804621be87c40bc9d3cf17" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0c/4b/dccbf5055ef8fb6eda542ab271955fc1f9bf0b941a058490293f8811122b/orjson-3.10.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5e3c9cc2ba324187cd06287ca24f65528f16dfc80add48dc99fa6c836bb3137e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/f3/1eac0c5e2d6d6790bd2025ebfbefcbd37f0d097103d76f9b3f9302af5a17/orjson-3.10.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50ce016233ac4bfd843ac5471e232b865271d7d9d44cf9d33773bcd883ce442b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/b4/ef0abf64c8f1fabf98791819ab502c2c8c1dc48b786646533a93637d8999/orjson-3.10.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3ceff74a8f7ffde0b2785ca749fc4e80e4315c0fd887561144059fb1c138aa7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/a3/6ea878e7b4a0dc5c888d0370d7752dcb23f402747d10e2257478d69b5e63/orjson-3.10.18-cp311-cp311-win32.whl", hash = "sha256:fdba703c722bd868c04702cac4cb8c6b8ff137af2623bc0ddb3b3e6a2c8996c1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/2a/4048700a3233d562f0e90d5572a849baa18ae4e5ce4c3ba6247e4ece57b0/orjson-3.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:c28082933c71ff4bc6ccc82a454a2bffcef6e1d7379756ca567c772e4fb3278a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/45/10d934535a4993d27e1c84f1810e79ccf8b1b7418cef12151a22fe9bb1e1/orjson-3.10.18-cp311-cp311-win_arm64.whl", hash = "sha256:a6c7c391beaedd3fa63206e5c2b7b554196f14debf1ec9deb54b5d279b1b46f5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/21/1a/67236da0916c1a192d5f4ccbe10ec495367a726996ceb7614eaa687112f2/orjson-3.10.18-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:50c15557afb7f6d63bc6d6348e0337a880a04eaa9cd7c9d569bcb4e760a24753" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b3/bc/c7f1db3b1d094dc0c6c83ed16b161a16c214aaa77f311118a93f647b32dc/orjson-3.10.18-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:356b076f1662c9813d5fa56db7d63ccceef4c271b1fb3dd522aca291375fcf17" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/84/664657cd14cc11f0d81e80e64766c7ba5c9b7fc1ec304117878cc1b4659c/orjson-3.10.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:559eb40a70a7494cd5beab2d73657262a74a2c59aff2068fdba8f0424ec5b39d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9a/bb/f50039c5bb05a7ab024ed43ba25d0319e8722a0ac3babb0807e543349978/orjson-3.10.18-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3c29eb9a81e2fbc6fd7ddcfba3e101ba92eaff455b8d602bf7511088bbc0eae" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/8c/ee74709fc072c3ee219784173ddfe46f699598a1723d9d49cbc78d66df65/orjson-3.10.18-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6612787e5b0756a171c7d81ba245ef63a3533a637c335aa7fcb8e665f4a0966f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/37/e6d3109ee004296c80426b5a62b47bcadd96a3deab7443e56507823588c5/orjson-3.10.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ac6bd7be0dcab5b702c9d43d25e70eb456dfd2e119d512447468f6405b4a69c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/5d/387dafae0e4691857c62bd02839a3bf3fa648eebd26185adfac58d09f207/orjson-3.10.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f72f100cee8dde70100406d5c1abba515a7df926d4ed81e20a9730c062fe9ad" }, + { url = "https://mirrors.aliyun.com/pypi/packages/27/6f/875e8e282105350b9a5341c0222a13419758545ae32ad6e0fcf5f64d76aa/orjson-3.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca85398d6d093dd41dc0983cbf54ab8e6afd1c547b6b8a311643917fbf4e0c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/b2/73a1f0b4790dcb1e5a45f058f4f5dcadc8a85d90137b50d6bbc6afd0ae50/orjson-3.10.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22748de2a07fcc8781a70edb887abf801bb6142e6236123ff93d12d92db3d406" }, + { url = "https://mirrors.aliyun.com/pypi/packages/56/f5/7ed133a5525add9c14dbdf17d011dd82206ca6840811d32ac52a35935d19/orjson-3.10.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:3a83c9954a4107b9acd10291b7f12a6b29e35e8d43a414799906ea10e75438e6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/7c/439654221ed9c3324bbac7bdf94cf06a971206b7b62327f11a52544e4982/orjson-3.10.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:303565c67a6c7b1f194c94632a4a39918e067bd6176a48bec697393865ce4f06" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/e7/d58074fa0cc9dd29a8fa2a6c8d5deebdfd82c6cfef72b0e4277c4017563a/orjson-3.10.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:86314fdb5053a2f5a5d881f03fca0219bfdf832912aa88d18676a5175c6916b5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/4d/fe17581cf81fb70dfcef44e966aa4003360e4194d15a3f38cbffe873333a/orjson-3.10.18-cp312-cp312-win32.whl", hash = "sha256:187ec33bbec58c76dbd4066340067d9ece6e10067bb0cc074a21ae3300caa84e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/22/469f62d25ab5f0f3aee256ea732e72dc3aab6d73bac777bd6277955bceef/orjson-3.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:f9f94cf6d3f9cd720d641f8399e390e7411487e493962213390d1ae45c7814fc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/10/b0/1040c447fac5b91bc1e9c004b69ee50abb0c1ffd0d24406e1350c58a7fcb/orjson-3.10.18-cp312-cp312-win_arm64.whl", hash = "sha256:3d600be83fe4514944500fa8c2a0a77099025ec6482e8087d7659e891f23058a" }, ] [[package]] @@ -3945,11 +4233,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.3.7" +version = "4.3.8" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4" }, ] [[package]] @@ -3984,11 +4272,11 @@ wheels = [ [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" }, ] [[package]] @@ -4065,18 +4353,18 @@ wheels = [ [[package]] name = "primp" -version = "0.14.0" +version = "0.15.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/95/1e/a063129aed2320b463fd35c5d918d5754e59011698aaf7cf297a610b3380/primp-0.14.0.tar.gz", hash = "sha256:b6f23b2b694118a9d0443b3760698b90afb6f867f8447e71972530f48297992e" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/56/0b/a87556189da4de1fc6360ca1aa05e8335509633f836cdd06dd17f0743300/primp-0.15.0.tar.gz", hash = "sha256:1af8ea4b15f57571ff7fc5e282a82c5eb69bc695e19b8ddeeda324397965b30a" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7f/12/eba13ddbeb5c6df6cf7511aedb5fa4bcb99c0754e88056260dd44aa53929/primp-0.14.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd2dfb57feeba21a77a1128b6c6f17856605c4e73edcc05764fb134de4ff014f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/77/65/3cd25b4f4d0cd9de4f1d95858dcddd7ed082587524294c179c847de18951/primp-0.14.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:31eecb5316f9bd732a7994530b85eb698bf6500d2f6c5c3382dac0353f77084e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/13/77/f85bc3e31befa9b9bac54bab61beb34ff84a70d20f02b7dcd8abc120120a/primp-0.14.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11229e65aa5755fdfb535cc03fd64259a06764ad7c22e650fb3bea51400f1d09" }, - { url = "https://mirrors.aliyun.com/pypi/packages/44/36/bc95049264ee668a5cdaadf77ef711aaa9cb0c4c0a246b27bba9a2f0114c/primp-0.14.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8f56ca2cd63f9ac75b33bf48129b7e79ade29cf280bc253b17b052afb27d2b9e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/d9/632a70c80dcdd0bb9293cdc7e7543d35e5912325631c3e9f3b7c7d842941/primp-0.14.0-cp38-abi3-manylinux_2_34_armv7l.whl", hash = "sha256:3fb204f67a4b58dc53f3452143121317b474437812662ac0149d332a77ecbe1a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/dc/ba/07b04b9d404f20ec78449c5974c988a5adf7d4d245a605466486f70d35c3/primp-0.14.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b0b21e6a599f580137774623009c7f895afab49d6c3d6c9a28344fd2586ebe8a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d7/d3/3bee499b4594fce1f8ccede785e517162407fbea1d452c4fb55fe3fb5e81/primp-0.14.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6549766ece3c7be19e1c16fa9029d3e50fa73628149d88601fcd964af8b44a8d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6a/20/042c8ae21d185f2efe61780dfbc01464c982f59626b746d5436c2e4c1e08/primp-0.14.0-cp38-abi3-win_amd64.whl", hash = "sha256:d3ae1ba954ec8d07abb527ccce7bb36633525c86496950ba0178e44a0ea5c891" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/5a/146ac964b99ea7657ad67eb66f770be6577dfe9200cb28f9a95baffd6c3f/primp-0.15.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:1b281f4ca41a0c6612d4c6e68b96e28acfe786d226a427cd944baa8d7acd644f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/8a/cc2321e32db3ce64d6e32950d5bcbea01861db97bfb20b5394affc45b387/primp-0.15.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:489cbab55cd793ceb8f90bb7423c6ea64ebb53208ffcf7a044138e3c66d77299" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c3/7b/cbd5d999a07ff2a21465975d4eb477ae6f69765e8fe8c9087dab250180d8/primp-0.15.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c18b45c23f94016215f62d2334552224236217aaeb716871ce0e4dcfa08eb161" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/6e/a6221c612e61303aec2bcac3f0a02e8b67aee8c0db7bdc174aeb8010f975/primp-0.15.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e985a9cba2e3f96a323722e5440aa9eccaac3178e74b884778e926b5249df080" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3b/54/bfeef5aca613dc660a69d0760a26c6b8747d8fdb5a7f20cb2cee53c9862f/primp-0.15.0-cp38-abi3-manylinux_2_34_armv7l.whl", hash = "sha256:6b84a6ffa083e34668ff0037221d399c24d939b5629cd38223af860de9e17a83" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ac/96/84078e09f16a1dad208f2fe0f8a81be2cf36e024675b0f9eec0c2f6e2182/primp-0.15.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:592f6079646bdf5abbbfc3b0a28dac8de943f8907a250ce09398cda5eaebd260" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6c/80/8a7a9587d3eb85be3d0b64319f2f690c90eb7953e3f73a9ddd9e46c8dc42/primp-0.15.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5a728e5a05f37db6189eb413d22c78bd143fa59dd6a8a26dacd43332b3971fe8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0c/dd/f0183ed0145e58cf9d286c1b2c14f63ccee987a4ff79ac85acc31b5d86bd/primp-0.15.0-cp38-abi3-win_amd64.whl", hash = "sha256:aeb6bd20b06dfc92cfe4436939c18de88a58c640752cf7f30d9e4ae893cdec32" }, ] [[package]] @@ -4090,71 +4378,71 @@ wheels = [ [[package]] name = "prompt-toolkit" -version = "3.0.50" +version = "3.0.51" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a1/e1/bd15cb8ffdcfeeb2bdc215de3c3cffca11408d829e4b8416dcfe71ba8854/prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/e4/ea/d836f008d33151c7a1f62caf3d8dd782e4d15f6a43897f64480c2b8de2ad/prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07" }, ] [[package]] name = "propcache" -version = "0.3.0" +version = "0.3.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/92/76/f941e63d55c0293ff7829dd21e7cf1147e90a526756869a9070f287a68c9/propcache-0.3.0.tar.gz", hash = "sha256:a8fd93de4e1d278046345f49e2238cdb298589325849b2645d4a94c53faeffc5" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/8d/f0/dc9ec44d2e63c13f816a16398c039329736712440ff82b682dd9a78d2258/propcache-0.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:efa44f64c37cc30c9f05932c740a8b40ce359f51882c70883cc95feac842da4d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/3a/33a207dfcb3ee1131ea23a2aeb726c3c4994f89546d7eadf8c50627c8b63/propcache-0.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2383a17385d9800b6eb5855c2f05ee550f803878f344f58b6e194de08b96352c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/af/68/0bde765c9f5dc02b4466d2838600af38c81b184c26c6d3cd44643ac668e3/propcache-0.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3e7420211f5a65a54675fd860ea04173cde60a7cc20ccfbafcccd155225f8bc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/06/a6/c682669bae41199358e16cc7b1c818f91c5f9e925cc863dabd98ce32716a/propcache-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3302c5287e504d23bb0e64d2a921d1eb4a03fb93a0a0aa3b53de059f5a5d737d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fb/ae/82cfb50267d9a1baa0340728eb9e32245a68538fef929d7bb786d01c11a8/propcache-0.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e2e068a83552ddf7a39a99488bcba05ac13454fb205c847674da0352602082f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ab/16/7b6b2bf8c207cfd0e5ca3d41aea397392de9899867ec024f88c94f9ae2ab/propcache-0.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d913d36bdaf368637b4f88d554fb9cb9d53d6920b9c5563846555938d5450bf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f4/eb/41447de61eb5454891658d0fb9b1d7d35d49a4a5dd2e0c86f2c332e8b7e1/propcache-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ee1983728964d6070ab443399c476de93d5d741f71e8f6e7880a065f878e0b9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/03/b6/9719878f8b5b20d37ee663a40f8dcbf888559e4d3be2ba2fe5c790fc28d2/propcache-0.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36ca5e9a21822cc1746023e88f5c0af6fce3af3b85d4520efb1ce4221bed75cc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bb/ec/b79c3210ba459800d1a8f1afeb81d7b503893555a7b79c24082ff26d3314/propcache-0.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9ecde3671e62eeb99e977f5221abcf40c208f69b5eb986b061ccec317c82ebd0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/48/f6/2b0140bc47013e43575973068e72ad51ee9f22f2dad42e6d6e362d715125/propcache-0.3.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d383bf5e045d7f9d239b38e6acadd7b7fdf6c0087259a84ae3475d18e9a2ae8b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/97/3d/2fa19303d87aa21f9a42dcd870d6088a2a776ff5518e394d50412c3679a6/propcache-0.3.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8cb625bcb5add899cb8ba7bf716ec1d3e8f7cdea9b0713fa99eadf73b6d4986f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/09/f3/a2170ffc9fa774c1dfd52294113c0fa6cdc5b71dbfd7129bb9378fdd8b42/propcache-0.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5fa159dcee5dba00c1def3231c249cf261185189205073bde13797e57dd7540a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d6/1e/cb8a6c82178efffa0b00dc463f36cd086f747345585140aeb95d5cb93666/propcache-0.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a7080b0159ce05f179cfac592cda1a82898ca9cd097dacf8ea20ae33474fbb25" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2b/72/6e273543337a3e22cf462eb836f065a9830b4d41baeb1f58db2695c934f3/propcache-0.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed7161bccab7696a473fe7ddb619c1d75963732b37da4618ba12e60899fefe4f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f3/ea/7412c79bcec06597c967d49789f5a1f7fd76a8654908feeaefafb7447c9a/propcache-0.3.0-cp310-cp310-win32.whl", hash = "sha256:bf0d9a171908f32d54f651648c7290397b8792f4303821c42a74e7805bfb813c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a3/42/488c90190491f3e61bd2c2fb0b3d91c1c78778270dde2f0b6633fc9ff723/propcache-0.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:42924dc0c9d73e49908e35bbdec87adedd651ea24c53c29cac103ede0ea1d340" }, - { url = "https://mirrors.aliyun.com/pypi/packages/45/c9/cf09ff7e6d09f14149094f7cd50d2dec032b24e61af21fc4540da2b17bfb/propcache-0.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9ddd49258610499aab83b4f5b61b32e11fce873586282a0e972e5ab3bcadee51" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/32/2424d89da88cd81b7d148e0d2b3131461b570a02aa9d84a2e567509adb0d/propcache-0.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2578541776769b500bada3f8a4eeaf944530516b6e90c089aa368266ed70c49e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f6/91/ee5b6aa7aa31754fefcf0c5180e09223cac380ef195c4ddc8c266eb641ea/propcache-0.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8074c5dd61c8a3e915fa8fc04754fa55cfa5978200d2daa1e2d4294c1f136aa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/73/38f0128462b8b616181d8c53bd5d04eac41c50c449b07615c65d56ba0a9b/propcache-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b58229a844931bca61b3a20efd2be2a2acb4ad1622fc026504309a6883686fbf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/59/82/f3d4e84f4539dcfc9c3d338282b9e915f5b63c921986ecfdf7af2d12f87c/propcache-0.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e45377d5d6fefe1677da2a2c07b024a6dac782088e37c0b1efea4cfe2b1be19b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/42/e8/029f58cccbae83c9969a7ee7a06558d5b83a93dfc54e0f4f70234bbaea1b/propcache-0.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ec5060592d83454e8063e487696ac3783cc48c9a329498bafae0d972bc7816c9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8b/a2/c373561777c0cb9b9e7b9b9a10b9b3a7b6bde75a2535b962231cecc8fdb8/propcache-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15010f29fbed80e711db272909a074dc79858c6d28e2915704cfc487a8ac89c6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d7/d2/4673f715beedf6038b485bcd976813149231d9df5bb6196cb69a09c185c9/propcache-0.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a254537b9b696ede293bfdbc0a65200e8e4507bc9f37831e2a0318a9b333c85c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e0/f6/1da65f900927bafd4675a16e890618ec7643f2f922bf0e4d84bb38645618/propcache-0.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2b975528998de037dfbc10144b8aed9b8dd5a99ec547f14d1cb7c5665a43f075" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ff/86/620451bdc02e91b1712cd71890c17077ee97e2a28493836a87e47b8e70ff/propcache-0.3.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:19d36bb351ad5554ff20f2ae75f88ce205b0748c38b146c75628577020351e3c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6e/1b/e8f86921ed4016da80faf3b8f515f7829decabdbff106736bfff353bceba/propcache-0.3.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6032231d4a5abd67c7f71168fd64a47b6b451fbcb91c8397c2f7610e67683810" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1a/95/a61d86cc49aa0945f6c06f3a4614fc543e311a50558c92861f5e9691a37c/propcache-0.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6985a593417cdbc94c7f9c3403747335e450c1599da1647a5af76539672464d3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8f/7d/10dbae48ff2bb189e92c2b3487a48f3229146a25941ad0d485934d1104d4/propcache-0.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6a1948df1bb1d56b5e7b0553c0fa04fd0e320997ae99689488201f19fa90d2e7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/39/ce/82d16aec96c5513ae7db13ab901a65a1e54c915292fb5b2390e33275b61d/propcache-0.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8319293e85feadbbfe2150a5659dbc2ebc4afdeaf7d98936fb9a2f2ba0d4c35c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/e0/cb077e8e7a583c733df7f53327fcbdb92e42be59b976ce60bf1d904a0efe/propcache-0.3.0-cp311-cp311-win32.whl", hash = "sha256:63f26258a163c34542c24808f03d734b338da66ba91f410a703e505c8485791d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d8/35/57abeb6146fe3c19081eeaf3d9d4cfea256f87f1e5101acf80d3332c1820/propcache-0.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:cacea77ef7a2195f04f9279297684955e3d1ae4241092ff0cfcef532bb7a1c32" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8d/2c/921f15dc365796ec23975b322b0078eae72995c7b4d49eba554c6a308d70/propcache-0.3.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e53d19c2bf7d0d1e6998a7e693c7e87300dd971808e6618964621ccd0e01fe4e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/11/a5/4a6cc1a559d1f2fb57ea22edc4245158cdffae92f7f92afcee2913f84417/propcache-0.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a61a68d630e812b67b5bf097ab84e2cd79b48c792857dc10ba8a223f5b06a2af" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e1/6d/28bfd3af3a567ad7d667348e7f46a520bda958229c4d545ba138a044232f/propcache-0.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb91d20fa2d3b13deea98a690534697742029f4fb83673a3501ae6e3746508b5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/73/20/d75b42eaffe5075eac2f4e168f6393d21c664c91225288811d85451b2578/propcache-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67054e47c01b7b349b94ed0840ccae075449503cf1fdd0a1fdd98ab5ddc2667b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a5/fb/4b537dd92f9fd4be68042ec51c9d23885ca5fafe51ec24c58d9401034e5f/propcache-0.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:997e7b8f173a391987df40f3b52c423e5850be6f6df0dcfb5376365440b56667" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e7/af/8a9db04ac596d531ca0ef7dde518feaadfcdabef7b17d6a5ec59ee3effc2/propcache-0.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d663fd71491dde7dfdfc899d13a067a94198e90695b4321084c6e450743b8c7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9d/c4/ecfc988879c0fd9db03228725b662d76cf484b6b46f7e92fee94e4b52490/propcache-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8884ba1a0fe7210b775106b25850f5e5a9dc3c840d1ae9924ee6ea2eb3acbfe7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/04/a2/298dd27184faa8b7d91cc43488b578db218b3cc85b54d912ed27b8c5597a/propcache-0.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa806bbc13eac1ab6291ed21ecd2dd426063ca5417dd507e6be58de20e58dfcf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/be/0d/efe7fec316ca92dbf4bc4a9ba49ca889c43ca6d48ab1d6fa99fc94e5bb98/propcache-0.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f4d7a7c0aff92e8354cceca6fe223973ddf08401047920df0fcb24be2bd5138" }, - { url = "https://mirrors.aliyun.com/pypi/packages/60/63/72404380ae1d9c96d96e165aa02c66c2aae6072d067fc4713da5cde96762/propcache-0.3.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9be90eebc9842a93ef8335291f57b3b7488ac24f70df96a6034a13cb58e6ff86" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9d/18/b8392cab6e0964b67a30a8f4dadeaff64dc7022b5a34bb1d004ea99646f4/propcache-0.3.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bf15fc0b45914d9d1b706f7c9c4f66f2b7b053e9517e40123e137e8ca8958b3d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6f/be/105d9ceda0f97eff8c06bac1673448b2db2a497444de3646464d3f5dc881/propcache-0.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5a16167118677d94bb48bfcd91e420088854eb0737b76ec374b91498fb77a70e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cb/c9/f09a4ec394cfcce4053d8b2a04d622b5f22d21ba9bb70edd0cad061fa77b/propcache-0.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:41de3da5458edd5678b0f6ff66691507f9885f5fe6a0fb99a5d10d10c0fd2d64" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/aa/96f7f9ed6def82db67c972bdb7bd9f28b95d7d98f7e2abaf144c284bf609/propcache-0.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:728af36011bb5d344c4fe4af79cfe186729efb649d2f8b395d1572fb088a996c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5a/11/bee5439de1307d06fad176f7143fec906e499c33d7aff863ea8428b8e98b/propcache-0.3.0-cp312-cp312-win32.whl", hash = "sha256:6b5b7fd6ee7b54e01759f2044f936dcf7dea6e7585f35490f7ca0420fe723c0d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e4/17/e5789a54a0455a61cb9efc4ca6071829d992220c2998a27c59aeba749f6f/propcache-0.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:2d15bc27163cd4df433e75f546b9ac31c1ba7b0b128bfb1b90df19082466ff57" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b5/35/6c4c6fc8774a9e3629cd750dc24a7a4fb090a25ccd5c3246d127b70f9e22/propcache-0.3.0-py3-none-any.whl", hash = "sha256:67dda3c7325691c2081510e92c561f465ba61b975f481735aefdfc845d2cd043" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614" }, + { url = "https://mirrors.aliyun.com/pypi/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f" }, ] [[package]] @@ -4303,14 +4591,14 @@ wheels = [ [[package]] name = "pyasn1-modules" -version = "0.4.1" +version = "0.4.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1d/67/6afbf0d507f73c32d21084a79946bfcfca5fbc62a72057e9c23797a737c9/pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/77/89/bc88a6711935ba795a679ea6ebee07e128050d6382eaa35a0a47c8032bdc/pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a" }, ] [[package]] @@ -4350,9 +4638,29 @@ wheels = [ [[package]] name = "pycryptodome" -version = "3.9.9" +version = "3.23.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c4/3a/5bca2cb1648b171afd6b7d29a11c6bca8b305bb75b7e2d78a0f5c61ff95e/pycryptodome-3.9.9.tar.gz", hash = "sha256:910e202a557e1131b1c1b3f17a63914d57aac55cf9fb9b51644962841c3995c4" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8e/a6/8452177684d5e906854776276ddd34eca30d1b1e15aa1ee9cefc289a33f5/pycryptodome-3.23.0.tar.gz", hash = "sha256:447700a657182d60338bab09fdb27518f8856aecd80ae4c6bdddb67ff5da44ef" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/db/6c/a1f71542c969912bb0e106f64f60a56cc1f0fabecf9396f45accbe63fa68/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/4e/a066527e079fc5002390c8acdd3aca431e6ea0a50ffd7201551175b47323/pycryptodome-3.23.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cfb5cd445280c5b0a4e6187a7ce8de5a07b5f3f897f235caa11f1f435f182843" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/52/adaf4c8c100a8c49d2bd058e5b551f73dfd8cb89eb4911e25a0c469b6b4e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67bd81fcbe34f43ad9422ee8fd4843c8e7198dd88dd3d40e6de42ee65fbe1490" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/e9/a09476d436d0ff1402ac3867d933c61805ec2326c6ea557aeeac3825604e/pycryptodome-3.23.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8987bd3307a39bc03df5c8e0e3d8be0c4c3518b7f044b0f4c15d1aa78f52575" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f9/c5/ffe6474e0c551d54cab931918127c46d70cab8f114e0c2b5a3c071c2f484/pycryptodome-3.23.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa0698f65e5b570426fc31b8162ed4603b0c2841cbb9088e2b01641e3065915b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/18/28/e199677fc15ecf43010f2463fde4c1a53015d1fe95fb03bca2890836603a/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:53ecbafc2b55353edcebd64bf5da94a2a2cdf5090a6915bcca6eca6cc452585a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/ea/4fdb09f2165ce1365c9eaefef36625583371ee514db58dc9b65d3a255c4c/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:156df9667ad9f2ad26255926524e1c136d6664b741547deb0a86a9acf5ea631f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/82/6edc3fc42fe9284aead511394bac167693fb2b0e0395b28b8bedaa07ef04/pycryptodome-3.23.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:dea827b4d55ee390dc89b2afe5927d4308a8b538ae91d9c6f7a5090f397af1aa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/59/fe/aae679b64363eb78326c7fdc9d06ec3de18bac68be4b612fc1fe8902693c/pycryptodome-3.23.0-cp37-abi3-win32.whl", hash = "sha256:507dbead45474b62b2bbe318eb1c4c8ee641077532067fec9c1aa82c31f84886" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/2f/e97a1b8294db0daaa87012c24a7bb714147c7ade7656973fd6c736b484ff/pycryptodome-3.23.0-cp37-abi3-win_amd64.whl", hash = "sha256:c75b52aacc6c0c260f204cbdd834f76edc9fb0d8e0da9fbf8352ef58202564e2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/18/3d/f9441a0d798bf2b1e645adc3265e55706aead1255ccdad3856dbdcffec14/pycryptodome-3.23.0-cp37-abi3-win_arm64.whl", hash = "sha256:11eeeb6917903876f134b56ba11abe95c0b0fd5e3330def218083c7d98bbcb3c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9f/7c/f5b0556590e7b4e710509105e668adb55aa9470a9f0e4dea9c40a4a11ce1/pycryptodome-3.23.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:350ebc1eba1da729b35ab7627a833a1a355ee4e852d8ba0447fafe7b14504d56" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/38/dcc795578d610ea1aaffef4b148b8cafcfcf4d126b1e58231ddc4e475c70/pycryptodome-3.23.0-pp27-pypy_73-win32.whl", hash = "sha256:93837e379a3e5fd2bb00302a47aee9fdf7940d83595be3915752c74033d17ca7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/12/e33935a0709c07de084d7d58d330ec3f4daf7910a18e77937affdb728452/pycryptodome-3.23.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ddb95b49df036ddd264a0ad246d1be5b672000f12d6961ea2c267083a5e19379" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/0b/aa8f9419f25870889bebf0b26b223c6986652bdf071f000623df11212c90/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e95564beb8782abfd9e431c974e14563a794a4944c29d6d3b7b5ea042110b4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/5e/63f5cbde2342b7f70a39e591dbe75d9809d6338ce0b07c10406f1a140cdc/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14e15c081e912c4b0d75632acd8382dfce45b258667aa3c67caf7a4d4c13f630" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d6/92/608fbdad566ebe499297a86aae5f2a5263818ceeecd16733006f1600403c/pycryptodome-3.23.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7fc76bf273353dc7e5207d172b83f569540fc9a28d63171061c42e361d22353" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/92/2eadd1341abd2989cce2e2740b4423608ee2014acb8110438244ee97d7ff/pycryptodome-3.23.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:45c69ad715ca1a94f778215a11e66b7ff989d792a4d63b68dc586a1da1392ff5" }, +] [[package]] name = "pycryptodomex" @@ -4370,6 +4678,8 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/48/7d/0f2b09490b98cc6a902ac15dda8760c568b9c18cfe70e0ef7a16de64d53a/pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43" }, { url = "https://mirrors.aliyun.com/pypi/packages/b0/1c/375adb14b71ee1c8d8232904e928b3e7af5bbbca7c04e4bec94fe8e90c3d/pycryptodomex-3.20.0-cp35-abi3-win32.whl", hash = "sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e" }, { url = "https://mirrors.aliyun.com/pypi/packages/b2/e8/1b92184ab7e5595bf38000587e6f8cf9556ebd1bf0a583619bee2057afbd/pycryptodomex-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/c5/9140bb867141d948c8e242013ec8a8011172233c898dfdba0a2417c3169a/pycryptodomex-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:1be97461c439a6af4fe1cf8bf6ca5936d3db252737d2f379cc6b2e394e12a458" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5e/6a/04acb4978ce08ab16890c70611ebc6efd251681341617bbb9e53356dee70/pycryptodomex-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:19764605feea0df966445d46533729b645033f134baeb3ea26ad518c9fdf212c" }, { url = "https://mirrors.aliyun.com/pypi/packages/eb/df/3f1ea084e43b91e6d2b6b3493cc948864c17ea5d93ff1261a03812fbfd1a/pycryptodomex-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b" }, { url = "https://mirrors.aliyun.com/pypi/packages/c9/f3/83ffbdfa0c8f9154bcd8866895f6cae5a3ec749da8b0840603cf936c4412/pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea" }, { url = "https://mirrors.aliyun.com/pypi/packages/c9/9d/c113e640aaf02af5631ae2686b742aac5cd0e1402b9d6512b1c7ec5ef05d/pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781" }, @@ -4447,15 +4757,16 @@ wheels = [ [[package]] name = "pydantic-settings" -version = "2.8.1" +version = "2.10.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "pydantic" }, { name = "python-dotenv" }, + { name = "typing-inspection" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/68/85/1ea668bbab3c50071ca613c6ab30047fb36ab0da1b92fa8f17bbc38fd36c/pydantic_settings-2.10.1.tar.gz", hash = "sha256:06f0062169818d0f5524420a360d632d5857b83cffd4d42fe29597807a1614ee" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/f0/427018098906416f580e3cf1366d3b1abfb408a0652e9f31600c24a1903c/pydantic_settings-2.10.1-py3-none-any.whl", hash = "sha256:a60952460b99cf661dc25c29c0ef171721f98bfcb52ef8d9ea4c943d7c8cc796" }, ] [[package]] @@ -4502,18 +4813,18 @@ sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ba/8e/aedef81641c8dca6 [[package]] name = "pygments" -version = "2.19.1" +version = "2.19.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" }, ] [[package]] name = "pyicu" -version = "2.15" +version = "2.15.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/57/34/10b57cb7bb2ec6fd04d97384ab7ea4422edb3e30ffa8cf4e5524954e8f2c/PyICU-2.15.tar.gz", hash = "sha256:241bf4e73851524af67fea5d94ff60bac83dd98ce3ef6fd6f2c00e07e8476c87" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/9f/57/9db810ab75133a1c87ac2e327fb59199d78d233f575fbb63bfd3492b769c/pyicu-2.15.2.tar.gz", hash = "sha256:561e77eedff17cec6839f26211f7a5ce3c071b776e8a0ec9d1207f46cbce598f" } [[package]] name = "pyjwt" @@ -4582,36 +4893,36 @@ wheels = [ [[package]] name = "pyopenssl" -version = "25.0.0" +version = "25.1.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "cryptography" }, { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/9f/26/e25b4a374b4639e0c235527bbe31c0524f26eda701d79456a7e1877f4cc5/pyopenssl-25.0.0.tar.gz", hash = "sha256:cd2cef799efa3936bb08e8ccb9433a575722b9dd986023f1cabc4ae64e9dac16" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/04/8c/cd89ad05804f8e3c17dea8f178c3f40eeab5694c30e0c9f5bcd49f576fc3/pyopenssl-25.1.0.tar.gz", hash = "sha256:8d031884482e0c67ee92bf9a4d8cceb08d92aba7136432ffb0703c5280fc205b" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/ca/d7/eb76863d2060dcbe7c7e6cccfd95ac02ea0b9acc37745a0d99ff6457aefb/pyOpenSSL-25.0.0-py3-none-any.whl", hash = "sha256:424c247065e46e76a37411b9ab1782541c23bb658bf003772c3405fbaa128e90" }, + { url = "https://mirrors.aliyun.com/pypi/packages/80/28/2659c02301b9500751f8d42f9a6632e1508aa5120de5e43042b8b30f8d5d/pyopenssl-25.1.0-py3-none-any.whl", hash = "sha256:2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab" }, ] [[package]] name = "pyparsing" -version = "3.2.1" +version = "3.2.3" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8b/1a/3544f4f299a47911c2ab3710f534e52fea62a633c96806995da5d25be4b2/pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf" }, ] [[package]] name = "pypdf" -version = "5.4.0" +version = "5.9.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f9/43/4026f6ee056306d0e0eb04fcb9f2122a0f1a5c57ad9dc5e0d67399e47194/pypdf-5.4.0.tar.gz", hash = "sha256:9af476a9dc30fcb137659b0dec747ea94aa954933c52cf02ee33e39a16fe9175" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/89/3a/584b97a228950ed85aec97c811c68473d9b8d149e6a8c155668287cf1a28/pypdf-5.9.0.tar.gz", hash = "sha256:30f67a614d558e495e1fbb157ba58c1de91ffc1718f5e0dfeb82a029233890a1" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0b/27/d83f8f2a03ca5408dc2cc84b49c0bf3fbf059398a6a2ea7c10acfe28859f/pypdf-5.4.0-py3-none-any.whl", hash = "sha256:db994ab47cadc81057ea1591b90e5b543e2b7ef2d0e31ef41a9bfe763c119dab" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/d9/6cff57c80a6963e7dd183bf09e9f21604a77716644b1e580e97b259f7612/pypdf-5.9.0-py3-none-any.whl", hash = "sha256:be10a4c54202f46d9daceaa8788be07aa8cd5ea8c25c529c50dd509206382c35" }, ] [[package]] @@ -4625,22 +4936,22 @@ wheels = [ [[package]] name = "pypdfium2" -version = "4.30.1" +version = "4.30.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/55/d4/905e621c62598a08168c272b42fc00136c8861cfce97afb2a1ecbd99487a/pypdfium2-4.30.1.tar.gz", hash = "sha256:5f5c7c6d03598e107d974f66b220a49436aceb191da34cda5f692be098a814ce" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a1/14/838b3ba247a0ba92e4df5d23f2bea9478edcfd72b78a39d6ca36ccd84ad2/pypdfium2-4.30.0.tar.gz", hash = "sha256:48b5b7e5566665bc1015b9d69c1ebabe21f6aee468b509531c3c8318eeee2e16" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/30/8e/3ce0856b3af0f058dd3655ce57d31d1dbde4d4bd0e172022ffbf1b58a4b9/pypdfium2-4.30.1-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:e07c47633732cc18d890bb7e965ad28a9c5a932e548acb928596f86be2e5ae37" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c2/6a/f6995b21f9c6c155487ce7df70632a2df1ba49efcb291b9943ea45f28b15/pypdfium2-4.30.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5ea2d44e96d361123b67b00f527017aa9c847c871b5714e013c01c3eb36a79fe" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/91/79060923148e6d380b8a299b32bba46d70aac5fe1cd4f04320bcbd1a48d3/pypdfium2-4.30.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de7a3a36803171b3f66911131046d65a732f9e7834438191cb58235e6163c4e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a8/6c/93507f87c159e747eaab54352c0fccbaec3f1b3749d0bb9085a47899f898/pypdfium2-4.30.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8a4231efb13170354f568c722d6540b8d5b476b08825586d48ef70c40d16e03" }, - { url = "https://mirrors.aliyun.com/pypi/packages/24/dc/d56f74a092f2091e328d6485f16562e2fc51cffb0ad6d5c616d80c1eb53c/pypdfium2-4.30.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f434a4934e8244aa95343ffcf24e9ad9f120dbb4785f631bb40a88c39292493" }, - { url = "https://mirrors.aliyun.com/pypi/packages/be/d9/a2f1ee03d47fbeb48bcfde47ed7155772739622cfadf7135a84ba6a97824/pypdfium2-4.30.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f454032a0bc7681900170f67d8711b3942824531e765f91c2f5ce7937f999794" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/47/6aa019c32aa39d3f33347c458c0c5887e84096cbe444456402bc97e66704/pypdfium2-4.30.1-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:bbf9130a72370ee9d602e39949b902db669a2a1c24746a91e5586eb829055d9f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4c/07/2954c15b3f7c85ceb80cad36757fd41b3aba0dd14e68f4bed9ce3f2e7e74/pypdfium2-4.30.1-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5cb52884b1583b96e94fd78542c63bb42e06df5e8f9e52f8f31f5ad5a1e53367" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b4/9b/b4667e95754624f4af5a912001abba90c046e1c80d4a4e887f0af664ffec/pypdfium2-4.30.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:1a9e372bd4867ff223cc8c338e33fe11055dad12f22885950fc27646cc8d9122" }, - { url = "https://mirrors.aliyun.com/pypi/packages/43/38/f9e77cf55ba5546a39fa659404b78b97de2ca344848271e7731efb0954cd/pypdfium2-4.30.1-py3-none-win32.whl", hash = "sha256:421f1cf205e213e07c1f2934905779547f4f4a2ff2f59dde29da3d511d3fc806" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a4/f3/8d3a350efb4286b5ebdabcf6736f51d8e3b10dbe68804c6930b00f5cf329/pypdfium2-4.30.1-py3-none-win_amd64.whl", hash = "sha256:598a7f20264ab5113853cba6d86c4566e4356cad037d7d1f849c8c9021007e05" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e1/6b/2706497c86e8d69fb76afe5ea857fe1794621aa0f3b1d863feb953fe0f22/pypdfium2-4.30.1-py3-none-win_arm64.whl", hash = "sha256:c2b6d63f6d425d9416c08d2511822b54b8e3ac38e639fc41164b1d75584b3a8c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c7/9a/c8ff5cc352c1b60b0b97642ae734f51edbab6e28b45b4fcdfe5306ee3c83/pypdfium2-4.30.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:b33ceded0b6ff5b2b93bc1fe0ad4b71aa6b7e7bd5875f1ca0cdfb6ba6ac01aab" }, + { url = "https://mirrors.aliyun.com/pypi/packages/21/8b/27d4d5409f3c76b985f4ee4afe147b606594411e15ac4dc1c3363c9a9810/pypdfium2-4.30.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:4e55689f4b06e2d2406203e771f78789bd4f190731b5d57383d05cf611d829de" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/63/28a73ca17c24b41a205d658e177d68e198d7dde65a8c99c821d231b6ee3d/pypdfium2-4.30.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e6e50f5ce7f65a40a33d7c9edc39f23140c57e37144c2d6d9e9262a2a854854" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/96/53b3ebf0955edbd02ac6da16a818ecc65c939e98fdeb4e0958362bd385c8/pypdfium2-4.30.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3d0dd3ecaffd0b6dbda3da663220e705cb563918249bda26058c6036752ba3a2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ec/ee/0394e56e7cab8b5b21f744d988400948ef71a9a892cbeb0b200d324ab2c7/pypdfium2-4.30.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc3bf29b0db8c76cdfaac1ec1cde8edf211a7de7390fbf8934ad2aa9b4d6dfad" }, + { url = "https://mirrors.aliyun.com/pypi/packages/65/cd/3f1edf20a0ef4a212a5e20a5900e64942c5a374473671ac0780eaa08ea80/pypdfium2-4.30.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1f78d2189e0ddf9ac2b7a9b9bd4f0c66f54d1389ff6c17e9fd9dc034d06eb3f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/91/2d517db61845698f41a2a974de90762e50faeb529201c6b3574935969045/pypdfium2-4.30.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:5eda3641a2da7a7a0b2f4dbd71d706401a656fea521b6b6faa0675b15d31a163" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ba/c4/ed1315143a7a84b2c7616569dfb472473968d628f17c231c39e29ae9d780/pypdfium2-4.30.0-py3-none-musllinux_1_1_i686.whl", hash = "sha256:0dfa61421b5eb68e1188b0b2231e7ba35735aef2d867d86e48ee6cab6975195e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7a/c4/9e62d03f414e0e3051c56d5943c3bf42aa9608ede4e19dc96438364e9e03/pypdfium2-4.30.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:f33bd79e7a09d5f7acca3b0b69ff6c8a488869a7fab48fdf400fec6e20b9c8be" }, + { url = "https://mirrors.aliyun.com/pypi/packages/90/47/eda4904f715fb98561e34012826e883816945934a851745570521ec89520/pypdfium2-4.30.0-py3-none-win32.whl", hash = "sha256:ee2410f15d576d976c2ab2558c93d392a25fb9f6635e8dd0a8a3a5241b275e0e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/25/bd/56d9ec6b9f0fc4e0d95288759f3179f0fcd34b1a1526b75673d2f6d5196f/pypdfium2-4.30.0-py3-none-win_amd64.whl", hash = "sha256:90dbb2ac07be53219f56be09961eb95cf2473f834d01a42d901d13ccfad64b4c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/7a/097801205b991bc3115e8af1edb850d30aeaf0118520b016354cf5ccd3f6/pypdfium2-4.30.0-py3-none-win_arm64.whl", hash = "sha256:119b2969a6d6b1e8d55e99caaf05290294f2d0fe49c12a3f17102d01c441bd29" }, ] [[package]] @@ -4729,15 +5040,15 @@ wheels = [ [[package]] name = "python-docx" -version = "1.1.2" +version = "1.2.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "lxml" }, { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/35/e4/386c514c53684772885009c12b67a7edd526c15157778ac1b138bc75063e/python_docx-1.1.2.tar.gz", hash = "sha256:0cf1f22e95b9002addca7948e16f2cd7acdfd498047f1941ca5d293db7762efd" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a9/f7/eddfe33871520adab45aaa1a71f0402a2252050c14c7e3009446c8f4701c/python_docx-1.2.0.tar.gz", hash = "sha256:7bc9d7b7d8a69c9c02ca09216118c86552704edc23bac179283f2e38f86220ce" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/3e/3d/330d9efbdb816d3f60bf2ad92f05e1708e4a1b9abe80461ac3444c83f749/python_docx-1.1.2-py3-none-any.whl", hash = "sha256:08c20d6058916fb19853fcf080f7f42b6270d89eac9fa5f8c15f691c0017fabe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/00/1e03a4989fa5795da308cd774f05b704ace555a70f9bf9d3be057b680bcf/python_docx-1.2.0-py3-none-any.whl", hash = "sha256:3fd478f3250fbbbfd3b94fe1e985955737c145627498896a8a6bf81f4baf66c7" }, ] [[package]] @@ -4775,11 +5086,11 @@ wheels = [ [[package]] name = "pytz" -version = "2020.5" +version = "2025.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/70/44/404ec10dca553032900a65bcded8b8280cf7c64cc3b723324e2181bf93c9/pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/89/06/2c2d3034b4d6bf22f2a4ae546d16925898658a33b4400cfb7e2c1e2871a3/pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00" }, ] [[package]] @@ -4798,6 +5109,22 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/77/4b/28d33a6edb8d98402789cbf418063a302a96d04d563163aef07ef5f97f22/pywencai-0.12.2-py3-none-any.whl", hash = "sha256:cd8e87771f057fe6e7019b41e07d9f2cea0600e41bbc445cd0e840d4ac1dde8c" }, ] +[[package]] +name = "pywin32" +version = "311" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/7b/40/44efbb0dfbd33aca6a6483191dae0716070ed99e2ecb0c53683f400a0b4f/pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5e/bf/360243b1e953bd254a82f12653974be395ba880e7ec23e3731d9f73921cc/pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/38/d290720e6f138086fb3d5ffe0b6caa019a791dd57866940c82e4eeaf2012/pywin32-311-cp310-cp310-win_arm64.whl", hash = "sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151" }, + { url = "https://mirrors.aliyun.com/pypi/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503" }, + { url = "https://mirrors.aliyun.com/pypi/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852" }, +] + [[package]] name = "pyyaml" version = "6.0.2" @@ -5128,7 +5455,7 @@ requires-dist = [ { name = "umap-learn", specifier = "==0.5.6" }, { name = "valkey", specifier = "==6.0.2" }, { name = "vertexai", specifier = "==1.64.0" }, - { name = "volcengine", specifier = "==1.0.146" }, + { name = "volcengine", specifier = "==1.0.194" }, { name = "voyageai", specifier = "==0.2.3" }, { name = "webdriver-manager", specifier = "==4.0.1" }, { name = "werkzeug", specifier = "==3.0.6" }, @@ -5137,10 +5464,9 @@ requires-dist = [ { name = "xgboost", specifier = "==1.6.0" }, { name = "xpinyin", specifier = "==0.7.6" }, { name = "xxhash", specifier = ">=3.5.0,<4.0.0" }, - { name = "yfinance", specifier = "==0.1.96" }, + { name = "yfinance", specifier = "==0.2.65" }, { name = "zhipuai", specifier = "==2.0.1" }, ] -provides-extras = ["full"] [package.metadata.requires-dev] test = [ @@ -5221,56 +5547,53 @@ wheels = [ [[package]] name = "regex" -version = "2024.11.6" +version = "2025.7.31" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a6/36/9995080bbdabd4683dd11ab54edcf4fc0e2e4ce4d3eea8034b49fa5dd6ef/regex-2025.7.31.tar.gz", hash = "sha256:80a1af156ea8670ae63184e5c112b481326ece1879e09447f6fbb49d1b49330b" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91" }, - { url = "https://mirrors.aliyun.com/pypi/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62" }, - { url = "https://mirrors.aliyun.com/pypi/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519" }, - { url = "https://mirrors.aliyun.com/pypi/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638" }, - { url = "https://mirrors.aliyun.com/pypi/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20" }, - { url = "https://mirrors.aliyun.com/pypi/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114" }, - { url = "https://mirrors.aliyun.com/pypi/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89" }, - { url = "https://mirrors.aliyun.com/pypi/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45" }, - { url = "https://mirrors.aliyun.com/pypi/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29" }, - { url = "https://mirrors.aliyun.com/pypi/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51" }, - { url = "https://mirrors.aliyun.com/pypi/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54" }, - { url = "https://mirrors.aliyun.com/pypi/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/30/51cf963b5acdb63f3c8e80c4129db3a997f2508e18bf8afc8696fb7408ab/regex-2025.7.31-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b40a8f8064c3b8032babb2049b7ab40812cbb394179556deb7c40c1e3b28630f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/fc/0fd637c648eb7b14cef655266129428fc23e0ceb0a14f5d816ba5e0b76f8/regex-2025.7.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f6aef1895f27875421e6d8047747702d6e512793c6d95614c56479a375541edb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e0/c7/dfdc769cfa01258f3ded76fd3e34d7aad9e96862513adccbdb2a7d02342f/regex-2025.7.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f124ff95b4cbedfd762897d4bd9da2b20b7574df1d60d498f16a42d398d524e9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/61/29f8152131ac78545a4382e14747246b9727ed9467f4f28becb6e97d7c2d/regex-2025.7.31-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea5b162c50745694606f50170cc7cc84c14193ac5fd6ecb26126e826a7c12bd6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8b/f3/10f827814b9d130c9f9e41bd4378b2386e6dd25e8a4c69837692f28db829/regex-2025.7.31-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f970a3e058f587988a18ed4ddff6a6363fa72a41dfb29077d0efe8dc4df00da" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/f9/b6454bedb3af4ae4aba3fdf54d6476872303b63c3d93d3dfc88b43c43334/regex-2025.7.31-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2dadf5788af5b10a78b996d24263e352e5f99dbfce9db4c48e9c875a9a7d051c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b9/28/f81b34d07c70dcd988b9bb124d47ae06c591bcabc2b703b601a61d39528c/regex-2025.7.31-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f67f9f8216a8e645c568daf104abc52cd5387127af8e8b17c7bc11b014d88fcb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/df/e6/3f25e64d853ca18151016329963f9e3a2c9d43f1bf36e172b23bf4e1a6bb/regex-2025.7.31-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:407da7504642830d4211d39dc23b8a9d400913b3f2d242774b8d17ead3487e00" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5c/bc/5b976ca504f2fabb340600bad426e530a25f2c0109c009834af42d5cfd33/regex-2025.7.31-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff7753bd717a9f2286d2171d758eebf11b3bfb21e6520b201e01169ec9cd5ec0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/56/a8/4b0db3eb6d4dbbc10777f20831fde816137a2a5737498c4c7f715e29f2f6/regex-2025.7.31-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de088fe37d4c58a42401bf4ce2328b00a760c7d85473ccf6e489094e13452510" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5a/57/5281baa48d9f25fc7f48f5c216c3825ae5b29c11b0c016535ae3f493b9df/regex-2025.7.31-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:67d708f8bfb89dcd57c3190cb5c343c7f40d3c81319a00c8188982a08c64b977" }, + { url = "https://mirrors.aliyun.com/pypi/packages/51/82/b193e9a4afdb982d39edbb5c2e245a7af2b2e3963c32265fcf2d960b0008/regex-2025.7.31-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3fe81cd00ef1eaef1ef00d61200bacb55b1a130570cd9be2e793b98981c6cd9c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/fc/aa19a1eba4168922d3e6e66671380b86a3841a2a8f6a54ecdcf217424e88/regex-2025.7.31-cp310-cp310-win32.whl", hash = "sha256:8542ee1fd8c8be4db1c58902956a220bdbe7c38362decec989f57ace0e37f14c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bb/ae/9b0c128ef88c3068f949025f6671261e504c6e586f9138309705b82524ee/regex-2025.7.31-cp310-cp310-win_amd64.whl", hash = "sha256:77be56e167e2685828ab0abc1bdf38db3ab385e624c3ea2694b0d4ea70a2b7bc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ba/54/4e598d171a32a67cf7b3912ded0b71dcbab30235f293963c6021359c1233/regex-2025.7.31-cp310-cp310-win_arm64.whl", hash = "sha256:7ddc7ab76d917cb680a3b0fa53fc2971d40cc17415539007e15fa31c829dcf2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ed/a7/85a371e31fb4f675593e0f731f89c54423e0b98d02a3e580fde206ba763b/regex-2025.7.31-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:55dc9f4094656d273562718d68cd8363f688e0b813d62696aad346bcd7b1c7d4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/75/2e738c69d43c086514f687f0d73a8cdc089e6823ad83192d2f6b2cf2b0c7/regex-2025.7.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8ff37cac0e1c7ba943bf46f6431b0c86cbe42d42ae862ff7b152b4ccc232bdd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/7a/8b7b102bc524c3bf8eb3389afcdc381f47cff95a05c5370803e6fd5dfe44/regex-2025.7.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:622aa4ca90d7cf38433d425a4f00543b08d3b109cca379df8f31827cf5e2ecb3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/db/335b829ae5cde7e5de00c0576d899e180605f8c8befee9d58e014d49d4f3/regex-2025.7.31-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cbd4ee61dddfcff625f8642e940ba61121b28e98d0eca24d79114209e3e8ce1b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0d/34/418288618d3c2e68bbf4be3138bcfa1dd088b869923ea8f0bdac37576fa1/regex-2025.7.31-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca7c9af8f33540b51f1b76092e732b62211092af947239e5db471323ae39ead4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/b8/b570626227c257725cd7ecfee07f697850fc45d38df710a13b2b6d681943/regex-2025.7.31-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:beda88db2cae5dc82a64cba465f7e8686392d96116f87e664af46c4dfcdd9cbc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/42/af/d35718c1ccd68bd2e7b6b26a83c4919516d73610ddf124796797a7858749/regex-2025.7.31-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055baef91bb31474bd919fd245cf154db00cbac449596952d3e6bc1e1b226808" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cd/32/3daed29302ead90198cdcd1367edaa6913899f3d224c41eddcf8750979cc/regex-2025.7.31-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:02e660c2d02854eed41b13f0e2c98d24efce4fb439aa316742f8d32aeda2803b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ac/30/7f823c11f9b83f3a6c333a37322aa5867d7983447f8a83a07eccd49bd847/regex-2025.7.31-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4372ca5c43d0e255e68a9aa6812d9be3447c4ce7ba7cb1429c7b96d2c63ee9b1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/80/0e/a1cae70e3b5e44f5ad5672c1a17011c4ae37250987ce7635c2547c2cc570/regex-2025.7.31-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:481f069facacb4f40bf37a51748a88952f5dd5707dd849f216d53bf5522c8add" }, + { url = "https://mirrors.aliyun.com/pypi/packages/73/ce/c8e3a31a449145572f9a97960e873546f7f842448dd2a0e68d4f667a77a4/regex-2025.7.31-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e8b4896ec5a9d0ae73d04e260ff6e1f366985b46505b2fa36d91501e4a7a98f0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/eb/0429111b7493459d3f765cc921d1e2ce1228b049895f3a1cb8525d51526a/regex-2025.7.31-cp311-cp311-win32.whl", hash = "sha256:47ceaa1e5eb243595306dfd5e5e294e251900aa94a0e2e1037fce125f432d2fb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ec/4a/5b05e5ff93eb852eec932eb71a7465e4a879a77f9558b2c132af0fcec438/regex-2025.7.31-cp311-cp311-win_amd64.whl", hash = "sha256:c4f6b34f509bb26507509b6f9ba85debcc6ca512d2d4a6fd5e96b9de2c187c83" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fc/0c/a27e089caaef5a393b72cc65f88a6ba23805f72b6c431c19928d2870a3a3/regex-2025.7.31-cp311-cp311-win_arm64.whl", hash = "sha256:75f74892df1593036e83b48ba50d1e1951af650b6fabbfcf7531e7082e3561d4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/2a/6cde7309f9a90a04b43492eef04893dd551b4284cfbde3650bdab1f2d45e/regex-2025.7.31-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1af64eed343f19e1f09da9e9e8cfb82570050c4ed9fec400f9f118aab383da4b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/19/aa/6ad49cb0e7e5c4ba6219b33aacf1b8217ecd4d8ec9c1173d8166b7b6d7b8/regex-2025.7.31-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:eab98712c0a6d053fb67b021fae43422f7eab8fa2aaa25034f5ef01585112cc7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b6/99/67826894a43447144e610c76a958db9b31318435b04bc21974ccc75fcfce/regex-2025.7.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34dcb7c4d89b83e7e3cb5a2679595f6f97d253815ed9402edbdfc56780668b89" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/22/14dcf80def58a009143ced54665721ff7706440ce93b37bd34a36eebbe24/regex-2025.7.31-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:52f1925d123338835e5b13e5ef8e6a744c02aef8e538e661ad5c76185e6ad87a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/51/f36e6c8fdb62304ed1ba29bbc2d381ecdf37273cc32a4d65a5e64b1fa002/regex-2025.7.31-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:569c2b6812d223ae82a2a13c36362ca5933b88011ba869111eba8fb769ccf492" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/4c/29083c291e329df4e883304c6d7a99beb6dba9cc31b4f99737cf0a75269a/regex-2025.7.31-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:27f17ade67d06ce4abff48f2ee99c6419f73e70882fe7ca51960916c75844e1f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/4e/7450d9d63edaa6abf7561fdf8ce540d7140bbd9d493328e3852c4bf9222c/regex-2025.7.31-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45622fab3a90590a41a541afea739a732bf110dd081c15c84538b115cf5f59f5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/36/57cb185286dc2c63f0e08e68a8f724870a0c7939a9029cb6e14fea159100/regex-2025.7.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:defab878ce91944baf2ade775895a097ad7eeeab3618d87b4c29753aad98a5c4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/88/bd/f38a26e98f4f504dc669cbb79e0df3b3eb09a1bcebf8b9eac91f62afc36a/regex-2025.7.31-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8ae02caf994a0a0d958b9b0fc5aebbdb48fa93491a582dd00db3733d258a6ac4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/b8/96ce23733a03f6c673ed9dd23766bdbf678c340d6c08016ffde04f53508b/regex-2025.7.31-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7c40ab21112711363d7612f35781c8b2d2d59c27e0a057a6486eea60ee01e54" }, + { url = "https://mirrors.aliyun.com/pypi/packages/10/4a/f50cd8c4699049513df4d999e1ff61c054304a29e099ed4848de36e52fb7/regex-2025.7.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4723c01dd28c1b1de5f463bba8672e3d0dc3d94d5db056e4bbc3cbc84bf23c1c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/05/5b68b3d392f6158f5ea968f193f3f6271609b8197483809bdf4c2081989b/regex-2025.7.31-cp312-cp312-win32.whl", hash = "sha256:3ebf32b2b2f60aecd6f8d375ff310849251946cf953aac69b8b5b10e3ccebaf9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0d/6c/703c6c8d4bdf771cf65466d09bd300ca663041a53d30555beca43b26d3dc/regex-2025.7.31-cp312-cp312-win_amd64.whl", hash = "sha256:12f9ab65b4cc771dd6d8af806ded7425ca50d2a188d2fc3a5aba3dc49f5684b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a1/90/f13eddf7ded8857b51f8d9ebebbc0e862ffb739f2a0f7fcff30a0f95676a/regex-2025.7.31-cp312-cp312-win_arm64.whl", hash = "sha256:fd454ed1fe245f983c2376b6f01948d6ec4a1e5869a8c883e320e1739cc63e57" }, ] [[package]] @@ -5290,15 +5613,15 @@ wheels = [ [[package]] name = "reportlab" -version = "4.4.1" +version = "4.4.3" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "chardet" }, + { name = "charset-normalizer" }, { name = "pillow" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7b/d8/c3366bf10a5a5fcc3467eefa9504f6aa24fcda5817b5b147eabd37a385e1/reportlab-4.4.1.tar.gz", hash = "sha256:5f9b9fc0b7a48e8912c25ccf69d26b82980ab0da718e4f583fa720e8f8f5073f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/2f/83/3d44b873fa71ddc7d323c577fe4cfb61e05b34d14e64b6a232f9cfbff89d/reportlab-4.4.3.tar.gz", hash = "sha256:073b0975dab69536acd3251858e6b0524ed3e087e71f1d0d1895acb50acf9c7b" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/a1/2e/7994a139150abf11c8dd258feb091ad654823a83cfd9720bfdded27185c3/reportlab-4.4.1-py3-none-any.whl", hash = "sha256:9217a1c8c1917217f819718b24972a96ad0c485a1c494749562d097b58d974b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/52/c8/aaf4e08679e7b1dc896ad30de0d0527f0fd55582c2e6deee4f2cc899bf9f/reportlab-4.4.3-py3-none-any.whl", hash = "sha256:df905dc5ec5ddaae91fc9cb3371af863311271d555236410954961c5ee6ee1b5" }, ] [[package]] @@ -5348,16 +5671,15 @@ wheels = [ [[package]] name = "rich" -version = "13.9.4" +version = "14.1.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f" }, ] [[package]] @@ -5380,73 +5702,86 @@ wheels = [ [[package]] name = "rpds-py" -version = "0.23.1" +version = "0.26.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/0a/79/2ce611b18c4fd83d9e3aecb5cba93e1917c050f556db39842889fa69b79f/rpds_py-0.23.1.tar.gz", hash = "sha256:7f3240dcfa14d198dba24b8b9cb3b108c06b68d45b7babd9eefc1038fdf7e707" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a5/aa/4456d84bbb54adc6a916fb10c9b374f78ac840337644e4a5eda229c81275/rpds_py-0.26.0.tar.gz", hash = "sha256:20dae58a859b0906f0685642e591056f1e787f3a8b39c8e8749a45dc7d26bdb0" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/34/fe/e5326459863bd525122f4e9c80ac8d7c6cfa171b7518d04cc27c12c209b0/rpds_py-0.23.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2a54027554ce9b129fc3d633c92fa33b30de9f08bc61b32c053dc9b537266fed" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f9/db/f10a3795f7a89fb27594934012d21c61019bbeb516c5bdcfbbe9e9e617a7/rpds_py-0.23.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b5ef909a37e9738d146519657a1aab4584018746a18f71c692f2f22168ece40c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/21/27/0d3678ad7f432fa86f8fac5f5fc6496a4d2da85682a710d605219be20063/rpds_py-0.23.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ee9d6f0b38efb22ad94c3b68ffebe4c47865cdf4b17f6806d6c674e1feb4246" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/a0/1786defa125b2ad228027f22dff26312ce7d1fee3c7c3c2682f403db2062/rpds_py-0.23.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f7356a6da0562190558c4fcc14f0281db191cdf4cb96e7604c06acfcee96df15" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f1/5c/1240934050a7ffd020a915486d0cc4c7f6e7a2442a77aedf13664db55d36/rpds_py-0.23.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9441af1d25aed96901f97ad83d5c3e35e6cd21a25ca5e4916c82d7dd0490a4fa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b7/1b/cee6905b47817fd0a377716dbe4df35295de46df46ee2ff704538cc371b0/rpds_py-0.23.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d8abf7896a91fb97e7977d1aadfcc2c80415d6dc2f1d0fca5b8d0df247248f3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/54/f7/f0821ca34032892d7a67fcd5042f50074ff2de64e771e10df01085c88d47/rpds_py-0.23.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b08027489ba8fedde72ddd233a5ea411b85a6ed78175f40285bd401bde7466d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/eb/ef/2afe53bc857c4bcba336acfd2629883a5746e7291023e017ac7fc98d85aa/rpds_py-0.23.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fee513135b5a58f3bb6d89e48326cd5aa308e4bcdf2f7d59f67c861ada482bf8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ae/9a/38d2236cf669789b8a3e1a014c9b6a8d7b8925b952c92e7839ae2749f9ac/rpds_py-0.23.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:35d5631ce0af26318dba0ae0ac941c534453e42f569011585cb323b7774502a5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e6/0a/f2705530c42578f20ed0b5b90135eecb30eef6e2ba73e7ba69087fad2dba/rpds_py-0.23.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a20cb698c4a59c534c6701b1c24a968ff2768b18ea2991f886bd8985ce17a89f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/29/4e/3b597dc84ed82c3d757ac9aa620de224a94e06d2e102069795ae7e81c015/rpds_py-0.23.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e9c206a1abc27e0588cf8b7c8246e51f1a16a103734f7750830a1ccb63f557a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/00/cc/6498b6f79e4375e6737247661e52a2d18f6accf4910e0c8da978674b4241/rpds_py-0.23.1-cp310-cp310-win32.whl", hash = "sha256:d9f75a06ecc68f159d5d7603b734e1ff6daa9497a929150f794013aa9f6e3f12" }, - { url = "https://mirrors.aliyun.com/pypi/packages/17/2b/08db023d23e8c7032c99d8d2a70d32e450a868ab73d16e3ff5290308a665/rpds_py-0.23.1-cp310-cp310-win_amd64.whl", hash = "sha256:f35eff113ad430b5272bbfc18ba111c66ff525828f24898b4e146eb479a2cdda" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1c/67/6e5d4234bb9dee062ffca2a5f3c7cd38716317d6760ec235b175eed4de2c/rpds_py-0.23.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b79f5ced71efd70414a9a80bbbfaa7160da307723166f09b69773153bf17c590" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a7/0a/3dedb2daee8e783622427f5064e2d112751d8276ee73aa5409f000a132f4/rpds_py-0.23.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c9e799dac1ffbe7b10c1fd42fe4cd51371a549c6e108249bde9cd1200e8f59b4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ed/fc/e1acef44f9c24b05fe5434b235f165a63a52959ac655e3f7a55726cee1a4/rpds_py-0.23.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721f9c4011b443b6e84505fc00cc7aadc9d1743f1c988e4c89353e19c4a968ee" }, - { url = "https://mirrors.aliyun.com/pypi/packages/97/0a/a05951f6465d01622720c03ef6ef31adfbe865653e05ed7c45837492f25e/rpds_py-0.23.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f88626e3f5e57432e6191cd0c5d6d6b319b635e70b40be2ffba713053e5147dd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/2e/cca0583ec0690ea441dceae23c0673b99755710ea22f40bccf1e78f41481/rpds_py-0.23.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:285019078537949cecd0190f3690a0b0125ff743d6a53dfeb7a4e6787af154f5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cc/e6/95cda68b33a6d814d1e96b0e406d231ed16629101460d1740e92f03365e6/rpds_py-0.23.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b92f5654157de1379c509b15acec9d12ecf6e3bc1996571b6cb82a4302060447" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5f/a7/e94cdb73411ae9c11414d3c7c9a6ad75d22ad4a8d094fb45a345ba9e3018/rpds_py-0.23.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e768267cbe051dd8d1c5305ba690bb153204a09bf2e3de3ae530de955f5b5580" }, - { url = "https://mirrors.aliyun.com/pypi/packages/dd/c5/a4a943d90a39e85efd1e04b1ad5129936786f9a9aa27bb7be8fc5d9d50c9/rpds_py-0.23.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c5334a71f7dc1160382d45997e29f2637c02f8a26af41073189d79b95d3321f1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0c/a0/80d0013b12428d1fce0ab4e71829400b0a32caec12733c79e6109f843342/rpds_py-0.23.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d6adb81564af0cd428910f83fa7da46ce9ad47c56c0b22b50872bc4515d91966" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a6/92/ec2e6980afb964a2cd7a99cbdef1f6c01116abe94b42cbe336ac93dd11c2/rpds_py-0.23.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cafa48f2133d4daa028473ede7d81cd1b9f9e6925e9e4003ebdf77010ee02f35" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3d/ce/75b6054db34a390789a82523790717b27c1bd735e453abb429a87c4f0f26/rpds_py-0.23.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fced9fd4a07a1ded1bac7e961ddd9753dd5d8b755ba8e05acba54a21f5f1522" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cc/24/f45abe0418c06a5cba0f846e967aa27bac765acd927aabd857c21319b8cc/rpds_py-0.23.1-cp311-cp311-win32.whl", hash = "sha256:243241c95174b5fb7204c04595852fe3943cc41f47aa14c3828bc18cd9d3b2d6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2d/a6/3c0880e8bbfc36451ef30dc416266f6d2934705e468db5d21c8ba0ab6400/rpds_py-0.23.1-cp311-cp311-win_amd64.whl", hash = "sha256:11dd60b2ffddba85715d8a66bb39b95ddbe389ad2cfcf42c833f1bcde0878eaf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f3/8c/d17efccb9f5b9137ddea706664aebae694384ae1d5997c0202093e37185a/rpds_py-0.23.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3902df19540e9af4cc0c3ae75974c65d2c156b9257e91f5101a51f99136d834c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6e/c0/ab030f696b5c573107115a88d8d73d80f03309e60952b64c584c70c659af/rpds_py-0.23.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66f8d2a17e5838dd6fb9be6baaba8e75ae2f5fa6b6b755d597184bfcd3cb0eba" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b3/55/b40170f5a079c4fb0b6a82b299689e66e744edca3c3375a8b160fb797660/rpds_py-0.23.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:112b8774b0b4ee22368fec42749b94366bd9b536f8f74c3d4175d4395f5cbd31" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ab/1c/b03a912c59ec7c1e16b26e587b9dfa8ddff3b07851e781e8c46e908a365a/rpds_py-0.23.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0df046f2266e8586cf09d00588302a32923eb6386ced0ca5c9deade6af9a149" }, - { url = "https://mirrors.aliyun.com/pypi/packages/52/6f/151b90792b62fb6f87099bcc9044c626881fdd54e31bf98541f830b15cea/rpds_py-0.23.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3288930b947cbebe767f84cf618d2cbe0b13be476e749da0e6a009f986248c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/71/2a/6de67c0c97ec7857e0e9e5cd7c52405af931b303eb1e5b9eff6c50fd9a2e/rpds_py-0.23.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce473a2351c018b06dd8d30d5da8ab5a0831056cc53b2006e2a8028172c37ce5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/db/5e/e759cd1c276d98a4b1f464b17a9bf66c65d29f8f85754e27e1467feaa7c3/rpds_py-0.23.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d550d7e9e7d8676b183b37d65b5cd8de13676a738973d330b59dc8312df9c5dc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1c/1e/2900358efcc0d9408c7289769cba4c0974d9db314aa884028ed7f7364f61/rpds_py-0.23.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e14f86b871ea74c3fddc9a40e947d6a5d09def5adc2076ee61fb910a9014fb35" }, - { url = "https://mirrors.aliyun.com/pypi/packages/23/07/6c177e6d059f5d39689352d6c69a926ee4805ffdb6f06203570234d3d8f7/rpds_py-0.23.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1bf5be5ba34e19be579ae873da515a2836a2166d8d7ee43be6ff909eda42b72b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/70/e4/f9097fd1c02b516fff9850792161eb9fc20a2fd54762f3c69eae0bdb67cb/rpds_py-0.23.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7031d493c4465dbc8d40bd6cafefef4bd472b17db0ab94c53e7909ee781b9ef" }, - { url = "https://mirrors.aliyun.com/pypi/packages/87/39/5db3c6f326bfbe4576ae2af6435bd7555867d20ae690c786ff33659f293b/rpds_py-0.23.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:55ff4151cfd4bc635e51cfb1c59ac9f7196b256b12e3a57deb9e5742e65941ad" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/14/2d5ad292f144fa79bafb78d2eb5b8a3a91c358b6065443cb9c49b5d1fedf/rpds_py-0.23.1-cp312-cp312-win32.whl", hash = "sha256:a9d3b728f5a5873d84cba997b9d617c6090ca5721caaa691f3b1a78c60adc057" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a3/4f/0fce63e0f5cdd658e71e21abd17ac1bc9312741ebb8b3f74eeed2ebdf771/rpds_py-0.23.1-cp312-cp312-win_amd64.whl", hash = "sha256:b03a8d50b137ee758e4c73638b10747b7c39988eb8e6cd11abb7084266455165" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/a9/6fafd35fc6bac05f59bcbc800b57cef877911ff1c015397c519fec888642/rpds_py-0.23.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c1f8afa346ccd59e4e5630d5abb67aba6a9812fddf764fd7eb11f382a345f8cc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5b/ac/44f00029b8fbe0903a19e9a87a9b86063bf8700df2cc58868373d378418c/rpds_py-0.23.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fad784a31869747df4ac968a351e070c06ca377549e4ace94775aaa3ab33ee06" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5e/9c/3da199346c68d785f10dccab123b74c8c5f73be3f742c9e33d1116e07931/rpds_py-0.23.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5a96fcac2f18e5a0a23a75cd27ce2656c66c11c127b0318e508aab436b77428" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d3/45/8f6533c33c0d33da8c2c8b2fb8f2ee90b23c05c679b86b0ac6aee4653749/rpds_py-0.23.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3e77febf227a1dc3220159355dba68faa13f8dca9335d97504abf428469fb18b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ca/56/6a9ac1bf0455ba07385d8fe98c571c519b4f2000cff6581487bf9fab9272/rpds_py-0.23.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26bb3e8de93443d55e2e748e9fd87deb5f8075ca7bc0502cfc8be8687d69a2ec" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f4/83/5d9a3f9731cdccf49088bcc4ce821a5cf50bd1737cdad83e9959a7b9054d/rpds_py-0.23.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db7707dde9143a67b8812c7e66aeb2d843fe33cc8e374170f4d2c50bd8f2472d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/44/50/f2e0a98c62fc1fe68b176caca587714dc5c8bb2c3d1dd1eeb2bd4cc787ac/rpds_py-0.23.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eedaaccc9bb66581d4ae7c50e15856e335e57ef2734dbc5fd8ba3e2a4ab3cb6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f2/d0/4981878f8f157e6dbea01d95e0119bf3d6b4c2c884fe64a9e6987f941104/rpds_py-0.23.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28358c54fffadf0ae893f6c1050e8f8853e45df22483b7fff2f6ab6152f5d8bf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ce/13/fc971c470da96b270d2f64fedee987351bd935dc3016932a5cdcb1a88a2a/rpds_py-0.23.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:633462ef7e61d839171bf206551d5ab42b30b71cac8f10a64a662536e057fdef" }, - { url = "https://mirrors.aliyun.com/pypi/packages/42/02/be91e1de139ec8b4f9fec4192fd779ba48af281cfc762c0ca4c15b945484/rpds_py-0.23.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a98f510d86f689fcb486dc59e6e363af04151e5260ad1bdddb5625c10f1e95f8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/27/28/3af8a1956df3edc41d884267d766dc096496dafc83f02f764a475eca0b4a/rpds_py-0.23.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e0397dd0b3955c61ef9b22838144aa4bef6f0796ba5cc8edfc64d468b93798b4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5e/bb/e45f51c4e1327dea3c72b846c6de129eebacb7a6cb309af7af35d0578c80/rpds_py-0.23.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:75307599f0d25bf6937248e5ac4e3bde5ea72ae6618623b86146ccc7845ed00b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b9/31/1459645f036c3dfeacef89e8e5825e430c77dde8489f3b99eaafcd4a60f5/rpds_py-0.26.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4c70c70f9169692b36307a95f3d8c0a9fcd79f7b4a383aad5eaa0e9718b79b37" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dd/ff/3d0727f35836cc8773d3eeb9a46c40cc405854e36a8d2e951f3a8391c976/rpds_py-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:777c62479d12395bfb932944e61e915741e364c843afc3196b694db3d669fcd0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/ce/badc5e06120a54099ae287fa96d82cbb650a5f85cf247ffe19c7b157fd1f/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec671691e72dff75817386aa02d81e708b5a7ec0dec6669ec05213ff6b77e1bd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1e/a5/fa5d96a66c95d06c62d7a30707b6a4cfec696ab8ae280ee7be14e961e118/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a1cb5d6ce81379401bbb7f6dbe3d56de537fb8235979843f0d53bc2e9815a79" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/a7/7049d66750f18605c591a9db47d4a059e112a0c9ff8de8daf8fa0f446bba/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f789e32fa1fb6a7bf890e0124e7b42d1e60d28ebff57fe806719abb75f0e9a3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/f1/528d02c7d6b29d29fac8fd784b354d3571cc2153f33f842599ef0cf20dd2/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c55b0a669976cf258afd718de3d9ad1b7d1fe0a91cd1ab36f38b03d4d4aeaaf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/15/93/fde36cd6e4685df2cd08508f6c45a841e82f5bb98c8d5ecf05649522acb5/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70d9ec912802ecfd6cd390dadb34a9578b04f9bcb8e863d0a7598ba5e9e7ccc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/69/f2/5007553aaba1dcae5d663143683c3dfd03d9395289f495f0aebc93e90f24/rpds_py-0.26.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3021933c2cb7def39d927b9862292e0f4c75a13d7de70eb0ab06efed4c508c19" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/a7/ce52c75c1e624a79e48a69e611f1c08844564e44c85db2b6f711d76d10ce/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a7898b6ca3b7d6659e55cdac825a2e58c638cbf335cde41f4619e290dd0ad11" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/d5/e119db99341cc75b538bf4cb80504129fa22ce216672fb2c28e4a101f4d9/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:12bff2ad9447188377f1b2794772f91fe68bb4bbfa5a39d7941fbebdbf8c500f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/94/d28272a0b02f5fe24c78c20e13bbcb95f03dc1451b68e7830ca040c60bd6/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:191aa858f7d4902e975d4cf2f2d9243816c91e9605070aeb09c0a800d187e323" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/e0/8c41166602f1b791da892d976057eba30685486d2e2c061ce234679c922b/rpds_py-0.26.0-cp310-cp310-win32.whl", hash = "sha256:b37a04d9f52cb76b6b78f35109b513f6519efb481d8ca4c321f6a3b9580b3f45" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/f0/509736bb752a7ab50fb0270c2a4134d671a7b3038030837e5536c3de0e0b/rpds_py-0.26.0-cp310-cp310-win_amd64.whl", hash = "sha256:38721d4c9edd3eb6670437d8d5e2070063f305bfa2d5aa4278c51cedcd508a84" }, + { url = "https://mirrors.aliyun.com/pypi/packages/09/4c/4ee8f7e512030ff79fda1df3243c88d70fc874634e2dbe5df13ba4210078/rpds_py-0.26.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9e8cb77286025bdb21be2941d64ac6ca016130bfdcd228739e8ab137eb4406ed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/9d/3dc16be00f14fc1f03c71b1d67c8df98263ab2710a2fbd65a6193214a527/rpds_py-0.26.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e09330b21d98adc8ccb2dbb9fc6cb434e8908d4c119aeaa772cb1caab5440a0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/5a/7f1bf8f045da2866324a08ae80af63e64e7bfaf83bd31f865a7b91a58601/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9c1b92b774b2e68d11193dc39620d62fd8ab33f0a3c77ecdabe19c179cdbc1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/45/8a/04479398c755a066ace10e3d158866beb600867cacae194c50ffa783abd0/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:824e6d3503ab990d7090768e4dfd9e840837bae057f212ff9f4f05ec6d1975e7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/72/88/9203f47268db488a1b6d469d69c12201ede776bb728b9d9f29dbfd7df406/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ad7fd2258228bf288f2331f0a6148ad0186b2e3643055ed0db30990e59817a6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/b4/01ce5d1e853ddf81fbbd4311ab1eff0b3cf162d559288d10fd127e2588b5/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dc23bbb3e06ec1ea72d515fb572c1fea59695aefbffb106501138762e1e915e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/a2/004c99936997bfc644d590a9defd9e9c93f8286568f9c16cdaf3e14429a7/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d80bf832ac7b1920ee29a426cdca335f96a2b5caa839811803e999b41ba9030d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/1b/ef5fba4a8f81ce04c427bfd96223f92f05e6cd72291ce9d7523db3b03a6c/rpds_py-0.26.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/80/5c54195aec456b292f7bd8aa61741c8232964063fd8a75fdde9c1e982328/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d422b945683e409000c888e384546dbab9009bb92f7c0b456e217988cf316107" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f2/1c/1845c1b1fd6d827187c43afe1841d91678d7241cbdb5420a4c6de180a538/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a7711fa562ba2da1aa757e11024ad6d93bad6ad7ede5afb9af144623e5f76a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/ff/9e979329dd131aa73a438c077252ddabd7df6d1a7ad7b9aacf6261f10faa/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238e8c8610cb7c29460e37184f6799547f7e09e6a9bdbdab4e8edb90986a2318" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/8b/d78cfe034b71ffbe72873a136e71acc7a831a03e37771cfe59f33f6de8a2/rpds_py-0.26.0-cp311-cp311-win32.whl", hash = "sha256:893b022bfbdf26d7bedb083efeea624e8550ca6eb98bf7fea30211ce95b9201a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/94/c1/3c8c94c7dd3905dbfde768381ce98778500a80db9924731d87ddcdb117e9/rpds_py-0.26.0-cp311-cp311-win_amd64.whl", hash = "sha256:87a5531de9f71aceb8af041d72fc4cab4943648d91875ed56d2e629bef6d4c03" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/93/e936fbed1b734eabf36ccb5d93c6a2e9246fbb13c1da011624b7286fae3e/rpds_py-0.26.0-cp311-cp311-win_arm64.whl", hash = "sha256:de2713f48c1ad57f89ac25b3cb7daed2156d8e822cf0eca9b96a6f990718cc41" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ea/86/90eb87c6f87085868bd077c7a9938006eb1ce19ed4d06944a90d3560fce2/rpds_py-0.26.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:894514d47e012e794f1350f076c427d2347ebf82f9b958d554d12819849a369d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/63/78/4469f24d34636242c924626082b9586f064ada0b5dbb1e9d096ee7a8e0c6/rpds_py-0.26.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc921b96fa95a097add244da36a1d9e4f3039160d1d30f1b35837bf108c21136" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ad/91/c448ed45efdfdade82348d5e7995e15612754826ea640afc20915119734f/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e1157659470aa42a75448b6e943c895be8c70531c43cb78b9ba990778955582" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ec/43/e5c86fef4be7f49828bdd4ecc8931f0287b1152c0bb0163049b3218740e7/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:521ccf56f45bb3a791182dc6b88ae5f8fa079dd705ee42138c76deb1238e554e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/55/34/e00f726a4d44f22d5c5fe2e5ddd3ac3d7fd3f74a175607781fbdd06fe375/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9def736773fd56b305c0eef698be5192c77bfa30d55a0e5885f80126c4831a15" }, + { url = "https://mirrors.aliyun.com/pypi/packages/52/1c/52dc20c31b147af724b16104500fba13e60123ea0334beba7b40e33354b4/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdad4ea3b4513b475e027be79e5a0ceac8ee1c113a1a11e5edc3c30c29f964d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/d4/7f2200c2d3ee145b65b3cddc4310d51f7da6a26634f3ac87125fd789152a/rpds_py-0.26.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d04cab0a54b9dba4d278fe955a1390da3cf71f57feb78ddc7cb67cbe0bd30323" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ae/13/9fdd428b9c820869924ab62236b8688b122baa22d23efdd1c566938a39ba/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:79061ba1a11b6a12743a2b0f72a46aa2758613d454aa6ba4f5a265cc48850158" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f3/e1/b69686c3bcbe775abac3a4c1c30a164a2076d28df7926041f6c0eb5e8d28/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f405c93675d8d4c5ac87364bb38d06c988e11028a64b52a47158a355079661f3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5c/c9/1e3d8c8863c84a90197ac577bbc3d796a92502124c27092413426f670990/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dafd4c44b74aa4bed4b250f1aed165b8ef5de743bcca3b88fc9619b6087093d2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9f/c5/90c569649057622959f6dcc40f7b516539608a414dfd54b8d77e3b201ac0/rpds_py-0.26.0-cp312-cp312-win32.whl", hash = "sha256:3da5852aad63fa0c6f836f3359647870e21ea96cf433eb393ffa45263a170d44" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/16/19f5d9f2a556cfed454eebe4d354c38d51c20f3db69e7b4ce6cff904905d/rpds_py-0.26.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf47cfdabc2194a669dcf7a8dbba62e37a04c5041d2125fae0233b720da6f05c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/83/f0/7935e40b529c0e752dfaa7880224771b51175fce08b41ab4a92eb2fbdc7f/rpds_py-0.26.0-cp312-cp312-win_arm64.whl", hash = "sha256:20ab1ae4fa534f73647aad289003f1104092890849e0266271351922ed5574f8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ef/9a/1f033b0b31253d03d785b0cd905bc127e555ab496ea6b4c7c2e1f951f2fd/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3c0909c5234543ada2515c05dc08595b08d621ba919629e94427e8e03539c958" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/29/5f88023fd6aaaa8ca3c4a6357ebb23f6f07da6079093ccf27c99efce87db/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c1fb0cda2abcc0ac62f64e2ea4b4e64c57dfd6b885e693095460c61bde7bb18e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6c/6c/13eaebd28b439da6964dde22712b52e53fe2824af0223b8e403249d10405/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d142d2d6cf9b31c12aa4878d82ed3b2324226270b89b676ac62ccd7df52d08" }, + { url = "https://mirrors.aliyun.com/pypi/packages/55/fc/3bb9c486b06da19448646f96147796de23c5811ef77cbfc26f17307b6a9d/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a547e21c5610b7e9093d870be50682a6a6cf180d6da0f42c47c306073bfdbbf6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/15/18/9d1b79eb4d18e64ba8bba9e7dec6f9d6920b639f22f07ee9368ca35d4673/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35e9a70a0f335371275cdcd08bc5b8051ac494dd58bff3bbfb421038220dc871" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/5a/175ad7191bdbcd28785204621b225ad70e85cdfd1e09cc414cb554633b21/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dfa6115c6def37905344d56fb54c03afc49104e2ca473d5dedec0f6606913b4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/45/6a67ecf6d61c4d4aff4bc056e864eec4b2447787e11d1c2c9a0242c6e92a/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313cfcd6af1a55a286a3c9a25f64af6d0e46cf60bc5798f1db152d97a216ff6f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a1/ba/16589da828732b46454c61858950a78fe4c931ea4bf95f17432ffe64b241/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7bf2496fa563c046d05e4d232d7b7fd61346e2402052064b773e5c378bf6f73" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/4b/00092999fc7c0c266045e984d56b7314734cc400a6c6dc4d61a35f135a9d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:aa81873e2c8c5aa616ab8e017a481a96742fdf9313c40f14338ca7dbf50cb55f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/0c/43737053cde1f93ac4945157f7be1428724ab943e2132a0d235a7e161d4e/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:68ffcf982715f5b5b7686bdd349ff75d422e8f22551000c24b30eaa1b7f7ae84" }, + { url = "https://mirrors.aliyun.com/pypi/packages/46/46/8e38f6161466e60a997ed7e9951ae5de131dedc3cf778ad35994b4af823d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6188de70e190847bb6db3dc3981cbadff87d27d6fe9b4f0e18726d55795cee9b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2c/ac/65da605e9f1dd643ebe615d5bbd11b6efa1d69644fc4bf623ea5ae385a82/rpds_py-0.26.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c962145c7473723df9722ba4c058de12eb5ebedcb4e27e7d902920aa3831ee8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/51/f2/b5c85b758a00c513bb0389f8fc8e61eb5423050c91c958cdd21843faa3e6/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f61a9326f80ca59214d1cceb0a09bb2ece5b2563d4e0cd37bfd5515c28510674" }, + { url = "https://mirrors.aliyun.com/pypi/packages/23/e0/25db45e391251118e915e541995bb5f5ac5691a3b98fb233020ba53afc9b/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:183f857a53bcf4b1b42ef0f57ca553ab56bdd170e49d8091e96c51c3d69ca696" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/73/dd5ee6075bb6491be3a646b301dfd814f9486d924137a5098e61f0487e16/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:941c1cfdf4799d623cf3aa1d326a6b4fdb7a5799ee2687f3516738216d2262fb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/10/84b522ff58763a5c443f5bcedc1820240e454ce4e620e88520f04589e2ea/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72a8d9564a717ee291f554eeb4bfeafe2309d5ec0aa6c475170bdab0f9ee8e88" }, + { url = "https://mirrors.aliyun.com/pypi/packages/06/ea/8667604229a10a520fcbf78b30ccc278977dcc0627beb7ea2c96b3becef0/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:511d15193cbe013619dd05414c35a7dedf2088fcee93c6bbb7c77859765bd4e8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/e6/9ed5b625c0661c4882fc8cdf302bf8e96c73c40de99c31e0b95ed37d508c/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aea1f9741b603a8d8fedb0ed5502c2bc0accbc51f43e2ad1337fe7259c2b77a5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/58/212c7b6fd51946047fb45d3733da27e2fa8f7384a13457c874186af691b1/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4019a9d473c708cf2f16415688ef0b4639e07abaa569d72f74745bbeffafa2c7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/aa/f5/a40ba78748ae8ebf4934d4b88e77b98497378bc2c24ba55ebe87a4e87057/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/a6/33b1fc0c9f7dcfcfc4a4353daa6308b3ece22496ceece348b3e7a7559a09/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2abe21d8ba64cded53a2a677e149ceb76dcf44284202d737178afe7ba540c1eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/2d/ceb3f9c12f8cfa56d34995097f6cd99da1325642c60d1b6680dd9df03ed8/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:4feb7511c29f8442cbbc28149a92093d32e815a28aa2c50d333826ad2a20fdf0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/ed/9de62c2150ca8e2e5858acf3f4f4d0d180a38feef9fdab4078bea63d8dba/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e99685fc95d386da368013e7fb4269dd39c30d99f812a8372d62f244f662709c" }, ] [[package]] name = "rsa" -version = "4.9" +version = "4.9.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "pyasn1" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/aa/65/7d973b89c4d2351d7fb232c2e452547ddfa243e93131e7cfa766da627b52/rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/49/97/fa78e3d2f65c02c8e1268b9aba606569fe97f6c8f7c2d74394553347c145/rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762" }, ] [[package]] @@ -5460,14 +5795,14 @@ wheels = [ [[package]] name = "ruamel-yaml" -version = "0.18.10" +version = "0.18.14" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ea/46/f44d8be06b85bc7c4d8c95d658be2b68f27711f279bf9dd0612a5e4794f5/ruamel.yaml-0.18.10.tar.gz", hash = "sha256:20c86ab29ac2153f80a428e1254a8adf686d3383df04490514ca3b79a362db58" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/39/87/6da0df742a4684263261c253f00edd5829e6aca970fff69e75028cccc547/ruamel.yaml-0.18.14.tar.gz", hash = "sha256:7227b76aaec364df15936730efbf7d72b30c0b79b1d578bbb8e3dcb2d81f52b7" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/c2/36/dfc1ebc0081e6d39924a2cc53654497f967a084a436bb64402dfce4254d9/ruamel.yaml-0.18.10-py3-none-any.whl", hash = "sha256:30f22513ab2301b3d2b577adc121c6471f28734d3d9728581245f1e76468b4f1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/6d/6fe4805235e193aad4aaf979160dd1f3c487c57d48b810c816e6e842171b/ruamel.yaml-0.18.14-py3-none-any.whl", hash = "sha256:710ff198bb53da66718c7db27eec4fbcc9aa6ca7204e4c1df2f282b6fe5eb6b2" }, ] [[package]] @@ -5759,14 +6094,14 @@ wheels = [ [[package]] name = "smart-open" -version = "7.1.0" +version = "7.3.0.post1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "wrapt" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/21/30/1f41c3d3b8cec82024b4b277bfd4e5b18b765ae7279eb9871fa25c503778/smart_open-7.1.0.tar.gz", hash = "sha256:a4f09f84f0f6d3637c6543aca7b5487438877a21360e7368ccf1f704789752ba" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/18/2b/5e7234c68ed5bc872ad6ae77b8a421c2ed70dcb1190b44dc1abdeed5e347/smart_open-7.3.0.post1.tar.gz", hash = "sha256:ce6a3d9bc1afbf6234ad13c010b77f8cd36d24636811e3c52c3b5160f5214d1e" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7a/18/9a8d9f01957aa1f8bbc5676d54c2e33102d247e146c1a3679d3bd5cc2e3a/smart_open-7.1.0-py3-none-any.whl", hash = "sha256:4b8489bb6058196258bafe901730c7db0dcf4f083f316e97269c66f45502055b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/08/5b/a2a3d4514c64818925f4e886d39981f1926eeb5288a4549c6b3c17ed66bb/smart_open-7.3.0.post1-py3-none-any.whl", hash = "sha256:c73661a2c24bf045c1e04e08fffc585b59af023fe783d57896f590489db66fb4" }, ] [[package]] @@ -5798,11 +6133,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.6" +version = "2.7" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4" }, ] [[package]] @@ -5967,32 +6302,32 @@ wheels = [ [[package]] name = "sse-starlette" -version = "2.2.1" +version = "3.0.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "anyio" }, - { name = "starlette" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/71/a4/80d2a11af59fe75b48230846989e93979c892d3a20016b42bb44edb9e398/sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/42/6f/22ed6e33f8a9e76ca0a412405f31abb844b779d52c5f96660766edcd737c/sse_starlette-3.0.2.tar.gz", hash = "sha256:ccd60b5765ebb3584d0de2d7a6e4f745672581de4f5005ab31c3a25d10b52b3a" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/d9/e0/5b8bd393f27f4a62461c5cf2479c75a2cc2ffa330976f9f00f5f6e4f50eb/sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ef/10/c78f463b4ef22eef8491f218f692be838282cd65480f6e423d7730dfd1fb/sse_starlette-3.0.2-py3-none-any.whl", hash = "sha256:16b7cbfddbcd4eaca11f7b586f3b8a080f1afe952c15813455b162edea619e5a" }, ] [[package]] name = "starlette" -version = "0.46.2" +version = "0.47.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "anyio" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/04/57/d062573f391d062710d4088fa1369428c38d51460ab6fedff920efef932e/starlette-0.47.2.tar.gz", hash = "sha256:6ae9aa5db235e4846decc1e7b79c4f346adf41e9777aebeb49dfd09bbd7023d8" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/1f/b876b1f83aef204198a42dc101613fefccb32258e5428b5f9259677864b4/starlette-0.47.2-py3-none-any.whl", hash = "sha256:c5847e96134e5c5371ee9fac6fdf1a67336d5815e09eb2a01fdb57a351ef915b" }, ] [[package]] name = "statsmodels" -version = "0.14.4" +version = "0.14.5" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "numpy" }, @@ -6001,26 +6336,26 @@ dependencies = [ { name = "patsy" }, { name = "scipy" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1f/3b/963a015dd8ea17e10c7b0e2f14d7c4daec903baf60a017e756b57953a4bf/statsmodels-0.14.4.tar.gz", hash = "sha256:5d69e0f39060dc72c067f9bb6e8033b6dccdb0bae101d76a7ef0bcc94e898b67" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/64/cc/8c1bf59bf8203dea1bf2ea811cfe667d7bcc6909c83d8afb02b08e30f50b/statsmodels-0.14.5.tar.gz", hash = "sha256:de260e58cccfd2ceddf835b55a357233d6ca853a1aa4f90f7553a52cc71c6ddf" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/af/2c/23bf5ad9e8a77c0c8d9750512bff89e32154dea91998114118e0e147ae67/statsmodels-0.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7a62f1fc9086e4b7ee789a6f66b3c0fc82dd8de1edda1522d30901a0aa45e42b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ba/a5/2f09ab918296e534ea5d132e90efac51ae12ff15992d77539bbfca1158fa/statsmodels-0.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46ac7ddefac0c9b7b607eed1d47d11e26fe92a1bc1f4d9af48aeed4e21e87981" }, - { url = "https://mirrors.aliyun.com/pypi/packages/93/6a/b86f8c9b799dc93e5b4a3267eb809843e6328e34248a53496b96f50d732e/statsmodels-0.14.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a337b731aa365d09bb0eab6da81446c04fde6c31976b1d8e3d3a911f0f1e07b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/44/d72c634211797ed07dd8c63ced4ae11debd7a40b24ee80e79346a526194f/statsmodels-0.14.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:631bb52159117c5da42ba94bd94859276b68cab25dc4cac86475bc24671143bc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/64/df81426924fcc48a0402534efa96cde13275629ae52f123189d16c4b75ff/statsmodels-0.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3bb2e580d382545a65f298589809af29daeb15f9da2eb252af8f79693e618abc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5c/f9/205130cceeda0eebd5a1a58c04e060c2f87a1d63cbbe37a9caa0fcb50c68/statsmodels-0.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:9729642884147ee9db67b5a06a355890663d21f76ed608a56ac2ad98b94d201a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/48/88/326f5f689e69d9c47a68a22ffdd20a6ea6410b53918f9a8e63380dfc181c/statsmodels-0.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ed7e118e6e3e02d6723a079b8c97eaadeed943fa1f7f619f7148dfc7862670f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/07/0b/9a0818be42f6689ebdc7a2277ea984d6299f0809d0e0277128df4f7dc606/statsmodels-0.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5f537f7d000de4a1708c63400755152b862cd4926bb81a86568e347c19c364b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b1/f2/91c70a3b4a3e416f76ead61b04c87bc60080d634d7fa2ab893976bdd86fa/statsmodels-0.14.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa74aaa26eaa5012b0a01deeaa8a777595d0835d3d6c7175f2ac65435a7324d2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9d/4f/a96e682f82b675e4a6f3de8ad990587d8b1fde500a630a2aabcaabee11d8/statsmodels-0.14.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e332c2d9b806083d1797231280602340c5c913f90d4caa0213a6a54679ce9331" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4b/c6/47549345d32da1530a819a3699f6f34f9f70733a245eeb29f5e05e53f362/statsmodels-0.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9c8fa28dfd75753d9cf62769ba1fecd7e73a0be187f35cc6f54076f98aa3f3f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4b/e4/f9e96896278308e17dfd4f60a84826c48117674c980234ee38f59ab28a12/statsmodels-0.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:a6087ecb0714f7c59eb24c22781491e6f1cfffb660b4740e167625ca4f052056" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f5/99/654fd41a9024643ee70b239e5ebc987bf98ce9fc2693bd550bee58136564/statsmodels-0.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5221dba7424cf4f2561b22e9081de85f5bb871228581124a0d1b572708545199" }, - { url = "https://mirrors.aliyun.com/pypi/packages/67/d8/ac30cf4cf97adaa48548be57e7cf02e894f31b45fd55bf9213358d9781c9/statsmodels-0.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:17672b30c6b98afe2b095591e32d1d66d4372f2651428e433f16a3667f19eabb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e0/77/2440d551eaf27f9c1d3650e13b3821a35ad5b21d3a19f62fb302af9203e8/statsmodels-0.14.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab5e6312213b8cfb9dca93dd46a0f4dccb856541f91d3306227c3d92f7659245" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fa/e1/60a652f18996a40a7410aeb7eb476c18da8a39792c7effe67f06883e9852/statsmodels-0.14.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbb150620b53133d6cd1c5d14c28a4f85701e6c781d9b689b53681effaa655f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/81/0c/2453eec3ac25e300847d9ed97f41156de145e507391ecb5ac989e111e525/statsmodels-0.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb695c2025d122a101c2aca66d2b78813c321b60d3a7c86bb8ec4467bb53b0f9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/59/9a/e466a1b887a1441141e52dbcc98152f013d85076576da6eed2357f2016ae/statsmodels-0.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:7f7917a51766b4e074da283c507a25048ad29a18e527207883d73535e0dc6184" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3a/2c/55b2a5d10c1a211ecab3f792021d2581bbe1c5ca0a1059f6715dddc6899d/statsmodels-0.14.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9fc2b5cdc0c95cba894849651fec1fa1511d365e3eb72b0cc75caac44077cd48" }, + { url = "https://mirrors.aliyun.com/pypi/packages/66/d9/6967475805de06691e951072d05e40e3f1c71b6221bb92401193ee19bd2a/statsmodels-0.14.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b8d96b0bbaeabd3a557c35cc7249baa9cfbc6dd305c32a9f2cbdd7f46c037e7f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/df/a8/803c280419a7312e2472969fe72cf461c1210a27770a662cbe3b5cd7c6fe/statsmodels-0.14.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:145bc39b2cb201efb6c83cc3f2163c269e63b0d4809801853dec6f440bd3bc37" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a1/25/edf20acbd670934b02cd9344e29c9a03ce040122324b3491bb075ae76b2d/statsmodels-0.14.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7c14fb2617bb819fb2532e1424e1da2b98a3419a80e95f33365a72d437d474e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/64/22/8b1e38310272e766abd6093607000a81827420a3348f09eff08a9e54cbaf/statsmodels-0.14.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1e9742d8a5ac38a3bfc4b7f4b0681903920f20cbbf466d72b1fd642033846108" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/6f/6de51f1077b7cef34611f1d6721392ea170153251b4d977efcf6d100f779/statsmodels-0.14.5-cp310-cp310-win_amd64.whl", hash = "sha256:1cab9e6fce97caf4239cdb2df375806937da5d0b7ba2699b13af33a07f438464" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/30/fd49902b30416b828de763e161c0d6e2cc04d119ae4fbdd3f3b43dc8f1be/statsmodels-0.14.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b7091a8442076c708c926de3603653a160955e80a2b6d931475b7bb8ddc02e5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ca/c1/2654541ff6f5790d01d1e5ba36405fde873f4a854f473e90b4fe56b37333/statsmodels-0.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:128872be8f3208f4446d91ea9e4261823902fc7997fee7e1a983eb62fd3b7c6e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/da/6ebb64d0db4e86c0d2d9cde89e03247702da0ab191789f7813d4f9a348da/statsmodels-0.14.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f2ad5aee04ae7196c429df2174df232c057e478c5fa63193d01c8ec9aae04d31" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/49/ac803ca093ec3845184a752a91cd84511245e1f97103b15cfe32794a3bb0/statsmodels-0.14.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f402fc793458dd6d96e099acb44cd1de1428565bf7ef3030878a8daff091f08a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/c8/ae82feb00582f4814fac5d2cb3ec32f93866b413cf5878b2fe93688ec63c/statsmodels-0.14.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:26c028832730aebfbfd4e7501694e1f9ad31ec8536e776716673f4e7afd4059a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/ac/4276459ea71aa46e2967ea283fc88ee5631c11f29a06787e16cf4aece1b8/statsmodels-0.14.5-cp311-cp311-win_amd64.whl", hash = "sha256:ec56f771d9529cdc17ed2fb2a950d100b6e83a7c5372aae8ac5bb065c474b856" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/a5/fcc4f5f16355660ce7a1742e28a43e3a9391b492fc4ff29fdd6893e81c05/statsmodels-0.14.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:37e7364a39f9aa3b51d15a208c2868b90aadb8412f868530f5cba9197cb00eaa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/6f/db0cf5efa48277ac6218d9b981c8fd5e63c4c43e0d9d65015fdc38eed0ef/statsmodels-0.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4263d7f4d0f1d5ac6eb4db22e1ee34264a14d634b9332c975c9d9109b6b46e12" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4a/93/4ddc3bc4a59c51e6a57c49df1b889882c40d9e141e855b3517f6a8de3232/statsmodels-0.14.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86224f6e36f38486e471e75759d241fe2912d8bc25ab157d54ee074c6aedbf45" }, + { url = "https://mirrors.aliyun.com/pypi/packages/66/de/dc6bf2f6e8c8eb4c5815560ebdbdf2d69a767bc0f65fde34bc086cf5b36d/statsmodels-0.14.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3dd760a6fa80cd5e0371685c697bb9c2c0e6e1f394d975e596a1e6d0bbb9372" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/4f/2d5a8d14bebdf2b03b3ea89b8c6a2c837bb406ba5b7a41add8bd303bce29/statsmodels-0.14.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6264fb00e02f858b86bd01ef2dc05055a71d4a0cc7551b9976b07b0f0e6cf24f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/df/4c/2feda3a9f0e17444a84ba5398ada6a4d2e1b8f832760048f04e2b8ea0c41/statsmodels-0.14.5-cp312-cp312-win_amd64.whl", hash = "sha256:b2ed065bfbaf8bb214c7201656df840457c2c8c65e1689e3eb09dc7440f9c61c" }, ] [[package]] @@ -6034,14 +6369,14 @@ wheels = [ [[package]] name = "sympy" -version = "1.13.1" +version = "1.14.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "mpmath" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5" }, ] [[package]] @@ -6234,19 +6569,21 @@ wheels = [ [[package]] name = "torch" -version = "2.6.0" +version = "2.7.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "filelock" }, { name = "fsspec" }, { name = "jinja2" }, - { name = "networkx" }, + { name = "networkx", version = "3.4.2", source = { registry = "https://mirrors.aliyun.com/pypi/simple" }, marker = "python_full_version < '3.11'" }, + { name = "networkx", version = "3.5", source = { registry = "https://mirrors.aliyun.com/pypi/simple" }, marker = "python_full_version >= '3.11'" }, { 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'" }, @@ -6260,18 +6597,18 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/37/81/aa9ab58ec10264c1abe62c8b73f5086c3c558885d6beecebf699f0dbeaeb/torch-2.6.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:6860df13d9911ac158f4c44031609700e1eba07916fff62e21e6ffa0a9e01961" }, - { url = "https://mirrors.aliyun.com/pypi/packages/86/86/e661e229df2f5bfc6eab4c97deb1286d598bbeff31ab0cdb99b3c0d53c6f/torch-2.6.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c4f103a49830ce4c7561ef4434cc7926e5a5fe4e5eb100c19ab36ea1e2b634ab" }, - { url = "https://mirrors.aliyun.com/pypi/packages/20/e0/5cb2f8493571f0a5a7273cd7078f191ac252a402b5fb9cb6091f14879109/torch-2.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:56eeaf2ecac90da5d9e35f7f35eb286da82673ec3c582e310a8d1631a1c02341" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e5/16/ea1b7842413a7b8a5aaa5e99e8eaf3da3183cc3ab345ad025a07ff636301/torch-2.6.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:09e06f9949e1a0518c5b09fe95295bc9661f219d9ecb6f9893e5123e10696628" }, - { url = "https://mirrors.aliyun.com/pypi/packages/78/a9/97cbbc97002fff0de394a2da2cdfa859481fdca36996d7bd845d50aa9d8d/torch-2.6.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:7979834102cd5b7a43cc64e87f2f3b14bd0e1458f06e9f88ffa386d07c7446e1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6d/fa/134ce8f8a7ea07f09588c9cc2cea0d69249efab977707cf67669431dcf5c/torch-2.6.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:ccbd0320411fe1a3b3fec7b4d3185aa7d0c52adac94480ab024b5c8f74a0bf1d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/11/c5/2370d96b31eb1841c3a0883a492c15278a6718ccad61bb6a649c80d1d9eb/torch-2.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:46763dcb051180ce1ed23d1891d9b1598e07d051ce4c9d14307029809c4d64f7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0b/fa/f33a4148c6fb46ca2a3f8de39c24d473822d5774d652b66ed9b1214da5f7/torch-2.6.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:94fc63b3b4bedd327af588696559f68c264440e2503cc9e6954019473d74ae21" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e5/35/0c52d708144c2deb595cd22819a609f78fdd699b95ff6f0ebcd456e3c7c1/torch-2.6.0-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:2bb8987f3bb1ef2675897034402373ddfc8f5ef0e156e2d8cfc47cacafdda4a9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/d6/455ab3fbb2c61c71c8842753b566012e1ed111e7a4c82e0e1c20d0c76b62/torch-2.6.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b789069020c5588c70d5c2158ac0aa23fd24a028f34a8b4fcb8fcb4d7efcf5fb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/18/cf/ae99bd066571656185be0d88ee70abc58467b76f2f7c8bfeb48735a71fe6/torch-2.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:7e1448426d0ba3620408218b50aa6ada88aeae34f7a239ba5431f6c8774b1239" }, - { url = "https://mirrors.aliyun.com/pypi/packages/81/b4/605ae4173aa37fb5aa14605d100ff31f4f5d49f617928c9f486bb3aaec08/torch-2.6.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:9a610afe216a85a8b9bc9f8365ed561535c93e804c2a317ef7fabcc5deda0989" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/27/2e06cb52adf89fe6e020963529d17ed51532fc73c1e6d1b18420ef03338c/torch-2.7.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a103b5d782af5bd119b81dbcc7ffc6fa09904c423ff8db397a1e6ea8fd71508f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0a/7c/0a5b3aee977596459ec45be2220370fde8e017f651fecc40522fd478cb1e/torch-2.7.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:fe955951bdf32d182ee8ead6c3186ad54781492bf03d547d31771a01b3d6fb7d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f9/91/3d709cfc5e15995fb3fe7a6b564ce42280d3a55676dad672205e94f34ac9/torch-2.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:885453d6fba67d9991132143bf7fa06b79b24352f4506fd4d10b309f53454162" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/f6/5da3918414e07da9866ecb9330fe6ffdebe15cb9a4c5ada7d4b6e0a6654d/torch-2.7.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:d72acfdb86cee2a32c0ce0101606f3758f0d8bb5f8f31e7920dc2809e963aa7c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/56/2eae3494e3d375533034a8e8cf0ba163363e996d85f0629441fa9d9843fe/torch-2.7.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:236f501f2e383f1cb861337bdf057712182f910f10aeaf509065d54d339e49b2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/94/34b80bd172d0072c9979708ccd279c2da2f55c3ef318eceec276ab9544a4/torch-2.7.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:06eea61f859436622e78dd0cdd51dbc8f8c6d76917a9cf0555a333f9eac31ec1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/9e/acf04ff375b0b49a45511c55d188bcea5c942da2aaf293096676110086d1/torch-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:8273145a2e0a3c6f9fd2ac36762d6ee89c26d430e612b95a99885df083b04e52" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5b/2b/d36d57c66ff031f93b4fa432e86802f84991477e522adcdffd314454326b/torch-2.7.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:aea4fc1bf433d12843eb2c6b2204861f43d8364597697074c8d38ae2507f8730" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/93/fb505a5022a2e908d81fe9a5e0aa84c86c0d5f408173be71c6018836f34e/torch-2.7.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:27ea1e518df4c9de73af7e8a720770f3628e7f667280bce2be7a16292697e3fa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/56/7e/67c3fe2b8c33f40af06326a3d6ae7776b3e3a01daa8f71d125d78594d874/torch-2.7.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c33360cfc2edd976c2633b3b66c769bdcbbf0e0b6550606d188431c81e7dd1fc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a1/37/a37495502bc7a23bf34f89584fa5a78e25bae7b8da513bc1b8f97afb7009/torch-2.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:d8bf6e1856ddd1807e79dc57e54d3335f2b62e6f316ed13ed3ecfe1fc1df3d8b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3a/60/04b77281c730bb13460628e518c52721257814ac6c298acd25757f6a175c/torch-2.7.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:787687087412c4bd68d315e39bc1223f08aae1d16a9e9771d95eabbb04ae98fb" }, ] [[package]] @@ -6322,7 +6659,7 @@ wheels = [ [[package]] name = "trio" -version = "0.29.0" +version = "0.30.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "attrs" }, @@ -6333,9 +6670,9 @@ dependencies = [ { name = "sniffio" }, { name = "sortedcontainers" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a1/47/f62e62a1a6f37909aed0bf8f5d5411e06fa03846cfcb64540cd1180ccc9f/trio-0.29.0.tar.gz", hash = "sha256:ea0d3967159fc130acb6939a0be0e558e364fee26b5deeecc893a6b08c361bdf" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/01/c1/68d582b4d3a1c1f8118e18042464bb12a7c1b75d64d75111b297687041e3/trio-0.30.0.tar.gz", hash = "sha256:0781c857c0c81f8f51e0089929a26b5bb63d57f927728a5586f7e36171f064df" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/c9/55/c4d9bea8b3d7937901958f65124123512419ab0eb73695e5f382521abbfb/trio-0.29.0-py3-none-any.whl", hash = "sha256:d8c463f1a9cc776ff63e331aba44c125f423a5a13c684307e828d930e625ba66" }, + { url = "https://mirrors.aliyun.com/pypi/packages/69/8e/3f6dfda475ecd940e786defe6df6c500734e686c9cd0a0f8ef6821e9b2f2/trio-0.30.0-py3-none-any.whl", hash = "sha256:3bf4f06b8decf8d3cf00af85f40a89824669e2d033bb32469d34840edcfc22a5" }, ] [[package]] @@ -6355,17 +6692,20 @@ wheels = [ [[package]] name = "triton" -version = "3.2.0" +version = "3.3.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "setuptools", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, +] wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/01/65/3ffa90e158a2c82f0716eee8d26a725d241549b7d7aaf7e4f44ac03ebd89/triton-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3e54983cd51875855da7c68ec05c05cf8bb08df361b1d5b69e05e40b0c9bd62" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a7/2e/757d2280d4fefe7d33af7615124e7e298ae7b8e3bc4446cdb8e88b0f9bab/triton-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8009a1fb093ee8546495e96731336a33fb8856a38e45bb4ab6affd6dbc3ba220" }, - { url = "https://mirrors.aliyun.com/pypi/packages/06/00/59500052cb1cf8cf5316be93598946bc451f14072c6ff256904428eaf03c/triton-3.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d9b215efc1c26fa7eefb9a157915c92d52e000d2bf83e5f69704047e63f125c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8d/a9/549e51e9b1b2c9b854fd761a1d23df0ba2fbc60bd0c13b489ffa518cfcb7/triton-3.3.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b74db445b1c562844d3cfad6e9679c72e93fdfb1a90a24052b03bb5c49d1242e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/21/2f/3e56ea7b58f80ff68899b1dbe810ff257c9d177d288c6b0f55bf2fe4eb50/triton-3.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b31e3aa26f8cb3cc5bf4e187bf737cbacf17311e1112b781d4a059353dfd731b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/5f/950fb373bf9c01ad4eb5a8cd5eaf32cdf9e238c02f9293557a2129b9c4ac/triton-3.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9999e83aba21e1a78c1f36f21bce621b77bcaa530277a50484a7cb4a822f6e43" }, ] [[package]] name = "typer" -version = "0.15.2" +version = "0.16.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "click" }, @@ -6373,39 +6713,51 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/8b/6f/3991f0f1c7fcb2df31aef28e0594d8d54b05393a0e4e34c65e475c2a5d41/typer-0.15.2.tar.gz", hash = "sha256:ab2fab47533a813c49fe1f16b1a370fd5819099c00b119e0633df65f22144ba5" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c5/8c/7d682431efca5fd290017663ea4588bf6f2c6aad085c7f108c5dbc316e70/typer-0.16.0.tar.gz", hash = "sha256:af377ffaee1dbe37ae9440cb4e8f11686ea5ce4e9bae01b84ae7c63b87f1dd3b" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/7f/fc/5b29fea8cee020515ca82cc68e3b8e1e34bb19a3535ad854cac9257b414c/typer-0.15.2-py3-none-any.whl", hash = "sha256:46a499c6107d645a9c13f7ee46c5d5096cae6f5fc57dd11eccbbb9ae3e44ddfc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl", hash = "sha256:1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855" }, ] [[package]] name = "types-python-dateutil" -version = "2.9.0.20241206" +version = "2.9.0.20250708" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c9/95/6bdde7607da2e1e99ec1c1672a759d42f26644bbacf939916e086db34870/types_python_dateutil-2.9.0.20250708.tar.gz", hash = "sha256:ccdbd75dab2d6c9696c350579f34cffe2c281e4c5f27a585b2a2438dd1d5c8ab" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53" }, + { url = "https://mirrors.aliyun.com/pypi/packages/72/52/43e70a8e57fefb172c22a21000b03ebcc15e47e97f5cb8495b9c2832efb4/types_python_dateutil-2.9.0.20250708-py3-none-any.whl", hash = "sha256:4d6d0cc1cc4d24a2dc3816024e502564094497b713f7befda4d5bc7a8e3fd21f" }, ] [[package]] name = "types-requests" -version = "2.32.0.20250306" +version = "2.32.4.20250611" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/09/1a/beaeff79ef9efd186566ba5f0d95b44ae21f6d31e9413bcfbef3489b6ae3/types_requests-2.32.0.20250306.tar.gz", hash = "sha256:0962352694ec5b2f95fda877ee60a159abdf84a0fc6fdace599f20acb41a03d1" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6d/7f/73b3a04a53b0fd2a911d4ec517940ecd6600630b559e4505cc7b68beb5a0/types_requests-2.32.4.20250611.tar.gz", hash = "sha256:741c8777ed6425830bf51e54d6abe245f79b4dcb9019f1622b773463946bf826" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/99/26/645d89f56004aa0ba3b96fec27793e3c7e62b40982ee069e52568922b6db/types_requests-2.32.0.20250306-py3-none-any.whl", hash = "sha256:25f2cbb5c8710b2022f8bbee7b2b66f319ef14aeea2f35d80f18c9dbf3b60a0b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/ea/0be9258c5a4fa1ba2300111aa5a0767ee6d18eb3fd20e91616c12082284d/types_requests-2.32.4.20250611-py3-none-any.whl", hash = "sha256:ad2fe5d3b0cb3c2c902c8815a70e7fb2302c4b8c1f77bdcd738192cdb3878072" }, ] [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.14.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51" }, ] [[package]] @@ -6445,20 +6797,20 @@ wheels = [ [[package]] name = "uritemplate" -version = "4.1.1" +version = "4.2.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d2/5a/4742fdba39cd02a56226815abfa72fe0aa81c33bed16ed045647d6000eba/uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/81/c0/7461b49cd25aeece13766f02ee576d1db528f1c37ce69aee300e075b485b/uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686" }, ] [[package]] name = "urllib3" -version = "2.3.0" +version = "2.5.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" }, ] [package.optional-dependencies] @@ -6468,16 +6820,16 @@ socks = [ [[package]] name = "uvicorn" -version = "0.34.1" +version = "0.35.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "click" }, { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/86/37/dd92f1f9cedb5eaf74d9999044306e06abe65344ff197864175dbbd91871/uvicorn-0.34.1.tar.gz", hash = "sha256:af981725fc4b7ffc5cb3b0e9eda6258a90c4b52cb2a83ce567ae0a7ae1757afc" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/5f/38/a5801450940a858c102a7ad9e6150146a25406a119851c993148d56ab041/uvicorn-0.34.1-py3-none-any.whl", hash = "sha256:984c3a8c7ca18ebaad15995ee7401179212c59521e67bfc390c07fa2b8d2e065" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a" }, ] [[package]] @@ -6506,7 +6858,7 @@ wheels = [ [[package]] name = "volcengine" -version = "1.0.146" +version = "1.0.194" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "google" }, @@ -6517,7 +6869,7 @@ dependencies = [ { name = "retry" }, { name = "six" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f1/67/d43c536892dbd97aaff91c78067e4e3f38207f040f63cc1bdfda790e75a3/volcengine-1.0.146.tar.gz", hash = "sha256:2810c2df9c4de0252e0aa85b653da87a81cf1f305c8caadb434f8f0abbc2fef9" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/21/6d/0b29d9bb3895990391ec1e3722f153c24f94a4f1bea2d2d4f418050fae89/volcengine-1.0.194.tar.gz", hash = "sha256:cab0ea38291ca7b2bbffe130a7b173cf6fdc4a1af61cf7792c35296d5498766c" } [[package]] name = "voyageai" @@ -6591,6 +6943,54 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526" }, ] +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57" }, + { url = "https://mirrors.aliyun.com/pypi/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065" }, + { url = "https://mirrors.aliyun.com/pypi/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215" }, + { url = "https://mirrors.aliyun.com/pypi/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04" }, + { url = "https://mirrors.aliyun.com/pypi/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f" }, +] + [[package]] name = "werkzeug" version = "3.0.6" @@ -6701,20 +7101,20 @@ wheels = [ [[package]] name = "xlrd" -version = "2.0.1" +version = "2.0.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a6/b3/19a2540d21dea5f908304375bd43f5ed7a4c28a370dc9122c565423e6b44/xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/07/5a/377161c2d3538d1990d7af382c79f3b2372e880b65de21b01b1a2b78691e/xlrd-2.0.2.tar.gz", hash = "sha256:08b5e25de58f21ce71dc7db3b3b8106c1fa776f3024c54e45b45b374e89234c9" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/a6/0c/c2a72d51fe56e08a08acc85d13013558a2d793028ae7385448a6ccdfae64/xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/62/c8d562e7766786ba6587d09c5a8ba9f718ed3fa8af7f4553e8f91c36f302/xlrd-2.0.2-py2.py3-none-any.whl", hash = "sha256:ea762c3d29f4cca48d82df517b6d89fbce4db3107f9d78713e48cd321d5c9aa9" }, ] [[package]] name = "xlsxwriter" -version = "3.2.2" +version = "3.2.5" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a1/08/26f69d1e9264e8107253018de9fc6b96f9219817d01c5f021e927384a8d1/xlsxwriter-3.2.2.tar.gz", hash = "sha256:befc7f92578a85fed261639fb6cde1fd51b79c5e854040847dde59d4317077dc" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a7/47/7704bac42ac6fe1710ae099b70e6a1e68ed173ef14792b647808c357da43/xlsxwriter-3.2.5.tar.gz", hash = "sha256:7e88469d607cdc920151c0ab3ce9cf1a83992d4b7bc730c5ffdd1a12115a7dbe" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/9b/07/df054f7413bdfff5e98f75056e4ed0977d0c8716424011fac2587864d1d3/XlsxWriter-3.2.2-py3-none-any.whl", hash = "sha256:272ce861e7fa5e82a4a6ebc24511f2cb952fde3461f6c6e1a1e81d3272db1471" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/34/a22e6664211f0c8879521328000bdcae9bf6dbafa94a923e531f6d5b3f73/xlsxwriter-3.2.5-py3-none-any.whl", hash = "sha256:4f4824234e1eaf9d95df9a8fe974585ff91d0f5e3d3f12ace5b71e443c1c6abd" }, ] [[package]] @@ -6786,82 +7186,90 @@ wheels = [ [[package]] name = "yarl" -version = "1.18.3" +version = "1.20.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b7/9d/4b94a8e6d2b51b599516a5cb88e5bc99b4d8d4583e468057eaa29d5f0918/yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/d2/98/e005bc608765a8a5569f58e650961314873c8469c333616eb40bff19ae97/yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34" }, - { url = "https://mirrors.aliyun.com/pypi/packages/df/5d/f8106b263b8ae8a866b46d9be869ac01f9b3fb7f2325f3ecb3df8003f796/yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/56/3e/d8637ddb9ba69bf851f765a3ee288676f7cf64fb3be13760c18cbc9d10bd/yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed" }, - { url = "https://mirrors.aliyun.com/pypi/packages/76/f9/d616a5c2daae281171de10fba41e1c0e2d8207166fc3547252f7d469b4e1/yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bb/b4/3ea5e7b6f08f698b3769a06054783e434f6d59857181b5c4e145de83f59b/yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/55/f1/e0fc810554877b1b67420568afff51b967baed5b53bcc983ab164eebf9c9/yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a9/42/b1753949b327b36f210899f2dd0a0947c0c74e42a32de3f8eb5c7d93edca/yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f0/6d/e87c62dc9635daefb064b56f5c97df55a2e9cc947a2b3afd4fd2f3b841c7/yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e3/ef/e2e8d1785cdcbd986f7622d7f0098205f3644546da7919c24b95790ec65a/yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fc/15/8723e22345bc160dfde68c4b3ae8b236e868f9963c74015f1bc8a614101c/yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db" }, - { url = "https://mirrors.aliyun.com/pypi/packages/86/09/bf764e974f1516efa0ae2801494a5951e959f1610dd41edbfc07e5e0f978/yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f6/4c/20a0187e3b903c97d857cf0272d687c1b08b03438968ae8ffc50fe78b0d6/yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c9/71/6244599a6e1cc4c9f73254a627234e0dad3883ece40cc33dce6265977461/yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/af/f5/e0c3efaf74566c4b4a41cb76d27097df424052a064216beccae8d303c90f/yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8a/b8/3d16209c2014c2f98a8f658850a57b716efb97930aebf1ca0d9325933731/yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/b7/2e9a5b18eb0fe24c3a0e8bae994e812ed9852ab4fd067c0107fadde0d5f0/yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/40/93/282b5f4898d8e8efaf0790ba6d10e2245d2c9f30e199d1a85cae9356098c/yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6d/9c/0a49af78df099c283ca3444560f10718fadb8a18dc8b3edf8c7bd9fd7d89/yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5a/a1/205ab51e148fdcedad189ca8dd587794c6f119882437d04c33c01a75dece/yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ed/fe/88b690b30f3f59275fb674f5f93ddd4a3ae796c2b62e5bb9ece8a4914b83/yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/07/eb/3b65499b568e01f36e847cebdc8d7ccb51fff716dbda1ae83c3cbb8ca1c9/yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca" }, - { url = "https://mirrors.aliyun.com/pypi/packages/33/46/f559dc184280b745fc76ec6b1954de2c55595f0ec0a7614238b9ebf69618/yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/af/ba/1865d85212351ad160f19fb99808acf23aab9a0f8ff31c8c9f1b4d671fc9/yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae" }, - { url = "https://mirrors.aliyun.com/pypi/packages/94/cb/5c3e975d77755d7b3d5193e92056b19d83752ea2da7ab394e22260a7b824/yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3" }, - { url = "https://mirrors.aliyun.com/pypi/packages/19/89/b77d3fd249ab52a5c40859815765d35c91425b6bb82e7427ab2f78f5ff55/yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/bd/f6b7630ba2cc06c319c3235634c582a6ab014d52311e7d7c22f9518189b5/yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/18/1a/0b4e367d5a72d1f095318344848e93ea70da728118221f84f1bf6c1e39e7/yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b5/cf/320fff4367341fb77809a2d8d7fe75b5d323a8e1b35710aafe41fdbf327b/yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/57/cf/aadba261d8b920253204085268bad5e8cdd86b50162fcb1b10c10834885a/yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/54/58/fb4cadd81acdee6dafe14abeb258f876e4dd410518099ae9a35c88d8097c/yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9a/7a/4c571597589da4cd5c14ed2a0b17ac56ec9ee7ee615013f74653169e702d/yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ae/7b/8600250b3d89b625f1121d897062f629883c2f45339623b69b1747ec65fa/yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/33/85/bd2e2729752ff4c77338e0102914897512e92496375e079ce0150a6dc306/yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ff/74/1178322cc0f10288d7eefa6e4a85d8d2e28187ccab13d5b844e8b5d7c88d/yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576" }, - { url = "https://mirrors.aliyun.com/pypi/packages/be/75/79c6acc0261e2c2ae8a1c41cf12265e91628c8c58ae91f5ff59e29c0787f/yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640" }, - { url = "https://mirrors.aliyun.com/pypi/packages/6b/32/927b2d67a412c31199e83fefdce6e645247b4fb164aa1ecb35a0f9eb2058/yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/19/e5/859fca07169d6eceeaa4fde1997c91d8abde4e9a7c018e371640c2da2b71/yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75" }, - { url = "https://mirrors.aliyun.com/pypi/packages/08/75/76b63ccd91c9e03ab213ef27ae6add2e3400e77e5cdddf8ed2dbc36e3f21/yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1a/e1/a097d5755d3ea8479a42856f51d97eeff7a3a7160593332d98f2709b3580/yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0b/42/e1b4d0e396b7987feceebe565286c27bc085bf07d61a59508cdaf2d45e63/yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7e/18/03a5834ccc9177f97ca1bbb245b93c13e58e8225276f01eedc4cc98ab820/yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/03/a713633bdde0640b0472aa197b5b86e90fbc4c5bc05b727b714cd8a40e6d/yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/eb/99/f6567e3f3bbad8fd101886ea0276c68ecb86a2b58be0f64077396cd4b95e/yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8e/a9/84717c896b2fc6cb15bd4eecd64e34a2f0a9fd6669e69170c73a8b46795a/yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1e/2e/d0f5f1bef7ee93ed17e739ec8dbcb47794af891f7d165fa6014517b48169/yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393" }, - { url = "https://mirrors.aliyun.com/pypi/packages/97/8a/568d07c5d4964da5b02621a517532adb8ec5ba181ad1687191fffeda0ab6/yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7d/e3/924c3f64b6b3077889df9a1ece1ed8947e7b61b0a933f2ec93041990a677/yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/34/45/0e055320daaabfc169b21ff6174567b2c910c45617b0d79c68d7ab349b02/yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f5/4b/a06e0ec3d155924f77835ed2d167ebd3b211a7b0853da1cf8d8414d784ef/yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16" }, + { url = "https://mirrors.aliyun.com/pypi/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004" }, + { url = "https://mirrors.aliyun.com/pypi/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77" }, ] [[package]] name = "yfinance" -version = "0.1.96" +version = "0.2.65" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ - { name = "appdirs" }, - { name = "cryptography" }, - { name = "lxml" }, + { name = "beautifulsoup4" }, + { name = "curl-cffi" }, + { name = "frozendict" }, { name = "multitasking" }, { name = "numpy" }, { name = "pandas" }, + { name = "peewee" }, + { name = "platformdirs" }, + { name = "protobuf" }, + { name = "pytz" }, { name = "requests" }, + { name = "websockets" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ab/5d/d34a65a1d9bd07b12c93ed67096c62a0b20a078e087d95f8da5ee1dca775/yfinance-0.1.96.tar.gz", hash = "sha256:f96be344330c4b04a985cb4e2a81bbe7db14499838e09f3d869ae85d989576e2" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a3/c1/2ef5acda45a71297f4be22e205359e0f93b0171f2b6ebdd681362e725686/yfinance-0.2.65.tar.gz", hash = "sha256:3d465e58c49be9d61f9862829de3e00bef6b623809f32f4efb5197b62fc60485" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/dd/bf/6f019392e8727f72dbf6ed90b34fcc571513704b041b1eb3d42941e4b091/yfinance-0.1.96-py2.py3-none-any.whl", hash = "sha256:5fd928297c9ed052f76e657694f6f1ac50ab9e154edcad80f3c262704ac81bcd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/1e/631c80e0f97aef46eb73549b9b0f60d94057294e040740f4cad0cb1f48e4/yfinance-0.2.65-py2.py3-none-any.whl", hash = "sha256:7be13abb0d80a17230bf798e9c6a324fa2bef0846684a6d4f7fa2abd21938963" }, ] [[package]] @@ -6881,11 +7289,11 @@ wheels = [ [[package]] name = "zipp" -version = "3.21.0" +version = "3.23.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e" }, ] [[package]]