From fd0bf3adf0261b96ab2cf3c53897276d46c3435b Mon Sep 17 00:00:00 2001 From: Jin Hai Date: Mon, 13 Jan 2025 18:19:01 +0800 Subject: [PATCH] Format: dos2unix (#4467) ### What problem does this PR solve? Format the code ### Type of change - [x] Refactoring Signed-off-by: Jin Hai --- agent/component/akshare.py | 112 +- agent/component/concentrator.py | 70 +- agent/component/jin10.py | 260 ++-- agent/component/tushare.py | 144 +- agent/component/wencai.py | 160 +-- agent/component/yahoofinance.py | 168 +-- agent/templates/investment_advisor.json | 1142 ++++++++-------- agent/templates/text2sql.json | 1170 ++++++++--------- .../dsl_examples/concentrator_message.json | 224 ++-- rag/svr/cache_file_svr.py | 118 +- sdk/python/ragflow_sdk/modules/base.py | 76 +- sdk/python/ragflow_sdk/modules/session.py | 146 +- 12 files changed, 1895 insertions(+), 1895 deletions(-) diff --git a/agent/component/akshare.py b/agent/component/akshare.py index c6ed2fb6f..36b3131b3 100644 --- a/agent/component/akshare.py +++ b/agent/component/akshare.py @@ -1,56 +1,56 @@ -# -# 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 akshare as ak -from agent.component.base import ComponentBase, ComponentParamBase - - -class AkShareParam(ComponentParamBase): - """ - Define the AkShare component parameters. - """ - - def __init__(self): - super().__init__() - self.top_n = 10 - - def check(self): - self.check_positive_integer(self.top_n, "Top N") - - -class AkShare(ComponentBase, ABC): - component_name = "AkShare" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = ",".join(ans["content"]) if "content" in ans else "" - if not ans: - return AkShare.be_output("") - - try: - ak_res = [] - stock_news_em_df = ak.stock_news_em(symbol=ans) - stock_news_em_df = stock_news_em_df.head(self._param.top_n) - ak_res = [{"content": '' + i["新闻标题"] + '\n 新闻内容: ' + i[ - "新闻内容"] + " \n发布时间:" + i["发布时间"] + " \n文章来源: " + i["文章来源"]} for index, i in stock_news_em_df.iterrows()] - except Exception as e: - return AkShare.be_output("**ERROR**: " + str(e)) - - if not ak_res: - return AkShare.be_output("") - - return pd.DataFrame(ak_res) +# +# 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 akshare as ak +from agent.component.base import ComponentBase, ComponentParamBase + + +class AkShareParam(ComponentParamBase): + """ + Define the AkShare component parameters. + """ + + def __init__(self): + super().__init__() + self.top_n = 10 + + def check(self): + self.check_positive_integer(self.top_n, "Top N") + + +class AkShare(ComponentBase, ABC): + component_name = "AkShare" + + def _run(self, history, **kwargs): + ans = self.get_input() + ans = ",".join(ans["content"]) if "content" in ans else "" + if not ans: + return AkShare.be_output("") + + try: + ak_res = [] + stock_news_em_df = ak.stock_news_em(symbol=ans) + stock_news_em_df = stock_news_em_df.head(self._param.top_n) + ak_res = [{"content": '' + i["新闻标题"] + '\n 新闻内容: ' + i[ + "新闻内容"] + " \n发布时间:" + i["发布时间"] + " \n文章来源: " + i["文章来源"]} for index, i in stock_news_em_df.iterrows()] + except Exception as e: + return AkShare.be_output("**ERROR**: " + str(e)) + + if not ak_res: + return AkShare.be_output("") + + return pd.DataFrame(ak_res) diff --git a/agent/component/concentrator.py b/agent/component/concentrator.py index 8ebaad507..efb9dd840 100644 --- a/agent/component/concentrator.py +++ b/agent/component/concentrator.py @@ -1,36 +1,36 @@ -# -# 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.base import ComponentBase, ComponentParamBase - - -class ConcentratorParam(ComponentParamBase): - """ - Define the Concentrator component parameters. - """ - - def __init__(self): - super().__init__() - - def check(self): - return True - - -class Concentrator(ComponentBase, ABC): - component_name = "Concentrator" - - def _run(self, history, **kwargs): +# +# 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.base import ComponentBase, ComponentParamBase + + +class ConcentratorParam(ComponentParamBase): + """ + Define the Concentrator component parameters. + """ + + def __init__(self): + super().__init__() + + def check(self): + return True + + +class Concentrator(ComponentBase, ABC): + component_name = "Concentrator" + + def _run(self, history, **kwargs): return Concentrator.be_output("") \ No newline at end of file diff --git a/agent/component/jin10.py b/agent/component/jin10.py index 9ff064da1..583a18286 100644 --- a/agent/component/jin10.py +++ b/agent/component/jin10.py @@ -1,130 +1,130 @@ -# -# 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 -from abc import ABC -import pandas as pd -import requests -from agent.component.base import ComponentBase, ComponentParamBase - - -class Jin10Param(ComponentParamBase): - """ - Define the Jin10 component parameters. - """ - - def __init__(self): - super().__init__() - self.type = "flash" - self.secret_key = "xxx" - self.flash_type = '1' - self.calendar_type = 'cj' - self.calendar_datatype = 'data' - self.symbols_type = 'GOODS' - self.symbols_datatype = 'symbols' - self.contain = "" - self.filter = "" - - def check(self): - self.check_valid_value(self.type, "Type", ['flash', 'calendar', 'symbols', 'news']) - self.check_valid_value(self.flash_type, "Flash Type", ['1', '2', '3', '4', '5']) - self.check_valid_value(self.calendar_type, "Calendar Type", ['cj', 'qh', 'hk', 'us']) - self.check_valid_value(self.calendar_datatype, "Calendar DataType", ['data', 'event', 'holiday']) - self.check_valid_value(self.symbols_type, "Symbols Type", ['GOODS', 'FOREX', 'FUTURE', 'CRYPTO']) - self.check_valid_value(self.symbols_datatype, 'Symbols DataType', ['symbols', 'quotes']) - - -class Jin10(ComponentBase, ABC): - component_name = "Jin10" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = " - ".join(ans["content"]) if "content" in ans else "" - if not ans: - return Jin10.be_output("") - - jin10_res = [] - headers = {'secret-key': self._param.secret_key} - try: - if self._param.type == "flash": - params = { - 'category': self._param.flash_type, - 'contain': self._param.contain, - 'filter': self._param.filter - } - response = requests.get( - url='https://open-data-api.jin10.com/data-api/flash?category=' + self._param.flash_type, - headers=headers, data=json.dumps(params)) - response = response.json() - for i in response['data']: - jin10_res.append({"content": i['data']['content']}) - if self._param.type == "calendar": - params = { - 'category': self._param.calendar_type - } - response = requests.get( - url='https://open-data-api.jin10.com/data-api/calendar/' + self._param.calendar_datatype + '?category=' + self._param.calendar_type, - headers=headers, data=json.dumps(params)) - - response = response.json() - jin10_res.append({"content": pd.DataFrame(response['data']).to_markdown()}) - if self._param.type == "symbols": - params = { - 'type': self._param.symbols_type - } - if self._param.symbols_datatype == "quotes": - params['codes'] = 'BTCUSD' - response = requests.get( - url='https://open-data-api.jin10.com/data-api/' + self._param.symbols_datatype + '?type=' + self._param.symbols_type, - headers=headers, data=json.dumps(params)) - response = response.json() - if self._param.symbols_datatype == "symbols": - for i in response['data']: - i['Commodity Code'] = i['c'] - i['Stock Exchange'] = i['e'] - i['Commodity Name'] = i['n'] - i['Commodity Type'] = i['t'] - del i['c'], i['e'], i['n'], i['t'] - if self._param.symbols_datatype == "quotes": - for i in response['data']: - i['Selling Price'] = i['a'] - i['Buying Price'] = i['b'] - i['Commodity Code'] = i['c'] - i['Stock Exchange'] = i['e'] - i['Highest Price'] = i['h'] - i['Yesterday’s Closing Price'] = i['hc'] - i['Lowest Price'] = i['l'] - i['Opening Price'] = i['o'] - i['Latest Price'] = i['p'] - i['Market Quote Time'] = i['t'] - del i['a'], i['b'], i['c'], i['e'], i['h'], i['hc'], i['l'], i['o'], i['p'], i['t'] - jin10_res.append({"content": pd.DataFrame(response['data']).to_markdown()}) - if self._param.type == "news": - params = { - 'contain': self._param.contain, - 'filter': self._param.filter - } - response = requests.get( - url='https://open-data-api.jin10.com/data-api/news', - headers=headers, data=json.dumps(params)) - response = response.json() - jin10_res.append({"content": pd.DataFrame(response['data']).to_markdown()}) - except Exception as e: - return Jin10.be_output("**ERROR**: " + str(e)) - - if not jin10_res: - return Jin10.be_output("") - - return pd.DataFrame(jin10_res) +# +# 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 +from abc import ABC +import pandas as pd +import requests +from agent.component.base import ComponentBase, ComponentParamBase + + +class Jin10Param(ComponentParamBase): + """ + Define the Jin10 component parameters. + """ + + def __init__(self): + super().__init__() + self.type = "flash" + self.secret_key = "xxx" + self.flash_type = '1' + self.calendar_type = 'cj' + self.calendar_datatype = 'data' + self.symbols_type = 'GOODS' + self.symbols_datatype = 'symbols' + self.contain = "" + self.filter = "" + + def check(self): + self.check_valid_value(self.type, "Type", ['flash', 'calendar', 'symbols', 'news']) + self.check_valid_value(self.flash_type, "Flash Type", ['1', '2', '3', '4', '5']) + self.check_valid_value(self.calendar_type, "Calendar Type", ['cj', 'qh', 'hk', 'us']) + self.check_valid_value(self.calendar_datatype, "Calendar DataType", ['data', 'event', 'holiday']) + self.check_valid_value(self.symbols_type, "Symbols Type", ['GOODS', 'FOREX', 'FUTURE', 'CRYPTO']) + self.check_valid_value(self.symbols_datatype, 'Symbols DataType', ['symbols', 'quotes']) + + +class Jin10(ComponentBase, ABC): + component_name = "Jin10" + + def _run(self, history, **kwargs): + ans = self.get_input() + ans = " - ".join(ans["content"]) if "content" in ans else "" + if not ans: + return Jin10.be_output("") + + jin10_res = [] + headers = {'secret-key': self._param.secret_key} + try: + if self._param.type == "flash": + params = { + 'category': self._param.flash_type, + 'contain': self._param.contain, + 'filter': self._param.filter + } + response = requests.get( + url='https://open-data-api.jin10.com/data-api/flash?category=' + self._param.flash_type, + headers=headers, data=json.dumps(params)) + response = response.json() + for i in response['data']: + jin10_res.append({"content": i['data']['content']}) + if self._param.type == "calendar": + params = { + 'category': self._param.calendar_type + } + response = requests.get( + url='https://open-data-api.jin10.com/data-api/calendar/' + self._param.calendar_datatype + '?category=' + self._param.calendar_type, + headers=headers, data=json.dumps(params)) + + response = response.json() + jin10_res.append({"content": pd.DataFrame(response['data']).to_markdown()}) + if self._param.type == "symbols": + params = { + 'type': self._param.symbols_type + } + if self._param.symbols_datatype == "quotes": + params['codes'] = 'BTCUSD' + response = requests.get( + url='https://open-data-api.jin10.com/data-api/' + self._param.symbols_datatype + '?type=' + self._param.symbols_type, + headers=headers, data=json.dumps(params)) + response = response.json() + if self._param.symbols_datatype == "symbols": + for i in response['data']: + i['Commodity Code'] = i['c'] + i['Stock Exchange'] = i['e'] + i['Commodity Name'] = i['n'] + i['Commodity Type'] = i['t'] + del i['c'], i['e'], i['n'], i['t'] + if self._param.symbols_datatype == "quotes": + for i in response['data']: + i['Selling Price'] = i['a'] + i['Buying Price'] = i['b'] + i['Commodity Code'] = i['c'] + i['Stock Exchange'] = i['e'] + i['Highest Price'] = i['h'] + i['Yesterday’s Closing Price'] = i['hc'] + i['Lowest Price'] = i['l'] + i['Opening Price'] = i['o'] + i['Latest Price'] = i['p'] + i['Market Quote Time'] = i['t'] + del i['a'], i['b'], i['c'], i['e'], i['h'], i['hc'], i['l'], i['o'], i['p'], i['t'] + jin10_res.append({"content": pd.DataFrame(response['data']).to_markdown()}) + if self._param.type == "news": + params = { + 'contain': self._param.contain, + 'filter': self._param.filter + } + response = requests.get( + url='https://open-data-api.jin10.com/data-api/news', + headers=headers, data=json.dumps(params)) + response = response.json() + jin10_res.append({"content": pd.DataFrame(response['data']).to_markdown()}) + except Exception as e: + return Jin10.be_output("**ERROR**: " + str(e)) + + if not jin10_res: + return Jin10.be_output("") + + return pd.DataFrame(jin10_res) diff --git a/agent/component/tushare.py b/agent/component/tushare.py index 236c79f63..bb9d34fe9 100644 --- a/agent/component/tushare.py +++ b/agent/component/tushare.py @@ -1,72 +1,72 @@ -# -# 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 -from abc import ABC -import pandas as pd -import time -import requests -from agent.component.base import ComponentBase, ComponentParamBase - - -class TuShareParam(ComponentParamBase): - """ - Define the TuShare component parameters. - """ - - def __init__(self): - super().__init__() - self.token = "xxx" - self.src = "eastmoney" - self.start_date = "2024-01-01 09:00:00" - self.end_date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) - self.keyword = "" - - def check(self): - self.check_valid_value(self.src, "Quick News Source", - ["sina", "wallstreetcn", "10jqka", "eastmoney", "yuncaijing", "fenghuang", "jinrongjie"]) - - -class TuShare(ComponentBase, ABC): - component_name = "TuShare" - - def _run(self, history, **kwargs): - ans = self.get_input() - ans = ",".join(ans["content"]) if "content" in ans else "" - if not ans: - return TuShare.be_output("") - - try: - tus_res = [] - params = { - "api_name": "news", - "token": self._param.token, - "params": {"src": self._param.src, "start_date": self._param.start_date, - "end_date": self._param.end_date} - } - response = requests.post(url="http://api.tushare.pro", data=json.dumps(params).encode('utf-8')) - response = response.json() - if response['code'] != 0: - return TuShare.be_output(response['msg']) - df = pd.DataFrame(response['data']['items']) - df.columns = response['data']['fields'] - tus_res.append({"content": (df[df['content'].str.contains(self._param.keyword, case=False)]).to_markdown()}) - except Exception as e: - return TuShare.be_output("**ERROR**: " + str(e)) - - if not tus_res: - return TuShare.be_output("") - - return pd.DataFrame(tus_res) +# +# 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 +from abc import ABC +import pandas as pd +import time +import requests +from agent.component.base import ComponentBase, ComponentParamBase + + +class TuShareParam(ComponentParamBase): + """ + Define the TuShare component parameters. + """ + + def __init__(self): + super().__init__() + self.token = "xxx" + self.src = "eastmoney" + self.start_date = "2024-01-01 09:00:00" + self.end_date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + self.keyword = "" + + def check(self): + self.check_valid_value(self.src, "Quick News Source", + ["sina", "wallstreetcn", "10jqka", "eastmoney", "yuncaijing", "fenghuang", "jinrongjie"]) + + +class TuShare(ComponentBase, ABC): + component_name = "TuShare" + + def _run(self, history, **kwargs): + ans = self.get_input() + ans = ",".join(ans["content"]) if "content" in ans else "" + if not ans: + return TuShare.be_output("") + + try: + tus_res = [] + params = { + "api_name": "news", + "token": self._param.token, + "params": {"src": self._param.src, "start_date": self._param.start_date, + "end_date": self._param.end_date} + } + response = requests.post(url="http://api.tushare.pro", data=json.dumps(params).encode('utf-8')) + response = response.json() + if response['code'] != 0: + return TuShare.be_output(response['msg']) + df = pd.DataFrame(response['data']['items']) + df.columns = response['data']['fields'] + tus_res.append({"content": (df[df['content'].str.contains(self._param.keyword, case=False)]).to_markdown()}) + except Exception as e: + return TuShare.be_output("**ERROR**: " + str(e)) + + if not tus_res: + return TuShare.be_output("") + + return pd.DataFrame(tus_res) diff --git a/agent/component/wencai.py b/agent/component/wencai.py index e518c54a2..8f8c35181 100644 --- a/agent/component/wencai.py +++ b/agent/component/wencai.py @@ -1,80 +1,80 @@ -# -# 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) +# +# 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/yahoofinance.py b/agent/component/yahoofinance.py index ac932bc68..f31c7aed4 100644 --- a/agent/component/yahoofinance.py +++ b/agent/component/yahoofinance.py @@ -1,84 +1,84 @@ -# -# 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) +# +# 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/investment_advisor.json b/agent/templates/investment_advisor.json index 908c5dd8a..e920aadda 100644 --- a/agent/templates/investment_advisor.json +++ b/agent/templates/investment_advisor.json @@ -1,571 +1,571 @@ -{ - "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": { - "begin": { - "obj": { - "component_name": "Begin", - "params": { - "prologue": "Hi there!" - } - }, - "downstream": [ - "Answer:NeatLandsWave" - ], - "upstream": [] - }, - "WenCai:TenParksOpen": { - "obj": { - "component_name": "WenCai", - "params": { - "query_type": "stock", - "top_n": 5 - } - }, - "downstream": [ - "Generate:RottenPianosUnite" - ], - "upstream": [ - "Answer:NeatLandsWave" - ] - }, - "AkShare:CalmHotelsKnow": { - "obj": { - "component_name": "AkShare", - "params": { - "top_n": 10 - } - }, - "downstream": [ - "Generate:RottenPianosUnite" - ], - "upstream": [ - "KeywordExtract:BreezyGoatsRead" - ] - }, - "Answer:NeatLandsWave": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": [ - "WenCai:TenParksOpen", - "KeywordExtract:BreezyGoatsRead" - ], - "upstream": [ - "begin", - "Generate:RottenPianosUnite" - ] - }, - "Generate:RottenPianosUnite": { - "obj": { - "component_name": "Generate", - "params": { - "cite": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 0, - "parameters": [ - { - "component_id": "WenCai:TenParksOpen", - "id": "d35f331b-2787-4ae7-ab81-a7ea15970843", - "key": "wencai_input" - }, - { - "component_id": "AkShare:CalmHotelsKnow", - "id": "36c4db0b-c80d-4119-a2a6-05ed9f7efbc9", - "key": "ak_input" - } - ], - "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_input}\n\n################\nContent provided by AkShare: \n{ak_input}", - "temperature": 0.1, - "top_p": 0.3 - } - }, - "downstream": [ - "Answer:NeatLandsWave" - ], - "upstream": [ - "WenCai:TenParksOpen", - "AkShare:CalmHotelsKnow" - ] - }, - "KeywordExtract:BreezyGoatsRead": { - "obj": { - "component_name": "KeywordExtract", - "params": { - "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 - } - }, - "downstream": [ - "AkShare:CalmHotelsKnow" - ], - "upstream": [ - "Answer:NeatLandsWave" - ] - } - }, - "graph": { - "nodes": [ - { - "data": { - "form": { - "prologue": "Hi there!" - }, - "label": "Begin", - "name": "Opening" - }, - "dragging": false, - "height": 44, - "id": "begin", - "position": { - "x": -521.8118264317484, - "y": -27.999467037576665 - }, - "positionAbsolute": { - "x": -521.8118264317484, - "y": -27.999467037576665 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode", - "width": 100 - }, - { - "data": { - "form": { - "query_type": "stock", - "top_n": 5 - }, - "label": "WenCai", - "name": "Wencai" - }, - "dragging": false, - "height": 44, - "id": "WenCai:TenParksOpen", - "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", - "position": { - "x": 267.17349571786156, - "y": 100.01281266803943 - }, - "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", - "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": { - "cite": true, - "frequencyPenaltyEnabled": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "maxTokensEnabled": true, - "max_tokens": 256, - "message_history_window_size": 0, - "parameter": "Precise", - "parameters": [ - { - "component_id": "WenCai:TenParksOpen", - "id": "d35f331b-2787-4ae7-ab81-a7ea15970843", - "key": "wencai_input" - }, - { - "component_id": "AkShare:CalmHotelsKnow", - "id": "36c4db0b-c80d-4119-a2a6-05ed9f7efbc9", - "key": "ak_input" - } - ], - "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_input}\n\n################\nContent provided by AkShare: \n{ak_input}", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "LLM" - }, - "dragging": false, - "height": 170, - "id": "Generate:RottenPianosUnite", - "position": { - "x": -16.477598988611703, - "y": -251.90091743639417 - }, - "positionAbsolute": { - "x": -16.477598988611703, - "y": -251.90091743639417 - }, - "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, - "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", - "position": { - "x": -17.690374759999543, - "y": 80.39964392387697 - }, - "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" - }, - "dragging": false, - "height": 162, - "id": "Note:FuzzyPoetsLearn", - "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, - "dragHandle": ".note-drag-handle" - }, - { - "data": { - "form": { - "text": "Extracts keywords based on the user's financial questions for better retrieval." - }, - "label": "Note", - "name": "N: Keywords" - }, - "dragging": false, - "height": 155, - "id": "Note:FlatBagsRun", - "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, - "dragHandle": ".note-drag-handle" - }, - { - "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" - }, - "dragging": false, - "height": 128, - "id": "Note:WarmClothsSort", - "position": { - "x": 573.7653319987893, - "y": 102.64512355369035 - }, - "positionAbsolute": { - "x": 573.7653319987893, - "y": 102.64512355369035 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 283 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 283, - "dragHandle": ".note-drag-handle" - }, - { - "data": { - "form": { - "text": "Searches by Wencai to select stocks that satisfy user mentioned conditions." - }, - "label": "Note", - "name": "N: Wencai" - }, - "dragging": false, - "height": 128, - "id": "Note:TiredReadersWash", - "position": { - "x": 571.4274792499875, - "y": -37.07105560150117 - }, - "positionAbsolute": { - "x": 571.4274792499875, - "y": -37.07105560150117 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 128, - "width": 285 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 285, - "dragHandle": ".note-drag-handle" - }, - { - "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" - }, - "dragging": false, - "height": 163, - "id": "Note:TameBoatsType", - "position": { - "x": -7.849538042569293, - "y": -427.90526378748035 - }, - "positionAbsolute": { - "x": -7.849538042569293, - "y": -427.90526378748035 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 163, - "width": 212 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 212, - "dragHandle": ".note-drag-handle" - } - ], - "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-WenCai:TenParksOpenb-Generate:RottenPianosUniteb", - "markerEnd": "logo", - "source": "WenCai:TenParksOpen", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RottenPianosUnite", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-AkShare:CalmHotelsKnowb-Generate:RottenPianosUniteb", - "markerEnd": "logo", - "source": "AkShare:CalmHotelsKnow", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RottenPianosUnite", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:RottenPianosUnitec-Answer:NeatLandsWavec", - "markerEnd": "logo", - "source": "Generate:RottenPianosUnite", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:NeatLandsWave", - "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" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} +{ + "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": { + "begin": { + "obj": { + "component_name": "Begin", + "params": { + "prologue": "Hi there!" + } + }, + "downstream": [ + "Answer:NeatLandsWave" + ], + "upstream": [] + }, + "WenCai:TenParksOpen": { + "obj": { + "component_name": "WenCai", + "params": { + "query_type": "stock", + "top_n": 5 + } + }, + "downstream": [ + "Generate:RottenPianosUnite" + ], + "upstream": [ + "Answer:NeatLandsWave" + ] + }, + "AkShare:CalmHotelsKnow": { + "obj": { + "component_name": "AkShare", + "params": { + "top_n": 10 + } + }, + "downstream": [ + "Generate:RottenPianosUnite" + ], + "upstream": [ + "KeywordExtract:BreezyGoatsRead" + ] + }, + "Answer:NeatLandsWave": { + "obj": { + "component_name": "Answer", + "params": {} + }, + "downstream": [ + "WenCai:TenParksOpen", + "KeywordExtract:BreezyGoatsRead" + ], + "upstream": [ + "begin", + "Generate:RottenPianosUnite" + ] + }, + "Generate:RottenPianosUnite": { + "obj": { + "component_name": "Generate", + "params": { + "cite": true, + "frequency_penalty": 0.7, + "llm_id": "deepseek-chat@DeepSeek", + "max_tokens": 256, + "message_history_window_size": 0, + "parameters": [ + { + "component_id": "WenCai:TenParksOpen", + "id": "d35f331b-2787-4ae7-ab81-a7ea15970843", + "key": "wencai_input" + }, + { + "component_id": "AkShare:CalmHotelsKnow", + "id": "36c4db0b-c80d-4119-a2a6-05ed9f7efbc9", + "key": "ak_input" + } + ], + "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_input}\n\n################\nContent provided by AkShare: \n{ak_input}", + "temperature": 0.1, + "top_p": 0.3 + } + }, + "downstream": [ + "Answer:NeatLandsWave" + ], + "upstream": [ + "WenCai:TenParksOpen", + "AkShare:CalmHotelsKnow" + ] + }, + "KeywordExtract:BreezyGoatsRead": { + "obj": { + "component_name": "KeywordExtract", + "params": { + "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 + } + }, + "downstream": [ + "AkShare:CalmHotelsKnow" + ], + "upstream": [ + "Answer:NeatLandsWave" + ] + } + }, + "graph": { + "nodes": [ + { + "data": { + "form": { + "prologue": "Hi there!" + }, + "label": "Begin", + "name": "Opening" + }, + "dragging": false, + "height": 44, + "id": "begin", + "position": { + "x": -521.8118264317484, + "y": -27.999467037576665 + }, + "positionAbsolute": { + "x": -521.8118264317484, + "y": -27.999467037576665 + }, + "selected": false, + "sourcePosition": "left", + "targetPosition": "right", + "type": "beginNode", + "width": 100 + }, + { + "data": { + "form": { + "query_type": "stock", + "top_n": 5 + }, + "label": "WenCai", + "name": "Wencai" + }, + "dragging": false, + "height": 44, + "id": "WenCai:TenParksOpen", + "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", + "position": { + "x": 267.17349571786156, + "y": 100.01281266803943 + }, + "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", + "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": { + "cite": true, + "frequencyPenaltyEnabled": true, + "frequency_penalty": 0.7, + "llm_id": "deepseek-chat@DeepSeek", + "maxTokensEnabled": true, + "max_tokens": 256, + "message_history_window_size": 0, + "parameter": "Precise", + "parameters": [ + { + "component_id": "WenCai:TenParksOpen", + "id": "d35f331b-2787-4ae7-ab81-a7ea15970843", + "key": "wencai_input" + }, + { + "component_id": "AkShare:CalmHotelsKnow", + "id": "36c4db0b-c80d-4119-a2a6-05ed9f7efbc9", + "key": "ak_input" + } + ], + "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_input}\n\n################\nContent provided by AkShare: \n{ak_input}", + "temperature": 0.1, + "temperatureEnabled": true, + "topPEnabled": true, + "top_p": 0.3 + }, + "label": "Generate", + "name": "LLM" + }, + "dragging": false, + "height": 170, + "id": "Generate:RottenPianosUnite", + "position": { + "x": -16.477598988611703, + "y": -251.90091743639417 + }, + "positionAbsolute": { + "x": -16.477598988611703, + "y": -251.90091743639417 + }, + "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, + "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", + "position": { + "x": -17.690374759999543, + "y": 80.39964392387697 + }, + "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" + }, + "dragging": false, + "height": 162, + "id": "Note:FuzzyPoetsLearn", + "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, + "dragHandle": ".note-drag-handle" + }, + { + "data": { + "form": { + "text": "Extracts keywords based on the user's financial questions for better retrieval." + }, + "label": "Note", + "name": "N: Keywords" + }, + "dragging": false, + "height": 155, + "id": "Note:FlatBagsRun", + "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, + "dragHandle": ".note-drag-handle" + }, + { + "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" + }, + "dragging": false, + "height": 128, + "id": "Note:WarmClothsSort", + "position": { + "x": 573.7653319987893, + "y": 102.64512355369035 + }, + "positionAbsolute": { + "x": 573.7653319987893, + "y": 102.64512355369035 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "style": { + "height": 128, + "width": 283 + }, + "targetPosition": "left", + "type": "noteNode", + "width": 283, + "dragHandle": ".note-drag-handle" + }, + { + "data": { + "form": { + "text": "Searches by Wencai to select stocks that satisfy user mentioned conditions." + }, + "label": "Note", + "name": "N: Wencai" + }, + "dragging": false, + "height": 128, + "id": "Note:TiredReadersWash", + "position": { + "x": 571.4274792499875, + "y": -37.07105560150117 + }, + "positionAbsolute": { + "x": 571.4274792499875, + "y": -37.07105560150117 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "style": { + "height": 128, + "width": 285 + }, + "targetPosition": "left", + "type": "noteNode", + "width": 285, + "dragHandle": ".note-drag-handle" + }, + { + "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" + }, + "dragging": false, + "height": 163, + "id": "Note:TameBoatsType", + "position": { + "x": -7.849538042569293, + "y": -427.90526378748035 + }, + "positionAbsolute": { + "x": -7.849538042569293, + "y": -427.90526378748035 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "style": { + "height": 163, + "width": 212 + }, + "targetPosition": "left", + "type": "noteNode", + "width": 212, + "dragHandle": ".note-drag-handle" + } + ], + "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-WenCai:TenParksOpenb-Generate:RottenPianosUniteb", + "markerEnd": "logo", + "source": "WenCai:TenParksOpen", + "sourceHandle": "b", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Generate:RottenPianosUnite", + "targetHandle": "b", + "type": "buttonEdge" + }, + { + "id": "reactflow__edge-AkShare:CalmHotelsKnowb-Generate:RottenPianosUniteb", + "markerEnd": "logo", + "source": "AkShare:CalmHotelsKnow", + "sourceHandle": "b", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Generate:RottenPianosUnite", + "targetHandle": "b", + "type": "buttonEdge" + }, + { + "id": "reactflow__edge-Generate:RottenPianosUnitec-Answer:NeatLandsWavec", + "markerEnd": "logo", + "source": "Generate:RottenPianosUnite", + "sourceHandle": "c", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Answer:NeatLandsWave", + "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" + } + ] + }, + "history": [], + "messages": [], + "path": [], + "reference": [] + }, + "avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAYAAADnRuK4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACEwAAAhMAfPPw2UAAE5xSURBVHhe7b15tC3XXR741ZnHOw/v3fvmUfMs2ZI8ISwLYwabBSYEN8RmNSE0hBWg6QR6BXcW0EPyT3qtzlrdIU1CDLEDqzGebVmyZCRkzbP05vm9O89nnqq/71dV59Y5976n93QlCOZ89+6zd+3atcevfvv327VPHccl0EMPbxMR3++hh7eFHoF62BJ6BOphS+gRqIctoUegHraEHoF62BJ6BOphS+gRqIctoUegHraEHoF62BJ6BOphS+gRqIctoUegHraEHoF62BJ6BOphS+gRqIctoUegHraEHoF62BJ6BOphS+gRqIctoUegHraEv1PfynBbDTjNBtCqAc063GaNx3W0Ggy7Td4NjqVrsUlOJAonGgOicSCWYDjB2yUBl3FOhPE9vCP4b5dAjQpQK6JVXoVTXwWqy8DaApxGgfE8rqzBLS3TraFeXkNMXHE8gdpqtVCvkzfpDCLpPrh0kVQ/kMjDjdNlhuBkBoBkP5w0/UQWiKfs2h6uDf9tEYgkcQvzcJfPwV27gEh5DigvkjBrcGol1pYEcVpkCNM2We1my8jSZLjVcimFlAmlDz8j/IhGIubbh66N6rQDt96Ek8qQTDkgO4JWegTo34nI0B44+VEgPaiM3nV84QtfwMmTJ/Hbv/3bfszfPfytE8itSLJchLt4HFg5B6cwDRTnOeVo0EUSujqJQtcgWUQYckT/3ofS2AHR9oMAIWLRU5TDLCP8iJJQsSgnPDqKLYks5s/zeZIpP4HI8F5g9ICRysm8e2T6gz/4A/zO7/wO6xaq798x/O0QiLqMu3oBWDgCLB6DU5oCCpQ2UYqIBge83kCjwUGVhFH1KDUEESBMDi+o83YY8tfTBOEgyjxJMLvO9QjFfGMxSqsYy1chJB3yw5RM2+BsvxHYdgOcwV1kX0936sbfKIHcehXu0gk4My8CyyROZYGRHM1ak3qxSEPfJIbTSZZwDUPV9YL8CKLa/nqaIByO8tLxw4+zLvDjWDLJFEUi4Usnl6TKjsIdPQTseQ8l02FPIe/B8DdDIFpLrfk3SZwX4CwdowK8xEgSpdJEQ+ThFKJKeKTxx1IIqhauoeKUzuBfECAItgmhoD/lmdTxYefW07TLIexSO2xROkWQIIliUUYkqGTvuhOt8ZuBQepKfdvhxJJ2zd9nvLsEYtauCDP1NDD7Ki2oNZuimtUGmpQ2HYNq0OjZvw8v5IhZ9r/OMFeSStwQ+TTl6N+SU4rI5zV2WYQHxkw5pfHS6mIr38L68LAe9PLXcoETTyM5cRCxkZ1eXpRArf4JYOgQIoOTTOTl/fcR7xqBXCnDM0/DnXoGEU1VUoJFHCnFGpjNlF8GRBJXxpYsJ1ZN5GgFpCtRYlXqNNsptapNCrYG9SQvzXoeGk4eiEBUkqMx+nH6iShiySiiyRgd9R3FsQxX6URGlWXl+ZmoklpzimUQHT0I9I2yyi3Oai5ikkbMz42l4Q7vgzN8gMr2sH/d3y+84wRyG1Vg7iW4F/8KkeXTHAcOdImDTqXY7lN9WIldg87BNCudCnOTynO91EBtpYraag3VlQqJQ9LQ/DZuMF1E5CAJHBJEYTnFGyH8vNW0gGAuSSj9KigrQjIl0jHEcwkkMiQW85LOYwRS+ibbESV5xg7SOhtjHE+4Kp/nWIKWCOJZEom+28fzg9SNhmi9xeJWxt8XvLMEotRxzz8KZ+55SpwyzXERhxYXT3WUYmF/MDXwIhUHulasoTJfQWm+bKRpUsrYWg4lRiIT54BxwCVFePebVJGSK0mlf8tEIIH8oDVNYXoihojZos7VqFIaVqi0U5IpLsI8Yqko4nmSiWXEqEBHUlmPEGlKliaJAzlmpmrL87OOU+GOZEikaBzuIKXROK227BDP/P3AO0Mgjo47/wZw/mE4KyfMqqqXaiGe8K4NSpHPno/4g68BrZAwhUtFlOnXObAxnktyMJP9dDlOOSk6Shqll4RSFpIDFvBC9Hje+/c/fEgiiVGKk6dj5qNmS6BIiW9QQtYKdZNyeiSSyKWQ2X89kpMkBBVot67HJpzObDnByyvca4pNpqlQpyh9cttosd1Es1/6EqXa9zm2TqBGBa2LT9HCehxOaR7uWhV1TTXqVSEYZL8USRyRp1luoDRTxOr5VSOOkOxLIjOYRLovQdJQyogwvNZmHg24/LakIdpBL9A+FUpiB+HjdhqPWDZtshzVs8lprsr619YoNSNpxAZGkRwfR3JogDoTdR5JU5NGnLYsE6uQhVQ5SaNoX9ZWuJ2R62ny0/SPf39balsikFtZAc5R6sw8xSmLespqlYPd1kI9MHcVYXoHp51mrYXSVAErp1dQmSubDpMd5h0/kuKdH+e05A2OZ2Ux1B58P9A+JizsRYR5FY6/XHoDg+0j1Y/TpXyZ/o0Cp9FVTnPNJKL9Y0hN7kRiqM+oo4VOW+A0pcvvPlWA9ZWXJImoqaM1SOV68mY4qbyX5vsQb59A5QW0znwVkblnOWVR1+EUYDmFrSuB4QhJoqjqQgVLJ5dQuFCwjs6NpZAdy1LvoLTRYHAAAkXXEIxumB2hoA42EkdgoCMdYcd+ZPfpjkx4KMlHIqvyjVIVlbU61SBKpKEJpCcnEcvR+tIOAOpPnTl5U6Nam2IaSR9Xz9cm7qQu1een+f7C2yKQW5gCTn8VWHoZTpn6Q7nG2KAjmZ2fo6YIkzqcrpZOL2Pl+BKa1DOyo2nkt2UocWJK5Ema8Fi0x4SBzvEJPgztcW9H+YH1JH54Pb59qos0oRO+T0gqSVejRGqWq6gWXDQj/Uhs24Xk2BilkR63UDcyKJ18fihvdmsilYKTpF40uBvYdQ8lUb+l/H7CNRPILc7CPfVFRBZfASoiDzsw6POgA/kficmsdsyqWnhjHmuctpK0cPonc0gPJWX9mmVsxBGCPAJfgXaYCMfrc8M5PyIcL4QSdl4TOniL+EDxFpEaRRKpEkOkbxKp7Tupq8U9EqkbTckOulPpSSJtKUnSWHBJpEMPIjK0wz///YFrIpDLacs9+UU4Cy/C0YIeLaaOPjOfIlyLd/xbO7OKhdfmaZHVTeL0TWTNXLbnXf5UZRZSgFCwc7SJ9uG7MG21g12JwodKTxeJcJqlVVYvkUyxYSTG99L8z7M9dZuCOyDTnlNddPUcEsUZtCbuAu79FCJaV/o+wdUTqLoK9/Rfwpl9hvqPRx71LqnQQaBIgndbtYWlY4tYOrJoU8Dg7jzSVJRFFj1hF0Sw9dEh1kfq8vH63HDOj7hCfPjU1RLH89qBdSgp82BLvFXxZg6xYZJoYJDNZ9tatNJ0V2knJEnVnDmF1sI5JJNRxNPUi/a9H7jrH3gb2q4BGibdeCpb3a21K6/fvbi/LVwdgdgR7umvAZcepeSpoU4CBQgTKEpTVwt086/MYfXUMhL5OAb35JHKJzqljo2CBT20w13xgh17kVdFHiGUsPOa0MHl4gUeejHtgId2mAFOwQ4NBkmjRo03x8AekmiEkWojT1LyNOdOorV0gf3DQY9GkbHHKSm0rv8IInd+kh12+af6us+qeoTTpCLfckjUpj0/tAVxnteSgZwIG420kGTeCW1JEbH+BiFT48rgvN+6RDN95kk46izedR2d6kOrww3qQ3MvzmDlxBIylDgjBweQpGmu1d6APIbLDUp3vB17ke0xbseHoKUZCTYVIaewXBjdJGmjK56HXkw74KEd9uNZjsuBdRIJxFM0ItbOoLE8xxM0DJoiz3G4yxd5zC4meXRJudqEW6vBOfYImkceZcxGkDMosT1rtRbWqg7KrQgarHujFUO1GUOtEUXTjaHRjKLKoSjVXVQaEcaDJBPh2NfdSynvIt5SArUWjwLH/hSR6gKaa1rn8ZMHHo8jPnnmRZ5TK8htT2Nodx+ivCPUoADvqOTx40x8B+eDc77HxvnVDBIQ7aAS+MEA7aiucxb2I8LxAsuXJNKydquVgpue4Kguw10ReZRPlHVY7zPVN5eKwU1m4Xzol4Gdd4JcwdT0Ik6fvoizZy+hUinTOKkiFk+gf2gQ2ycnML5tHKkMLdeoawveSeqZWjNTH8cZDiSBJJQMlCYD6m/rno4OfGdxRQK5lSW0jvxnRNdOwF2rkPUhZvtXOWyAHnJ6kmcZOSrLg7tztrsv0HeEDY1oH6qFflAIx+szOO6KDxAbjSE2wLs+VDVLok5cpZ4yLwvJjwtfGq6PH/Q8fganQkk64gU/3L4p5LErtZrdKlRZOMVIhFMMy14nkJYsWog3CkiPbEP9rp/Dq5EDePzhp/Dq8y/j2JGjWJibR6lcYt+5JAenvTQl+fg4brrtJtz7gffhnvfeje3b++Ewf4ek1ejpprZhJFnj8RhStPo429kXDbRJL0ZGaefBu4HLE0jbTs98Fc7F79D6qtpWjDZrBNWX5JHlMf/qHBZfn0d2LI3BvZI8UpY7s+0gULgtl4vnQQfn2mEGFBZhWHxiZxLxcd6SKi5ois47FP3zdVTPc8pQWo7lOvw8ArQPN8Z76IoX7HiTOtLZk/9ijdMVR5EJAgJpGo/Vi0iN78OZiR/C147U8PWvPIw3XnwJpVIR8USMBEhQsmhrrZojQjZRr7H/SZihkWEj0U/8w0/itjtuZZM4h3G6tLxJzoBI0hYSnFr78knbUq4Fzwy7KK4dB+8wLk+ghdfhHv8TONUVNNbYGZbKT0rPHk2QQEvHFzH73LQpykMH+6kkUiJpIifad2eAdvgK8frccM6PCMerCCZMTFIHoRSyY796lo6usdBA9VKdjeSx+i6ccUeW/AydWg93xQt23EUcwY83X6ShVG6uVjh4LFxxlDyxZgXJicN4oe8B/J9/+Toe/dKX0eB0l83lkEgmeRmv80lgufmFyJMkKZfKqFYqOHTDYfz8L/0ifvCjH0aEUkhxggiqe8VIxID8dDaDLKc+LTNkEy0MkFTvJDYlkEvSuEc+h8jaUbQ4ddkmMDvhN4x/WmEuzRYx9eRFG6DhwwO2FaLVWJ9LrkrqCO3D0MC0i1TAjww8W3ziOSZO7iSBxroJxACTaPqqnmfn6paUtGR6q5PEucJ+8o76rEeGwj7s2L8ufK47QkGW0SpRmS5QQshSInnSo7vw7MBH8Ad/8gye/MbXaZU5yORzakibNFeCntXV6w2sLC9RJ9qGf/zPfgU//PEfQbFYRrnMdjIL631lZWERqUlplMLg0BAlYxWj/VEM9r1ze7o3yjRp8HMvIVI4aSvNTXV+GOwcJ06zkqa8pq5WpYmB3XmSRyuyHnnUxW3yyLOgH+gerNC59qmgSEpyETWSpsvS5aOI9lPnGaQbprini6R5kd9hHnTr0UWziPRPIjY2iqiepucyZjFZUdJPpCRs0ragLl44BCOcX8fwuXBE17kI5w0nGUWkWUU6348j/ffh33zhefz1t76BPM9l8n1W1ashj6C947E4CUAyzM3O4f/5t/8O3/32d5DOpNn8CMo0xbQToq5pT2Y/x0NTW4USam5ujsZqDPMrLayK1O8QNkggtzQLHPlPcArnefdUbF5tDw7DwQawBZJn4bU59O/I0eWZhH8cEHVyuBPXw13xgh17kTYOVhSVRxIlNsTOJ1HtoaZUgkBqaI+zXeA5I2q7BT554nkgM8kRzPJQegL1N31NSPt6qpxWOBW0CiW4vHMV50kllmO3kzK1zNZhUX5k+JyFQxFB0BpDqM61OuLFElbH78fvPwF87o//K9LRJlJpDnq73tcG1Ve7HpYXl3HdDdfjf/5fP4td+/Zjdm6JNzyV66B8HzrSMEepVff3DyHmNLBnexLpJCX3FtEpgbSKOv8KnPIlNtzfshAGK6aV5fJsySyuVF+SJnuGuXjk8dJ4nqEdZqA73o69yI72MptojtJlPEESxYxM0Szv4hQlEK0LI5URS2QKXxiQZwBI6ztcrBfvOUdrMAnqF9k0ogN5xMZHEN8zicShvYgf2ofY5DiQSvBStj3QVwIobJWj8702gngLrwfDjdFe60SCN9WOA/j6pX58+SuPIk7FdyvkEUQGfWMk35fH0SNH8Gd/8nkq2mVkKIm0YKtZQ37g7Jjl1UjmldUV6PHl1ELZFPOtopNAetY19wLHomEb1ruhfcf6hujS8WUq/030TWZt9VkWl+7QDua3gwyEotfhRbYvkW/OjyAXzGlQpZTLN6e40HlGWUBaY3yQkmcHGZhiPBMpTtLHJBAlUUNhL95hvaODVF73TCB53V7Eto2YnuRqahOsGmqVHwxj03YSYfIw6LCikXgc56N78eePvI6VuWkb5M6L3h5EojjzTlL5/qtHH8cLTz+LfD5lepK3Yt1JIjmRVgp3rVrD8hol2NrWp7I2gSRB3KUjiOhbolVWYIP04T+nkuKlAt0qsiNp23J6TdOWwnbsRXaQx+AHVHTg3gqmRNAlhjzyRKjnaNqy+nc5xYlUrLOnBzEdj7WnObF3EvG9E9SpaKXYnemRxz7a9SOukjwqLkoSN9MjePRoA6+8/DoFnfY9SWFW/qzHVUF1V1r5cusQiWSury6v4ttfe5hWWhFpSrfNyNN21ItKhQJzilAfqnOG3SgorgXrEqi+BnfxNRoEJI9ZUuHe4RGnjAaJtXx62Z635MZTWmrpblNXp/q+0Jldxzh42BDx1tBAiBRJSo+cJE+ckYxTVma7EzpvZLKDLkewU00y8Tg2Moj47m02pRmJuqsUPr5MddejW4hSgV5ytuOx586juLrKwWb9eBc6uhMd6R/qwMtkpHOUJk6EuqDv7KvV1unrwyaJE+M0/eqLL+P4G8eQy3G65kzhKdCSOl2O19QooZZpXS+sNrC8RYV6vSaFc3DWzsLh1LSp9OGIl2ZKtg1VG8JkdQVj0Ea7L+wCP0xYUB+ea58KovTRDl8l7C4m+rYDehlChjoP9SSk2MlpOq2cZehr3V+bwkSU8J2sNlo75dPT1EXSSE+Kbx/ldMZBlrQKYJX2Kxiup+L9Bq0n0aMFZprJ4ehqFm+emEI8Rp0uqXWyQUQpLSOxPF2GTusyLKsN9g+J4kSTvB/yJOEgheoI3RCv097srJ33iKQyHVpmcSzOL+CVF14wvT1BZTl4Y4nUCzk7Jqlq9DV1nT1PI2i5jqn56kZL+xrg1YKD4eqZV6tsHSmmhiFlVaurxXNrvMBBZjhtFdfM0YbXhwQD7TARDhN+X4fQncB3V4LIow5MjaJWyKB4ZAarL53G6gtnsfLCGay8eA6F1y6idHoOtVW2SSuwIpUKD0jTRnBMZ9MbTeUhDlxfxksqhOtzmbp1RPPCKA2LZnIAb15sYHGhgGRmGPEMp8jEHqpy+ziY29GqkQxIkkQkeTsHESjOdDn6g0w3yewO0x1keJwEyVN/ox4lKeZDjzyaJP/R14+guLaGJI0GjaEePYkcnlJNK5SjVyzV8eJTf42//OP/G9/52hdx6twiVovhgbw2RD9LuNVF4PyjiNSX7Ws2XfyxClaXylh6cwGp/jiyY7zbw2k6Orirh9uHIckjhOI7rieiOSq4eQ640FUXjzy8IDeBVnQUc995AwuPv0ayzNBNm18+PUuf7uQMiiLRUhHRNCUAlUxPCCnToNPkBxVgvM5pCqjSCqWpb3X273ZDkFQn/AbZZxDvI87qV1Lb8RfPN/HK6xcpjMYpTQ5Tcb8D299/O8bfexBOMoXy1BybVGNWbJfaFo2ZZEKrn3Xeh5F73ofJH7gXQzcfpjWZ5wywCrfGekW1B53pCd3MWmCMRKK4+773ID8whNW1kpFGLRWZNNVJcr3+4oskzx/izRefxbkTR9A3OIp9Bw9idIhTn+V2bbCecdYuUnGepwj3xF4Y9k0FRhVpuuuhaWaImj6nBJtNVWLQe6EONdg5+7AGtk+F4s3fLL4d2QXrMEke6SnbTDS7ZU6pNPmHDuQxfLAfI4f7zR/cm0Mf41ORGmrHzmHpsddROjsPN8a87em58iN5rLkikcIWaUW42tukx+TqD/VSu2q63qtfcNiurn/Ons6ThGu1OC7NF9hfnKoS+6ljfQg3fPpBfOBffAD3/tZDuOf3fg4TH3uA1aDEUDm6nNm4jRhi/ZM4/Jkfxvt+9yO4/9fvwL2/8R7c/69+DAc+9TFEM6NmJwTlytOT+dWVZSzMzbWfeQWKswgkqVYqFvHCE49hYXYG/UPDqJQreP7Jx3Di5BlwaN8WPHYULjCg9w6qI7vA2ukbouXZon23PE7dp73mY/BbHUBhO/Yi/b4OxfvYEPYjutMFMMlDsZ2mzpMYVwTrUUcsl6D+3I/8ZB8y41mkRugoITPjOYvvPzCIoeuGkU41UTszhWaxwnxYQKBkq/0ijh3qg+eYr4MCGpUqB0DxPtqN8YPtw44DL8gbr1iPYXmV0iUyQGlzKyYfuBW3/UQOQyOcuJIRbDswiut/+ceRv/4gmtoeTEJ7z86y2PuJ9+O2T9+N8V1ppKgm6cuv2/b14dZ/8kHs+NH72XaOg406+4GVEYGqlRpWlpYtThXU1CXyGDd5vLQwj0sXziFOy016k56/zU1P4cK5c1SsNxn7qwBlNUWhTHcOkPc1lRCsI6i1F6qordSQ7GPBem+O19sEE4T6bR1eZKi/fSii6xoLr0eET7Xh0kqS1aK9NtR7PAnimZ/qIHWk97IFrTbT0W9yKtZala1R0fpJjWWRjPM6TktGGO/qTqepSi/wrCzCaZX8PFpsB+NDjelsFw90HMSZzw8SSBu9KlVNI6OIj+zHnvvi6KP6EvSy/MH94xh7361ME2HRDSsvu3cn9n78LqSz1G28pJatwpm+JHZ/4l6kJrfZNOuRX/WPUOdpmJSx5hCyxAJlWo8PK8VVVEqc/jSrEPJrNZJucZnX+hddIyJurUATfsla0z19URizMg6qyzWOV4sEIusV5Z+1VgVQ2I69yHYnd8UHnqErfiPhCCMPzWqRJznMY1bUyKNaBPX1Lw6ulx+EmUQ3hin8egyiRUUjYOC8ZHZ9q8q7hfqgW7RTkrw2a4by25Q8ATrO8Xpm4hWRQXIwyynVi1cyDaF8GYjZ3VSOtRpuC50uciRVZtcQ1EpB6YKs1Yzs7u3I7mJ/WP5eA+w8ww3lIUnGsdR4amOZ6UJMZnX30xtUN8tDjz9C8deAiKtXr+g9hV3kMbCVqkh1uWx7fBI0i71K0AUtEsJhorOTQ7hcPNE+ZQF9sBA9XnAkv3d4C4WaT2xEfagzgrpsmjcjg3NKqrSyc9udKJ/OJA/JU2VfNCmheGc2y000iuxYpdf1hO/56Dxax3p6beLSIwe4VUYxf8Z3ldyuk6xb76RWyaljqkp25EWHfdXPlhkUY9d4nuqq512a0ow4zFzD2hCZGO7r70cyneKYWi68pkVlP47RkUFKZ+b5NkAZq1fnasuDx9IwJIE0DTQK1DVSUdj3w1V2mCEW1Ifn2qeCqCAQxAsWtR6/nl1woI7hnRQVeSZJnn4eizhyqiQrYZX1KyyxKMizoB/wowU969JdHslyDtG11hCBiUQaWaJN9gMtGZeDXp6uoFWh4Utdxc8tlB8D7Ujft7AfL7CMVMylSc1gY5HdfB6FRUoInpKTDuz5DiqzS5y+SDIjBVA6N43yIqWgnV93Sq9al+cWUJ2i2kF4BopWtyXNYsho7w/Dmr7MdGc7Fa7X6hgdG8PE5KTpSk1KKj3SGBwewv4De5HUdpe3gUik5r1uzp4zBY33oXHRPKv9zrFU3NuBuD7aG9KHT3nwIy4XT2w4JWhwIxzoNMkT72OviTjqOtbRBt9SEQoEbhMore423gROPIH4tiFmqxENk6dMCawpXBKCA8ibpFlsoHCCRkM6znb7ywlt8JpwpdvhrnjWN5toYEB7b1wS6OLLuPTcOZRZtFojMqjWxaUC5p99BXpZeoTKrfp49c0TuPTI80Ya1TQgkK7TxvmpR59H8fRZmvusm6/P2L4fjtHA4IDpPTW22aYnSh9JnFKpimy+Dx988AHqVmnMTM/a1o/7PngfrrtxX2fVrwERV/qPX1AH/BylnEr/kQTyhMPmg9VBnsuFhSuls3mYXRYNyJNneWHJE0BhOibViw6Ct2aonmYIKCwn8rCDI/0ZJHaPITrk5xdk1aDCKcnDKcbuFhoILuuw/OISavM1ZCe1t1t3d7jszdDVSHWGdJlEHdvHcsyzQFK+ibNfeQTHv0MSkT0iRmGtglN/+k0sPvMSogm9Qd+T8s3iMk780Rdx8usvoFystQlUZPqTX3wCp//TFykdqQzra9MsSvVrUrfrI3mGR0dR1U0vY8K6QroQr6eyvLBcwP0PfBCf/qVP4/a7bsNPfeqT+MlP/SSGBtnfbxPRf/kLH/qsU5n3BqGrn/T0vbpUoTgvIDOUtDvSOtMGWym8wEby+Ak64nW8Hm+H3pn1eOVNFx3SJjBaW8YQOSUKKiefjjeerK/awpq9fMoWCWmaqlMjnDci2RRiAznExgYQG6fkyWtxLiAPy2qSPDXpfhwa7UGWpKEOsfzyMua/t4C+nX3o360NX0H5qrCcwt6hF/bjgnhCUz+1KESzGZwuDuGp50+xnCJaK0uYf/0CSitrWJmex8k/+zbO/gnJQMJI7/FoxWupj9RmFzH//HGsTa9SSpUx98ZZnPzCt3Hyj/4Clalztr1FX24UtApdJUFuuvkmPPixj2Kl0MDyStHr1hCKRX3TI4b33n83HnjoAfzAQx9hWSkknRbSGyTt1cFpPvm7boQEanGOtGdg3r91giznlVPLWH59HkN780jkvC8IevBq11FJC/sRXZUPJ+y8JnTA8u1bC7t22DYL61BNrd4I+vA6TXFaM2lWKfoZ1uzjpWJYeZL8pgAHz8HYyd5pHos8VUperf7yzgf1nGahicXnF7HwzKKttI/eMWoDqUc4hnA920EGQtFCkCxCHS460Icnlm/Gr//rJzF78SJyuTz7WbWlpGGxzdIKE2rqYrVkHfqwZ2Hs/AZ1MLTiiFKvEVkapQLbSV1OktIkqdemer1u+synf+kz+OlP/yO8fmyKBCrY5vxw9aRYa6YZHu7DtvFBdgmlc6uCu24cReptbi6jFbZi08CGB6gCo9SBsiS0ZuDpqvrwpE67Ty3Ki/dPewjiza0HDeEDeRZkgbbmwo5rSx4RRgH5fpwvqZQ0lk9SuqTgpOlTv9F2DEkh28modNquEJBH0JtiZapTQrhkXa3UxOobq7j45QuYf2oe2e1ZjN5GCZjUC6VU2Gb19OP8aMFrjiK8c3ru5JQLODxQxnUHtnEKKaGu9aXIMvOdplQ5jkpjjjeppt1Q/Qgp/C3qZNGEyFIi0aaoh84yXKUTCSg1ffIIUpCHR4Zw652325cXV9fKds9IiRZpAhfUbWZ2BW8cncb5C/MYH069bfIIEb3LcNOnsX7nmG7Eu9vb/edFWj9ZwHdB4iBeCMcT4VPrGRDtIANiRAdUL9/5pGkTyo4ZFkHktLenHRZp6ExZVjq/kDrJU9dKLeOpgNZX61j43jymvjaF6qUaRm4awRglj16p16rxOtUzqF9HPf0gYUns2I8PzrEtsmCHI9P4wF07kMpmOdC07Jo19mcTJVpm04vHWU1aX+H+MHjtc20NjDewLOCEBkFN8tvkw0jC9t50283Yf/1hzMytmA6k7tFs0elkaetNajGk0xmMDKaoo2X9nN4edJuuN3oz6LTIYwRi+HJpr5THlc4FaKdR54SdPN/vOA7HBWGh+5wyFtFW6ThlGKnYbHaoXveb302Jc+8IJh+YwMCBAZ7xdl1ujqtpiA92VMvh9EP14MM3JKmfXMeB1QCqK6PIZ8cwNrSHOj4lXbt93fDLC26ATVCrVpHv66Pu8xCnxTSmZlbaU5UU6G6n5kdjCej7BYeo4+VklW4B3i1/hfpr85j3Z33iwQ5CgSBeUCJL6MXbYTjezunYd0EiH+306tTABaSw4/AdGIoPwuE4CzJ9g+SpkTwiUiDleF4Eyu3PY+ieIWQOpWit6RJepCJUibDTRztMT4fteDmL9qAw41xXjyfq2J2+iJ/84duRGRxBuaxHKQ6SiSxJNMJkqo8qeo1gGdq6Wq1U8b4H3o+73vsenLuwgEKxYtXZKH08p26JJZLIkDjZjPYibQ0RLZp5HdGFoE0yY3WwoY3+RZtd6+Oyp8InusN0KnG9QN9vkyQAw4qj2WsWlOZxinpzphjT19Te0tvx6awcnzwBlB2nGVAy6CDa7yC+jTKIBpuRqA2r1CbYJN6O/UgW1ySJImsX8CM3u/joxz6EWjNqX7PRg1Ot3bxdaHPY2uoa9h86gJ/+uZ+x525nz9Oa9m8c+d3OEI1h6sIZnDp+Ei8dW8GRMyv2pcW3CzPjo5prgwJ8qAukONf1ou/FMlIDVFL1INWS+R0U7jy7YD2ig5TdDA0Ow/EM2hHzj/TlOJg57yBQ/ryCfTDsP8+qrZRZvxI5UrWXfMpvlmqchqQTrfFKmrMykTUFX2EqCLLnrMN28rBBGteZPqhj6FIvamO8F+6KZ2JZWNnICvZcfxuOziU4eCd4X3qb4sOtuhrYqjP7ZG1lDcNjw/jV3/o13HjHnXjhlbNYXS3T+PRuEg1n4CR5dF0yk8Pi7Ay++V//I5557FuIp/to4Y2T5w4G+2mA+GrKtSD6v/zyxz4L/QqgHjj6kQHUUXqdS3WubE/io0agrg4SrEfX4+0wQPignawrkQ7lWwUc2w0YJYksonvKCogek67SxNzjJ7Dw5CkUjs+icFRujuE5FI/Po3hmAZVZKq68P2RVSRk1BNl1QcaETdckXISOFq4niUKCy6u2X2EL+wjiQ57BLmDZ1TWM5avYddN9OD7j4vTJkzQ2G4gnaDF2dNjmUBq5Bm+MlZUV+578//Abv4If+KGH8PJrF3Dh0qJt6RC6yROh1EmmRZ5pPP6lL+D4ay9geWEeF8+ewq6DN6AVG4C+SzDYd+1TWvR3/9lPfxblebNcNvSr+EJrpDRXRCIdR5xThaXp6KD2h6GjL8IHV4j3jtbj9K5lORvpgDBWcuAIdpYes5RInCTbnR3P2G4Be0G53mgvsrcoQVcaKJ8vozxTMVLEBxI2EEE2YQTCTnek1sCstKqdsip71VbAojwoHMSHPMEGXRH0W1ScI+UF7Bqq48AdH8BsJYfTp8+gvLZqUiOiNZtA39R1XU6LhdqqUSwUbNqS5Hngh34Ir7x5EcdPz1B6aKnFn/zZZ8GaXpydk0imMX3uFB774n/BsddetO+laSN+i3nuPXQjxnbsxcJiESPsmwzH+VoQ/d3f+PRnUToPRwQiW9tgUPqdBEBlrsQG6ml8gtGhNOGOE9RXfpCt9gM+1k+EwkT7cD3SI1AggYLyFPaDCrA+2j9TnVpBdiyF3I4+JPqTSA6kkKR5mhpJIzOaQXZbFqnBtPewXSRKkET9uuu9bMJQG70/gh863SpRKtmvvyjWr6PvGYLEIc/AsJ+TF8/rW5JExRnsHKzgtvs/hNjoQcwsFGwXYbVcpNnfIIm9h6CypBo81n6dcrFE5buMHPvkwx99EL/6P/5T3HTnPZy2zuHYyWkjj/1wjCnJnotGYrzp2W7OLMdfeZ6S5/M4d/JNSiIpeBzTUgEHbroVd7zvASNeUT+9RSttWP2nJYOrhNM6+6jrnP8KQOugIYUyGCd+aHVXX/FZfHme2nYT+Ql9VVgV1JV2uT46uXI54mwS78W0AyxTebcQnxxFfMeYHWtq9Wvk+344FuXMW8HiE6eQYp8YSXQD6LSfn+5c6T5aVJRqoE1xemaU3p9CLMvGscM6oOuCKAmwhovqhRoiLeoHtNjs5gnOB3VuF+Z5gpUbIBS0PmD7YpEmnOQYlqM34ZnCdnz7+TN48bmXMXX2LCXSEiVr2fpBUknf8xodHcH1N12P+x/4AG69+24Uqw5eeuUMZufXEOdULgKJNCo3Sr0qnkjZ9QszF/HGc0/gzeeeRImSLp3LoUGrsFhcw+59h/Ajn/oFTO49gArHPpPtQ76/DzvG+rB9AJgYTbanxCvBaU2/5OLY5+DUS2hS31H/WB/xw/qBeSwfW0J9voT+XZQKPNar3dpgMNxH3kU+2sGuRO3DrngjEMXu5IiRyA5sXrEaeb7iBO1Z7iaQzgVJw3kzTtJUHa27OzbMO7aPJ5W2nb4LOk1Ft3iGilAxisQg58kgf8vXzzwoQ2C4LXWEjnNBeg50kgN5aR7O3AJiu27C8thdONUcx8nFFs7PFcy6SlABy2dTGBodxfjEdirM28yCO3VuHqfPzlAyNTl1x61NWkvSPiARrlGvYWluCmfefBknXn0OcxfPMT5ipBJR9EriQzffjgc/8dOYJIm0Q1FbXJfnZ3H+5AmMjE3g4PXX4ebrhnFoV1/HcG4Gp7Vy3nXf/EPvFXbFaruPvI6iAkaG64dQCicWva8ySw/SnWud5aO7lPUToTDhhztEe9iXdKMX3z7sEUhHgakbEMernSnRjWKdBDrpEWgoLIHWC+2omn8uOhBBTL+lq2M/uw3gdS6ntOLZIurTLeS2572bx+rhZxrOm+EN7QoQrgQlIkig6oVFtGbnEHVr1FNSiA5OojG4F4XcTswm9mA6tgONSJqDH0OZut7c/ArdKqrVuv0kp15t5/00lp68Vym5VjBPiTN16igunj5GJXmaErTB6+O2S1HKt950dtf7P4R7PvQg+odGqE+VbG/07KXz+NLn/gOKy/O449778OCPfxKjE9twcCKNbVQFJOUuB6dVWXVx9I/grJ6wV7PZYpPO+B9653O90MDSa3NI69dzaI2ZuNTpAOEOCp/YJN7z+NmRzv9gvsrbI9AI41iJQAK1K2UBbwrjnbr45Bl7uZU3hflasI8gWw/K3wtFBxzEhvxjP24DWHd9g6N4uoDK2Rr6dg/QOuNUIZLaec8zMPyWksfAfuPd3kIK1ZOX9NZN0+Wo/FAHLZOfnL4pUU5lbsK3Ix/E9148joXpefQNDVP/pC6X0mBKu29RAlVQLfHGXl3G2tIcVihB1pZpdXJ68t7QIWnL8pjf8NgYbrz9Ttx+7/uxc/8hq1NhTUsc3hrgU498jdJ8AT/4sY9ibFJfD48jkdB31hz00zCZGE7aY4/N4LSadRcn/gzO/PcAEki/lmxd5H9IRGpgF99coBLR8L4TZmswOk90dBARHHbFrx8yED5lYT9CBOKfNn7FJ/1fADQdSFCBDNsyguajChpLC1h8eh6p/gwlUKotgcJZeuCBjv06x0co9vXTFeHZsRussAhUOLaG0tkqBg4Osl+jbekb4LL6jhCcC+LZvgiJUF9ronb6IqOVF9uidKx7RBv6Ofgv5d+PVxK3468e/jYe+erXKW2iVKD7KHmo/EuCMa2ssmZDOp2+ONBk1nom5u1AjCeSln5i1y5cd/OtuP7W27Btxx7qRwlbxJRCrrTqx3iU6d0CDh3ej9zAEArFMtbWirZrMRpPs7vj5HgLu8eT2DOR26AX2fuB3AvfhXvq/0OE86fehWh9GnywvlJCSxcLdKvI01y2hTm72YOeIdpBXeAHBT+8qXi3cCg+kEABgVQHm8KsMr7HhNp6ilXeNWUsPrtKCRQQSARjinAZSh8cMysnTWtylBFapfaz3RSUDNpbvPTyEmozDQxdP2L94D3M9GFZhwoLBTf2DQuTQp8eQO3CEhqcvmzHQHARBz7aaqAUy+PpkY9jPrkLxYUZPPmdx/Hy889jdWWV5NXNTanCS/T9ei38Sf+xnRLMfmBoCHsPHsCu/fvpH8L2XbuR6x+0Pq3otz4qeteirDzXdiOq6P27hrFjYsisvmq5ggp1q5LW/qhs1ylbmtR340kZTw0c3pXFgZ39Hol9eARaPum9VEp6UMnf2mGd6/WwvVih1MTKkQWk8/plP/+LcAHW81PL/AChhvrBjR0q+IHgOEwgNsrK90nhgQlbJe/BKO8cbXpffFbvKSKBKGI7BtcQKlOn4uQNp65oTvl40ZcF26y9xHOPywKNY+iGYVaDf367r0nyCLzMSWoZJMPp6zxcvZJO0t2Hfo9V71CczR7CSxM/iQKSiFEiVas1XDp/ERfOnsPi/DxKpbLt/VEtRBxB223GJiZwz/33Y/91hzn98GZiAr15o8K09ao3syhOG+z1DK1GnWh4MIeDe0eRpGQ1LrPvVws1rOj3QLSrke3XO4VEpHgqb9Lq1sOD2LWN+qAP7w1ljRLcN/8YzvJraFExte0dqqH3wX5gT7CAtTMr9q5oTWO6zD+tBD4YCHda+3BjvIeueCMQx3nbIAnka7mBqa1B0RZUkUd7YWSFFRtY+N4Sp7As0pRAEuPtOiljhm3Go4vQiJLuE83w4K3IIySjqMyUMf3tWQzsG0Jud972B1m7mcWmElW4LLFcErcPtYUaamc5fdnYryegLmFT2LntP4iTEz9sW1BbVVrGKo9oNOqoUYKUKUk0BVUY1nSkodL7Eg9ed71921Q7E+tUtOtUN+w1d0ygKc6exos8dFWe069CHto7ggFO/5lUFClOk8VyHUsc31USSFaevSpPa20Ma40omckjl47gvltH0Z/zVq09CuuFTIOHGaBZuInGrTtPbU2MZFhh3pmVhncHqv3mFPaPhfbhxngv7AeCeIHplKeSm44l+J6l0+OWgDxe71u6aIomeYKiXGtfiqazH3vhNOuwWbE8RfAI3RjTiTxBnleCpiomXaH+g4aD1DAz4nXqB6tjUHHfa8MqL993gh/nUH9pUao0loMtJZ1wXN7xHIf64D4aaXmk0zQM0ml7JYyXndoo6yuKRIo6DtPs2LUTd95zN26/5x70DQygTJNc05D2BxnRN4EZSTwn4uSyKSRoGOS0+sx+U61U3bbTBQxoBiIN7f1Dc0sVHD+74s1ShDcSGpD+A2jp9XC8s/02r0Odx4L1Spd4f8r/iScW151O2CxO6I4PH29SnokiA32Rp0bymBLjVVlvLdPb0fpv6kd6TxJRWv3xUSqFJEqMOk58jG6cYZInShLp0YT1UJDt5aD5naQs0XzXTsWsfmFow9e5iQ3t6Y4QvDh1v5POeu+cpIJqOkRHeuYtczwzgtbIQaRpbWVSKaQy2i2YRJJhvYlMm8AGhwaxc9cO3HDLTbjl9tuxc/cu5hfhlKMlGOazWTU6wOmI/TbIcZSfS8UpjTwdSi3UtG0B5SPyyClb+pKCwqkLq1hc9n6m1B8NJsiOwxm+Dq4UM29C9E4EsEyAtEmhiH2N2KTQJjX2Yvi58RSxWbzuLx8WUGG+b5KHksBGv11dg8qPD9BKyNMcTbHelDDmqCjr+4hGGkGXyl0Jaq4GNhNFdbaCmcdmEKPOkt/Xb3XR4IRq2QnrBx/hJApT2nhvh02gMaPvnvEmCOk+Bpt6qdj27UJkYILkiZMsHmGylDQDlC6j42PYRbLoOdieffswMjZi0kjEkcSxorzcrghJIL1cM0sJpy8TBi/a1LXSk4JfI/DG1kcQVB1rFZTKLs5NrVmfrLckkoAzdDPFt94kscmzEJYgJTWW4V0+kEadmRhtlbnvVKZ1shfwIN/CXfECj43hQRo5zR2KUN4ijvbyWDldnR5AuwelJwUk6XY8dUXovJwevmZiKE+VMfWNS9T1mhi5bdR+V16me5s8QT0Fa8/l403y8PaV9GksUZ9ZXfUtr07YTxZwiqsO7mc9MvZKa0mdbC7LqakPg8ODGBoesnCSZJQ01D5omfDXgmBaS6cSnLpi9so9++l01lMWrH2XjIdauvGkjpza4LVevLdlA4YvzpZsgbOzNX17gfwhuGykvW6/GxLjvFvStJKcbL8vhVgIT8nZpxfwYGH/bHe8X6mOeB2YicgqahehpI/arELeaXh9yXmPXZCNmeRdfW0FF//yImpLDYzfsx2ZbZS2IqjVwXcBgjp1xDPgx9M6sb5yqMe4rQTq0zTblVG39FEc0zUTedQG99rSgR67atA0BvbNCoY1+A1KGg1gQIRQwVcFXSZypCnh4hxj6T+BSV6nStAgiYKXuFtTLH/WV57VgQGmaTbrWFzVizqrXQSKp+GM30UCZWm1eBVvQ6WrLyO8Q/L9SG3fRo2E5jznbi8ZP0LJvbAfEY43bEIehZmRsV3rPLK41LnhOmwVykodRiXbdi5yutJgFM8UMfX1S7hEx1sH2++fRG5Xn/etjG7dR7hcnfxoz+OdyylG6z716SVat7wZNpCH0KDSAmvltqOen+QAqpO9MlW3sNsqrNrMh2YQq8LpX6KOx62WliyYP/+t/5nORkj/nuc5P2Bfi6bwmF/S6nk3hg7BGbiOZIrZFgEPXuUdilf9cKwepsZzVL5GRlkwB0LrL0FSv5B2RBAv2LnLkMePsH6Sgq4pxban0peU0OKlBj5wEr1y/N8Uykf11/VJPy/5nPJb+o0t6jmLLyzi4lcu4cKXLqJ4qoSBA0OY+MAksttzJnlMcVb+4TKsF+X7zsCA3y4vyrvOyQ7R6qJZPTO7ieLsQVIpyvhK/x40ktS3bOH0XQCLFnXq9YpZrBkq6DE9FiFEzkB5VhXVdVZ/7+T6gTw6LSrqYK1MfVNpOhBLA9vuRTOaJ1liTMYMlElcTyylUFJj19xLs9N+R71fJOJ1unO6YTXwYWE/IhxvWI/Xnpz6atOkQmWqghoHQOs9zUrLBt7eSubfpEFDNwXj9VVnXV+5VEbheAFLLyxh5tEZXPjyBVz44gXMPbGA2mIDA3sHMfHBHRi5w9N59H6hNnnC2IQAlqgjWhVrIZLto/BKoHb+Ity6vsrDUesGr0tEWpirR3E8sgMtvVhTysc7DOWoZ2OavvS22OnzF6i/lLyt41SibYpUQr99QTPlKWzOPw7a2qLedvr0BU3VRrFOcI5rnf4qIlOPwi1V0GzRpEnp4RH5puTKRB4r1GpFUJvnHVZcsGNvQYbwCwp8X+6sxwsWDsXTqZHV1SoWjy7a9/IdSg1b1yGx7JeglT2LUX66q/sO55HdRXL7ItigFvOawokCZr83h1ZZOoVXd728QGa5Np6lRlJIDNKc1aZ8XUPStM11v1qGoEeFcLwOvH8PCvBucvRNUprklZMX0JydZV1YaeUR1M/v8qRulkoRXzgTR+6jv4Pbbr8TDR57D4U3hyctqK9QYtjCIMuT8NDGMVtllo7E85ZG+koQR/2Fsg6njx/B+WOvYLAvgxtv2Iv3ffC9GNs+jvO0qpZX9cM6LVs4rHOaqlMKB2Ep2HLaM6bnY3Mz0zjy7HcvQyDCLc7APfo5ROqzHIAY+1Yd0B4hz9Mx7yyRqLkwAxSWeCwS0QWwpD59/Mva2Gxg5LOs+hpFf5FE1vOYBnUETSmSPmygqux98Q8YvKMf+YM5G3xzQR4kSvlsBatHivYV5XguZm/aiGZo9tP60BcE7M5TXkY+CXi/EkFdhHAdhfYhA96/BwUo2p1ECk7/OCXPPOrnz3v9EeThV09ladrSr/V845Xz+JPF/fjMb/1r7Bofhn6t8DJDYtC5t0MgVbDGvjx/+jgmxrK2DnT0lVexsryCj/7YQ9h36AZcmltFrVpHjXnpWVmD5NGKdJV6bl0+nbpYr8PTuxa1t+iyBBLcuVdor30LDufNZkEN808YvE7R4wNHP2/NO7xFErXWFj0CySm933nd4+Bd7keGz/kJtd+lPcH6lgHp4+dJx5ZoyO3ZVp4R3c1Q8UUqh6siCsN6O5n+zZLgtZoqghudUW3yCKFgR8U3iW9HcbD0rCsyMIba9Arqp88ykmVQIlu9hcBj+fl0FFNLa/iVPz+KiQ//In7zN36T0ojTbUUPij1Y3l0d97YJxHbrBeOnjh3BdYd24AMfuAu5RBPf+uq38VePP4Of+NlPYnzHXiwuse6SNiIPfZM+flhOi2uLC4t4+tFv4oa77ttEBwrBGbkR7uCtZuJG9ZZ1GyQ6+UGYDTRLjESKjozD6Ru2zjTHc2p+Vx/4EX5k+FwooTrE3ncopzBde3qRJ6WUTusULNzLJ+wIDVyLnaZ3HUqvkTSzV8Co7puRJ3StIVzxdpCBoF1eBPNi+33y1OcLqJ05p8jN9R4iRenHYcbnXljF9y7FcejAfmTSEVv36e/vNz+h/Pw1I9U3cNb2twHdN3pyL0LNzy2SBGuMiOPHPv4QbrjxMB4mkZq1GlJJPVP0+tOarwvVXvOoRlAwFJcX2fUR7JyY8N4T7RWxCaQwp4apB80h4q7C4WDYE2/LWY6wwhim9WDvt6HyKLQoinm1am3Hbdhl/rW+Z7A8PYSTWCCcLgAbpqLtnL7DVWYUb1571Q91VnMKS3oLQf7hvCzrUETHuSvHt0/z7jadp98jT/3UGa8vop6FE4aqK4MyRYvwkWMl/O+PL6PS4pRXbeDU8XPUK+Y4VVQpfWNIM89MJms/ziIy2XqQbhpmErwsQc+jpC/ZfcUP3RMByeTpvB3ah1oaIXE4tVKB3r13l21e01ebt0+M4cknnkaBs8yB6w+zSTQ+qjUjm25alSGJpjZpJfvVZ59Crn8I933wnrcgEOHE2EC93LI4xQw4IjU9qPNPBlBvqkMp7qyauT5bA2mViz6x2GuWRonk1j1DMChBsH2OgXaYsPB6An26dZGVvshSJZHk61jOszbpvPT+ZQZb7wgiLI0XNITTt+MZCOopz0aI01YuR6lL8sysoBaQxzePu6Hxz6ZjeGOmhv/pS+fx4tlZ/MAP3o/33PNenD5xFi8++zyee/pZvPjM83jj5ddwnpJscXHBNndJGul5mD0Xo9MremP2nTKt13n9y9rYYBuZ5FhHIxHjPKuShsXaqm0L2bd/tz0qiVB6Dw33IZPL4OFvPMohbGLHnr3QL0Z737FnU0m8GHU7ba997dmncfHsGdx27wdxy/UTV9aBwnAX3oR7/puINNbQWvFeH6I+ZfX44XWsQSVSNDrpFFqlAvWiKZKOo6k7coM08gek/RGAB+HjcIJQvDeQ+icVNqQXGFA4dE7EaSMUNATnOuJ54P17UECDpFJ5FyLZh9qFOTQuXLS2B+85VL0C3/qIyJE855eq+M0vX8CfPXOehmIV//Jf/Sv8i9/8p5hbqeD40dM4eewszpKIM1PTVHApocqU5JQ+evdhf/8AhkaH7C1kg8Mj9mgjw5s1nc0hHqelzP41Xvv6jynCvKn1dSFtzRARZqan8fqLz+Oee27Bve+9E/FYEwN9SegLjo8+8hS+9qVvYduOnbjx9jvQr5/JbDkoV+qYn1/EGy+9iDPHj+L2+38Qh2+4CfffNnT1BFLntGZegDP9GEVu0fYF6UJTRoMcbL5UC+g4nTmpLOMoCqlcu8UVnuN5mfkdox0+9APh01c45123Md4Lbx7fIXUCdNVn/Zxd4IXkq53Sd2J6bjjK6TGG6tmLnqnOwdMU3u6MwDPfRS4VwRLvo99/ZB6PzUQpTRxkU0k89NBH8amf/0fI9WVtJSLO+4xCHkuLJcxPL1JfmcP09AxmL01jfnYOyyTV2moB1bLX/9oUr5+8THO6y/f127aOTD5vpEqm07a9Ncb6SnropQraR/S9xx/H6tx5/JNf+yVM7tqBSKuKnF60wDQvvPAGvvvIE1haWkKKeUoSaSejdkRqCjt8y53Yd90tGMq2cO+tI9dAIIGd584+B8w8aS9Psu0J1gy/l/3OsmPLltNZKgOXIt0tzKO1vEBFts6KeCSyq/xLLdAOE+H4sBdOc6VrOtLxMHxhxzWXiffzaEfZPiS2J5vnPDRo38Ovnz1Hq9PrWJOu7fave+oH7bdZqzv4/W9eQOvwg/jZn/kJ5PL6dmgcKUrqAW07RdR+V0+mtvZeF0uSGrw2H7d7jnaKbUtdXS1Sj+E0tLDAqWiJkmEei3MLJq00PVVKFVSrFZM+nNDthtX0F+VUp++MSZpdPHcWF8+cxn/33/88Pv3L/5h1pERt1Eg2LdfEMDu/jLNnzmOaUrBUpHLJKVKSbnB0G/oGx2wB8sa9Gezclr9GAgkkUWv6WURmnmBrS5REnM6Cbrac+CFfAxPkrM7Xl+nYmCaJ5xZ83Si8RtIxWkQ73Bm/Pt6d8QY73jz+7UgeGwDrHrZQ6zuyMLW6PD2LxhSlar3m6TtBPtZev9H0FCudx0334UTuLnztXBKf+NEPY9euSS/NJvAUXwdvnFzAV7/8KEorM9izby927tuFUU5dOU5jIp1Ipe05VVqpUnhLxRIKxSJJVESJrsjjYrFgBNDPhcvpW656I4gU6e89Kqurgl/957+OH/2JH7cbQLsg9aMt/Kc09H4hWl8jqmo7rGZtqiary2tItxbx0Y/cgaR0sGsmkMDbwZ19Hph+gpYZJRGnM5nZXpcxO+VonUqCNMq0kJZ4vklplIXDO1izXLNIM9LelcPrTAkMrvFhQf84HH2Z+MulV7hNHiEIXo48ileX0BmBEhT/tCzdRA7N5SIaFy95D0aVTvUOQ+3226+HlXoHj8jTvPnjcPd/kDdMgtNJ1zWXwYkLRfzRf34YX//8f8DC1FmMbpvA+MQ2jG2n27YN49vG7UuH0oVyeoG4vvIjxZpTjuPyRpUlRVfXFyWo/0gHsm9ikHmFQgHf+vPP4ztf+UtM7t6JX/z1X8N77r0LKRJCW2ZLVNq1n9qe0NNpEblBN0U979EvfxEjWRe/93/8c9PL3h6BBDK5Nf+qkShSW6JUqdjKpQ2E6UJ09QqtIW3hlOXG4ZCSKZGazoGTNBxp+ZRIrSrFJBto19rAWMA79mFRhs54gx37keFzlnSTeGE9Q+9cuxtMJbd1HSeThxvP0RiomsRpUi8wyakpOcgw3H0K8lgkSWmbaG4MrVs+AWff/dbua8HF2QIe/t60Ka7f+Py/x6UzJ0nAuFleUU6Z+qnLTDbNKS5PAnF6GRy2zWY/9Q8+QYKN24umZuaWcerUea+KrHOE05gWfFX3ualLOPHmG2aej2zfYYuKu3eO4OAN1yPN6Uo3f7FUsylRX148ffwY/uJPP49TR47gjrtuxr/79/8bRkaHt0AgH82Fo8DUXyFaprVF5jbKdZvSHNrWbnnVOlyDtT4+DEgeshOcTI5kyiiSRKOk0k9y68GjzgcDLNtX+dkhP/zoNoL4kGewpKGIjnP+gVWKTr4WJfW9K05VIrf2ibfYeY1Z6m4ijuYL0908CdLRnnUP6WSUg8yBGtwL5/afAiZv9U5cI+aXSiTQJZTrMZw7/gqefvjLOPHGq/aiBa8t1kDjrPpLb3Y9fN0+/Nv/6/dw0y3XW/zZs5fw2d/+N3j1tSPW5KhuXmrpeltHnlJLVtaOvfuwi2b7U5zSvvuNr+PA4cP4yI99BDfdfCO+9Y3HsER9qJ9W2o3X78F//MP/QiXcxQMP3ovf/b1fx8BA/1uvA70VIpkRILOdynGJbFyjokaGl9c88gTTUxhqieJ4zuUUJieJJWXbCEVRrLtFg6+VDXURWU7PHyGvyzzYsoD1ZtsTNqzxtK+RH+RFp6pQsXRYdjTfz3b0w41mOEVR4tDqCaYrW8DzFf/NoOy09UWLcnpLbGvb7XDu/odwxq/zU1w7dA/pAefKWoXK6ygO0Gwem5i0t9GrQL3mV2s71jeEFgmHhgfwQz/yAMbHR63ZGVpWT373Kbzy4mvUf+qc3pIYGB7mtLUX1918C2654w7s2b8HY6NDSFBxP3H0KGZp8d1z9404dGg7/vT//TyOvvYmJidG8Jlf/Blcd8NhHDy8Dx//yYdMj7N+3qoECqBf/WlNP4fI3NNw1i5wSitRKWMv2HSmBvsJBQvzQ76mMc7VUqgdzuFm+qeosMosVifRatPd7zbpM53tRVHvWhZ+pjau64PrWVzBOYbFM00hypNEkKRxpStQJ3Ei1FNUFZqqzdU1NPQFvhJJDSn9obWroKzA0zUK8yNNiaOXsCM9ZLoODnzI9gJtBdqf/J1nzuPE+SLbXrU90plcmopvGctz05ibvmQvRCisrtr3vvTtjZ07tuHnP/MJ7Nq53fKQHvSVbzyDx//6GPI07weGBzFIqZPP59jF2pXIrtTOC1pg2tq6tDDHfljDgw/czXR9+M6jf43zZy7ZlHXr7TdYnt14xwhkEBkWXrOfz3RWTqgFVLC1JK5FrPUB9gZBI2BHnq9qGDn4LwmUSCKSJJGkxGrANcVYUpFSieQ4PRqZFA6I44MdYu9/JHFckUZkMGmoxTYSmmauy45v0TqRVWjSUMsUPO8tMzBpUD8h6Cbf00qvXgyV0Y/7slx37Do41/8w3MlbrMytQnV89rVpPPf6AqtCMlOPTFLC5TLaK50xCyiuLS5suKo7xAHPZ6IYzsc6fnnn9FQRjz8/a81pNSussxYMHAl525GoPdaJOBX+bMoU87F+B32bfw1+U7yzBPKhZ2eYeQbO7LNAcdZWxmxrhorSIFuJ/AhKbtfAi7PleJGE6W2ZXvoSSUQZbFOO/EiMxJBE0Xn1DvM1iil75WfX0xepJbm0EkszVa5F4tD29SSbEqscX0LZtQbF+0HBP6FsNaPp5dxar0F+FO7u+4C976OZv83SvBNQvU5eWMFjz07ZdhbHrSNOSRePOSZtUtRltDler3iRNNGLxrNpB8NUKZUmwMJKGQ8/eR6rxQYJVDYFP8k+TDAvTVvaXK8XSomUebrJ0TQGsupXP4O3wLtCIIOkw8opuBdp6ksq6SeVyg37Tpn3WCY0QO0aeHHrhzqgtNAUx1ib8xWvaUV3vSSMfM1RRiAP1iQSx6w83xmR5BuYUv/qJREw1AXrQZXtBwmVzZQecejcSBruBKXNwR8ARg9RavGWfocxz8H/5pPnaA1J0tYQp6SwQSeBEryB9JXkGMmSTMTsWxt5SsOxwSjJpZp6qFQbePzZizg3QwOFBNLSm0gTECjph/N9OZNceydy6M/xJr1KrJf0TkN39OBB4NAn4R7+Wbgjt8OldZPoTyOlTV0avNAAXRYihmS0pJCkT3t64cVaj6LV5tbYOXqrlyy5wClOlhOnJVHMs7K8PMy3fK6u+ZwpbEEwQ9keoaKPHXfAfc8vIHLPz8PZdsO7Qh5BK9iDuRSbrAemavRGKF4u4p/vTiWyDPez3rxh9ThjI7xB0Ap1jITSFHctePcI5MPRe2a23QEc/hm415NI4+z8VB9iWYrfnOZfmpa+fnNVUEdp4CWFRFJ1ru+MXO1jdpaO/anJrrnMIHRDqVQn3eHZTIKE15oQrbTd98C95zPA3Z9BZM890Iui3k2ob8aGvZ9i0j4cr2bdUJz6RE7HnQTQZdvGsvYdsJhuwq4+UGrF6VyWinrwi89Xi2tLvQU4yTwi2++Gc8PPArd+Bu7eD8PNT9pzMv2Qb1T7MmRpScn4W4EsRU6RlFiqi/0Ul/SsvglK0Ifg3vdLwF2fgbPnvZzHvD1P7zYkVYb7k7alOiqL0Y+/LFh/27bRhUHmMZCnMcKbyXRGH0F+tt2GR1GnSf2JhV0DrlkHsk6+yjv5itDzscIMsHiMmt5RtGaOwl2jwq2XJsn0l/TQ6rXKkh80N1Rbr+b8CJoQnAs3yU8TjpL6pTg2nrnKl5IqPYuxetzQPwZn+2FgjKYr9RuQROvd/TeLUqWJR56+gIXlKutYNZ0nrAOZJZVMYJgmupTo8QFPKQ5DFuMLb8zj9VP6fbSaTWfSe6T/SOJkc2nksllMjCSwfZiW7zWM7zURKEi6VQKFC9Qdo3WO1spFtOaPw50/gcbiGUQri4jYa9+kQOoKlslyvW8X6FAWkx8OMmz7XsBqaRKNxyKLT5iIztvalAzkKBpOHLV4H5p9O9AcPoDkxA1IjOygBGJnGpFD+bTh9UFHT2zoFn9q7krUHWcxXcesmkkgWWDPvDaLV48vkTyukUaLiQGBTBEmGdJ6qt8Xx+7xrFlhdqObauBlfPbiKr7112dQrTdt3UrXSPmWZaev9kjfuvnAmOURFhLh8Ga4agK9VUbdUHr1udZtRBKZ5orzdsrRpGZYm73104yVep2WvktHC61GBbg4D2dtCvHyNBLVeSRrK0g0C4jJitAdpPUiZs4S2AArJNz/Xl2tVaKLAiJKhOVGUUcMVTeOkpvEqpvGCvpQiPWjkhhGIzlACaTX2/LOpjKZ0DqLFjjVFmWn8lSS/v2pQH2iss2XfU/fFFqel6Fgg+gPpHYPasHOSxuxdNJtWALJap/esaYUZqG3ZkgXuzRbwPELNdoRki4RSg8OPMMij164meC1Ms/zuSS2DSWNXJY/r1VeSru8WsJTL13ECs35LM1/SR7lozxUv75sEjfsH9kgvd4KV0UgDb41Wh3zdsAS7NsCGggRh/kFWy0lXZokgZ7ma+XUHvZFYjaN2a/yNaqURBWSp4B4Y42uhChdjE4boex1d9oso2UDK0vNoSNZWsqH0qURSaCGJKpO0ohTRgLlJl0rBr0ewAScSEkdzPsxN9XTy8uo4/0brAeMJwGBdMjB12AZMUQDS2ADqD6zH+yzc7JygjQcYJFJ19n13oB7+XjpdWzfj+d1+nE8Xa9iozrPsHhmhGNab8+0lFrVVNf6xgnP672GylMb1vRA3n6OXGmt7lvDNU1hwjUm74RdakMSBIMPDwx6Z70D3e/qkiYbr2Lt9dQ6TSepID1KK7Ra4/HFnYEhhil12EvKQ51vepXCvE6xEaaPUGmUjLL1Il1jUMjr1vW4jVjveKbSyBEWF5xoZyOyhMP8Y1iHViX/eN0P4B8re/oacJFKzfaTe+HgwIfXZ4qhvx5t18pdCTa27Xp34nLXXjOBeughDO/W6aGHt4kegXrYEnoE6mFL6BGohy2hR6AetoQegXrYEnoE6mFL6BGohy2hR6AetoQegXrYEnoE6mFL6BGohy2hR6AetoQegXrYEnoE6mFL6BGohy2hR6AetoQegXrYEnoE6mFL6BGohy2hR6AetoQegXrYEnoE6mFL6BGohy2hR6AetgDg/wcjLgwY8u5DYQAAAABJRU5ErkJggg==" +} diff --git a/agent/templates/text2sql.json b/agent/templates/text2sql.json index cf6dd5307..c5a62d192 100644 --- a/agent/templates/text2sql.json +++ b/agent/templates/text2sql.json @@ -1,585 +1,585 @@ -{ - "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": { - "begin": { - "obj": { - "component_name": "Begin", - "params": {} - }, - "downstream": [ - "Answer:SocialAdsWonder" - ], - "upstream": [] - }, - "Answer:SocialAdsWonder": { - "obj": { - "component_name": "Answer", - "params": {} - }, - "downstream": [ - "Retrieval:TrueCornersJam", - "Retrieval:EasyDryersShop", - "Retrieval:LazyChefsWatch" - ], - "upstream": [ - "begin", - "Generate:RareSymbolsGrin" - ] - }, - "Retrieval:TrueCornersJam": { - "obj": { - "component_name": "Retrieval", - "params": { - "empty_response": "Nothing found in DDL!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.02, - "top_n": 8 - } - }, - "downstream": [ - "Generate:RareSymbolsGrin" - ], - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "Retrieval:EasyDryersShop": { - "obj": { - "component_name": "Retrieval", - "params": { - "empty_response": "Nothing found in Q-SQL!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_n": 8 - } - }, - "downstream": [ - "Generate:RareSymbolsGrin" - ], - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "Retrieval:LazyChefsWatch": { - "obj": { - "component_name": "Retrieval", - "params": { - "empty_response": "Nothing found in DB-Description!", - "kb_ids": [], - "keywords_similarity_weight": 0.3, - "similarity_threshold": 0.2, - "top_n": 8 - } - }, - "downstream": [ - "Generate:RareSymbolsGrin" - ], - "upstream": [ - "Answer:SocialAdsWonder" - ] - }, - "Generate:RareSymbolsGrin": { - "obj": { - "component_name": "Generate", - "params": { - "cite": true, - "frequency_penalty": 0.7, - "llm_id": "deepseek-chat@DeepSeek", - "max_tokens": 256, - "message_history_window_size": 12, - "parameters": [ - { - "component_id": "Retrieval:TrueCornersJam", - "id": "78644673-9236-4605-8110-59705fc38784", - "key": "ddl_input" - }, - { - "component_id": "Retrieval:LazyChefsWatch", - "id": "afbf91ce-6f58-4573-b02d-9a4973f124f4", - "key": "db_input" - }, - { - "component_id": "Retrieval:EasyDryersShop", - "id": "ee2b84f4-1cf5-43be-80e6-60bfaea3d834", - "key": "sql_input" - } - ], - "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: {ddl_input}.\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: {db_input}.\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: {sql_input}.", - "temperature": 0.1, - "top_p": 0.3 - } - }, - "downstream": [ - "Answer:SocialAdsWonder" - ], - "upstream": [ - "Retrieval:TrueCornersJam", - "Retrieval:EasyDryersShop", - "Retrieval:LazyChefsWatch" - ] - } - }, - "embed_id": "", - "graph": { - "nodes": [ - { - "data": { - "label": "Begin", - "name": "begin" - }, - "dragging": false, - "height": 44, - "id": "begin", - "position": { - "x": -520.486587527275, - "y": 117.87988995940702 - }, - "positionAbsolute": { - "x": -520.486587527275, - "y": 117.87988995940702 - }, - "selected": false, - "sourcePosition": "left", - "targetPosition": "right", - "type": "beginNode", - "width": 100 - }, - { - "data": { - "form": {}, - "label": "Answer", - "name": "interface" - }, - "dragging": false, - "height": 44, - "id": "Answer:SocialAdsWonder", - "position": { - "x": -284.9289105495367, - "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", - "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", - "position": { - "x": 81.2024576603057, - "y": 94.16303322180948 - }, - "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", - "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": { - "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": [ - { - "component_id": "Retrieval:TrueCornersJam", - "id": "78644673-9236-4605-8110-59705fc38784", - "key": "ddl_input" - }, - { - "component_id": "Retrieval:LazyChefsWatch", - "id": "afbf91ce-6f58-4573-b02d-9a4973f124f4", - "key": "db_input" - }, - { - "component_id": "Retrieval:EasyDryersShop", - "id": "ee2b84f4-1cf5-43be-80e6-60bfaea3d834", - "key": "sql_input" - } - ], - "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: {ddl_input}.\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: {db_input}.\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: {sql_input}.", - "temperature": 0.1, - "temperatureEnabled": true, - "topPEnabled": true, - "top_p": 0.3 - }, - "label": "Generate", - "name": "LLM" - }, - "dragging": false, - "height": 212, - "id": "Generate:RareSymbolsGrin", - "position": { - "x": 6.6098512156750076, - "y": 405.0105548561454 - }, - "positionAbsolute": { - "x": 6.6098512156750076, - "y": 405.0105548561454 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "generateNode", - "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" - }, - "dragging": false, - "height": 132, - "id": "Note:GentleRabbitsWonder", - "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, - "dragHandle": ".note-drag-handle" - }, - { - "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" - }, - "dragging": false, - "height": 147, - "id": "Note:SixCitiesJoke", - "position": { - "x": 5.12121582244032, - "y": 637.6539219843564 - }, - "positionAbsolute": { - "x": 5.12121582244032, - "y": 637.6539219843564 - }, - "resizing": false, - "selected": false, - "sourcePosition": "right", - "style": { - "height": 147, - "width": 326 - }, - "targetPosition": "left", - "type": "noteNode", - "width": 326, - "dragHandle": ".note-drag-handle" - }, - { - "data": { - "form": { - "text": "Searches for description about meanings of tables and fields." - }, - "label": "Note", - "name": "N: DB description" - }, - "dragging": false, - "height": 128, - "id": "Note:FamousCarpetsTaste", - "position": { - "x": 399.9267065852242, - "y": 250.0329701879931 - }, - "positionAbsolute": { - "x": 399.9267065852242, - "y": 250.0329701879931 - }, - "selected": false, - "sourcePosition": "right", - "targetPosition": "left", - "type": "noteNode", - "width": 269, - "dragHandle": ".note-drag-handle" - }, - { - "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" - }, - "dragging": false, - "height": 130, - "id": "Note:PoliteBeesArrive", - "position": { - "x": 489.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": 451, - "dragHandle": ".note-drag-handle" - }, - { - "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" - }, - "dragging": false, - "height": 258, - "id": "Note:SmartWingsDouble", - "position": { - "x": 404.1930553966363, - "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": 283, - "dragHandle": ".note-drag-handle" - } - ], - "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": "reactflow__edge-Retrieval:TrueCornersJamb-Generate:RareSymbolsGrinb", - "markerEnd": "logo", - "source": "Retrieval:TrueCornersJam", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RareSymbolsGrin", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Retrieval:EasyDryersShopb-Generate:RareSymbolsGrinb", - "markerEnd": "logo", - "source": "Retrieval:EasyDryersShop", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RareSymbolsGrin", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Retrieval:LazyChefsWatchb-Generate:RareSymbolsGrinb", - "markerEnd": "logo", - "source": "Retrieval:LazyChefsWatch", - "sourceHandle": "b", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Generate:RareSymbolsGrin", - "targetHandle": "b", - "type": "buttonEdge" - }, - { - "id": "reactflow__edge-Generate:RareSymbolsGrinc-Answer:SocialAdsWonderc", - "markerEnd": "logo", - "source": "Generate:RareSymbolsGrin", - "sourceHandle": "c", - "style": { - "stroke": "rgb(202 197 245)", - "strokeWidth": 2 - }, - "target": "Answer:SocialAdsWonder", - "targetHandle": "c", - "type": "buttonEdge" - } - ] - }, - "history": [], - "messages": [], - "path": [], - "reference": [] - }, - "avatar": "data:image/png;base64,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" -} +{ + "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": { + "begin": { + "obj": { + "component_name": "Begin", + "params": {} + }, + "downstream": [ + "Answer:SocialAdsWonder" + ], + "upstream": [] + }, + "Answer:SocialAdsWonder": { + "obj": { + "component_name": "Answer", + "params": {} + }, + "downstream": [ + "Retrieval:TrueCornersJam", + "Retrieval:EasyDryersShop", + "Retrieval:LazyChefsWatch" + ], + "upstream": [ + "begin", + "Generate:RareSymbolsGrin" + ] + }, + "Retrieval:TrueCornersJam": { + "obj": { + "component_name": "Retrieval", + "params": { + "empty_response": "Nothing found in DDL!", + "kb_ids": [], + "keywords_similarity_weight": 0.3, + "similarity_threshold": 0.02, + "top_n": 8 + } + }, + "downstream": [ + "Generate:RareSymbolsGrin" + ], + "upstream": [ + "Answer:SocialAdsWonder" + ] + }, + "Retrieval:EasyDryersShop": { + "obj": { + "component_name": "Retrieval", + "params": { + "empty_response": "Nothing found in Q-SQL!", + "kb_ids": [], + "keywords_similarity_weight": 0.3, + "similarity_threshold": 0.2, + "top_n": 8 + } + }, + "downstream": [ + "Generate:RareSymbolsGrin" + ], + "upstream": [ + "Answer:SocialAdsWonder" + ] + }, + "Retrieval:LazyChefsWatch": { + "obj": { + "component_name": "Retrieval", + "params": { + "empty_response": "Nothing found in DB-Description!", + "kb_ids": [], + "keywords_similarity_weight": 0.3, + "similarity_threshold": 0.2, + "top_n": 8 + } + }, + "downstream": [ + "Generate:RareSymbolsGrin" + ], + "upstream": [ + "Answer:SocialAdsWonder" + ] + }, + "Generate:RareSymbolsGrin": { + "obj": { + "component_name": "Generate", + "params": { + "cite": true, + "frequency_penalty": 0.7, + "llm_id": "deepseek-chat@DeepSeek", + "max_tokens": 256, + "message_history_window_size": 12, + "parameters": [ + { + "component_id": "Retrieval:TrueCornersJam", + "id": "78644673-9236-4605-8110-59705fc38784", + "key": "ddl_input" + }, + { + "component_id": "Retrieval:LazyChefsWatch", + "id": "afbf91ce-6f58-4573-b02d-9a4973f124f4", + "key": "db_input" + }, + { + "component_id": "Retrieval:EasyDryersShop", + "id": "ee2b84f4-1cf5-43be-80e6-60bfaea3d834", + "key": "sql_input" + } + ], + "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: {ddl_input}.\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: {db_input}.\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: {sql_input}.", + "temperature": 0.1, + "top_p": 0.3 + } + }, + "downstream": [ + "Answer:SocialAdsWonder" + ], + "upstream": [ + "Retrieval:TrueCornersJam", + "Retrieval:EasyDryersShop", + "Retrieval:LazyChefsWatch" + ] + } + }, + "embed_id": "", + "graph": { + "nodes": [ + { + "data": { + "label": "Begin", + "name": "begin" + }, + "dragging": false, + "height": 44, + "id": "begin", + "position": { + "x": -520.486587527275, + "y": 117.87988995940702 + }, + "positionAbsolute": { + "x": -520.486587527275, + "y": 117.87988995940702 + }, + "selected": false, + "sourcePosition": "left", + "targetPosition": "right", + "type": "beginNode", + "width": 100 + }, + { + "data": { + "form": {}, + "label": "Answer", + "name": "interface" + }, + "dragging": false, + "height": 44, + "id": "Answer:SocialAdsWonder", + "position": { + "x": -284.9289105495367, + "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", + "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", + "position": { + "x": 81.2024576603057, + "y": 94.16303322180948 + }, + "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", + "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": { + "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": [ + { + "component_id": "Retrieval:TrueCornersJam", + "id": "78644673-9236-4605-8110-59705fc38784", + "key": "ddl_input" + }, + { + "component_id": "Retrieval:LazyChefsWatch", + "id": "afbf91ce-6f58-4573-b02d-9a4973f124f4", + "key": "db_input" + }, + { + "component_id": "Retrieval:EasyDryersShop", + "id": "ee2b84f4-1cf5-43be-80e6-60bfaea3d834", + "key": "sql_input" + } + ], + "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: {ddl_input}.\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: {db_input}.\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: {sql_input}.", + "temperature": 0.1, + "temperatureEnabled": true, + "topPEnabled": true, + "top_p": 0.3 + }, + "label": "Generate", + "name": "LLM" + }, + "dragging": false, + "height": 212, + "id": "Generate:RareSymbolsGrin", + "position": { + "x": 6.6098512156750076, + "y": 405.0105548561454 + }, + "positionAbsolute": { + "x": 6.6098512156750076, + "y": 405.0105548561454 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "generateNode", + "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" + }, + "dragging": false, + "height": 132, + "id": "Note:GentleRabbitsWonder", + "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, + "dragHandle": ".note-drag-handle" + }, + { + "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" + }, + "dragging": false, + "height": 147, + "id": "Note:SixCitiesJoke", + "position": { + "x": 5.12121582244032, + "y": 637.6539219843564 + }, + "positionAbsolute": { + "x": 5.12121582244032, + "y": 637.6539219843564 + }, + "resizing": false, + "selected": false, + "sourcePosition": "right", + "style": { + "height": 147, + "width": 326 + }, + "targetPosition": "left", + "type": "noteNode", + "width": 326, + "dragHandle": ".note-drag-handle" + }, + { + "data": { + "form": { + "text": "Searches for description about meanings of tables and fields." + }, + "label": "Note", + "name": "N: DB description" + }, + "dragging": false, + "height": 128, + "id": "Note:FamousCarpetsTaste", + "position": { + "x": 399.9267065852242, + "y": 250.0329701879931 + }, + "positionAbsolute": { + "x": 399.9267065852242, + "y": 250.0329701879931 + }, + "selected": false, + "sourcePosition": "right", + "targetPosition": "left", + "type": "noteNode", + "width": 269, + "dragHandle": ".note-drag-handle" + }, + { + "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" + }, + "dragging": false, + "height": 130, + "id": "Note:PoliteBeesArrive", + "position": { + "x": 489.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": 451, + "dragHandle": ".note-drag-handle" + }, + { + "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" + }, + "dragging": false, + "height": 258, + "id": "Note:SmartWingsDouble", + "position": { + "x": 404.1930553966363, + "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": 283, + "dragHandle": ".note-drag-handle" + } + ], + "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": "reactflow__edge-Retrieval:TrueCornersJamb-Generate:RareSymbolsGrinb", + "markerEnd": "logo", + "source": "Retrieval:TrueCornersJam", + "sourceHandle": "b", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Generate:RareSymbolsGrin", + "targetHandle": "b", + "type": "buttonEdge" + }, + { + "id": "reactflow__edge-Retrieval:EasyDryersShopb-Generate:RareSymbolsGrinb", + "markerEnd": "logo", + "source": "Retrieval:EasyDryersShop", + "sourceHandle": "b", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Generate:RareSymbolsGrin", + "targetHandle": "b", + "type": "buttonEdge" + }, + { + "id": "reactflow__edge-Retrieval:LazyChefsWatchb-Generate:RareSymbolsGrinb", + "markerEnd": "logo", + "source": "Retrieval:LazyChefsWatch", + "sourceHandle": "b", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Generate:RareSymbolsGrin", + "targetHandle": "b", + "type": "buttonEdge" + }, + { + "id": "reactflow__edge-Generate:RareSymbolsGrinc-Answer:SocialAdsWonderc", + "markerEnd": "logo", + "source": "Generate:RareSymbolsGrin", + "sourceHandle": "c", + "style": { + "stroke": "rgb(202 197 245)", + "strokeWidth": 2 + }, + "target": "Answer:SocialAdsWonder", + "targetHandle": "c", + "type": "buttonEdge" + } + ] + }, + "history": [], + "messages": [], + "path": [], + "reference": [] + }, + "avatar": "data:image/png;base64,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" +} diff --git a/agent/test/dsl_examples/concentrator_message.json b/agent/test/dsl_examples/concentrator_message.json index 98d62b580..ee875ae02 100644 --- a/agent/test/dsl_examples/concentrator_message.json +++ b/agent/test/dsl_examples/concentrator_message.json @@ -1,113 +1,113 @@ -{ - "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": [] +{ + "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/rag/svr/cache_file_svr.py b/rag/svr/cache_file_svr.py index 4bbadf0f8..5c984db97 100644 --- a/rag/svr/cache_file_svr.py +++ b/rag/svr/cache_file_svr.py @@ -1,60 +1,60 @@ -# -# 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 time -import traceback - -from api.db.db_models import close_connection -from api.db.services.task_service import TaskService -from rag.utils.storage_factory import STORAGE_IMPL -from rag.utils.redis_conn import REDIS_CONN - - -def collect(): - doc_locations = TaskService.get_ongoing_doc_name() - logging.debug(doc_locations) - if len(doc_locations) == 0: - time.sleep(1) - return - return doc_locations - - -def main(): - locations = collect() - if not locations: - return - logging.info(f"TASKS: {len(locations)}") - for kb_id, loc in locations: - try: - if REDIS_CONN.is_alive(): - try: - key = "{}/{}".format(kb_id, loc) - if REDIS_CONN.exist(key): - continue - file_bin = STORAGE_IMPL.get(kb_id, loc) - REDIS_CONN.transaction(key, file_bin, 12 * 60) - logging.info("CACHE: {}".format(loc)) - except Exception as e: - traceback.print_stack(e) - except Exception as e: - traceback.print_stack(e) - - -if __name__ == "__main__": - while True: - main() - close_connection() +# +# 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 time +import traceback + +from api.db.db_models import close_connection +from api.db.services.task_service import TaskService +from rag.utils.storage_factory import STORAGE_IMPL +from rag.utils.redis_conn import REDIS_CONN + + +def collect(): + doc_locations = TaskService.get_ongoing_doc_name() + logging.debug(doc_locations) + if len(doc_locations) == 0: + time.sleep(1) + return + return doc_locations + + +def main(): + locations = collect() + if not locations: + return + logging.info(f"TASKS: {len(locations)}") + for kb_id, loc in locations: + try: + if REDIS_CONN.is_alive(): + try: + key = "{}/{}".format(kb_id, loc) + if REDIS_CONN.exist(key): + continue + file_bin = STORAGE_IMPL.get(kb_id, loc) + REDIS_CONN.transaction(key, file_bin, 12 * 60) + logging.info("CACHE: {}".format(loc)) + except Exception as e: + traceback.print_stack(e) + except Exception as e: + traceback.print_stack(e) + + +if __name__ == "__main__": + while True: + main() + close_connection() time.sleep(1) \ No newline at end of file diff --git a/sdk/python/ragflow_sdk/modules/base.py b/sdk/python/ragflow_sdk/modules/base.py index ced942d2c..49aa18db3 100644 --- a/sdk/python/ragflow_sdk/modules/base.py +++ b/sdk/python/ragflow_sdk/modules/base.py @@ -1,38 +1,38 @@ -class Base(object): - def __init__(self, rag, res_dict): - self.rag = rag - for k, v in res_dict.items(): - if isinstance(v, dict): - self.__dict__[k] = Base(rag, v) - else: - self.__dict__[k] = v - - def to_json(self): - pr = {} - for name in dir(self): - value = getattr(self, name) - if not name.startswith('__') and not callable(value) and name != "rag": - if isinstance(value, Base): - pr[name] = value.to_json() - else: - pr[name] = value - return pr - - def post(self, path, json=None, stream=False, files=None): - res = self.rag.post(path, json, stream=stream,files=files) - return res - - def get(self, path, params=None): - res = self.rag.get(path, params) - return res - - def rm(self, path, json): - res = self.rag.delete(path, json) - return res - - def put(self,path, json): - res = self.rag.put(path,json) - return res - - def __str__(self): - return str(self.to_json()) +class Base(object): + def __init__(self, rag, res_dict): + self.rag = rag + for k, v in res_dict.items(): + if isinstance(v, dict): + self.__dict__[k] = Base(rag, v) + else: + self.__dict__[k] = v + + def to_json(self): + pr = {} + for name in dir(self): + value = getattr(self, name) + if not name.startswith('__') and not callable(value) and name != "rag": + if isinstance(value, Base): + pr[name] = value.to_json() + else: + pr[name] = value + return pr + + def post(self, path, json=None, stream=False, files=None): + res = self.rag.post(path, json, stream=stream,files=files) + return res + + def get(self, path, params=None): + res = self.rag.get(path, params) + return res + + def rm(self, path, json): + res = self.rag.delete(path, json) + return res + + def put(self,path, json): + res = self.rag.put(path,json) + return res + + def __str__(self): + return str(self.to_json()) diff --git a/sdk/python/ragflow_sdk/modules/session.py b/sdk/python/ragflow_sdk/modules/session.py index 3ea275eb5..dcfc3392b 100644 --- a/sdk/python/ragflow_sdk/modules/session.py +++ b/sdk/python/ragflow_sdk/modules/session.py @@ -1,73 +1,73 @@ -import json - -from .base import Base - - -class Session(Base): - def __init__(self, rag, res_dict): - self.id = None - self.name = "New session" - self.messages = [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] - for key,value in res_dict.items(): - if key =="chat_id" and value is not None: - self.chat_id = None - self.__session_type = "chat" - if key == "agent_id" and value is not None: - self.agent_id = None - self.__session_type = "agent" - super().__init__(rag, res_dict) - - def ask(self, question="",stream=True,**kwargs): - if self.__session_type == "agent": - res=self._ask_agent(question,stream) - elif self.__session_type == "chat": - res=self._ask_chat(question,stream,**kwargs) - for line in res.iter_lines(): - line = line.decode("utf-8") - if line.startswith("{"): - json_data = json.loads(line) - raise Exception(json_data["message"]) - if not line.startswith("data:"): - continue - json_data = json.loads(line[5:]) - if json_data["data"] is True or json_data["data"].get("running_status"): - continue - answer = json_data["data"]["answer"] - reference = json_data["data"].get("reference", {}) - temp_dict = { - "content": answer, - "role": "assistant" - } - if reference and "chunks" in reference: - chunks = reference["chunks"] - temp_dict["reference"] = chunks - message = Message(self.rag, temp_dict) - yield message - - def _ask_chat(self, question: str, stream: bool,**kwargs): - json_data={"question": question, "stream": True,"session_id":self.id} - json_data.update(kwargs) - res = self.post(f"/chats/{self.chat_id}/completions", - json_data, stream=stream) - return res - - def _ask_agent(self,question:str,stream:bool): - res = self.post(f"/agents/{self.agent_id}/completions", - {"question": question, "stream": True,"session_id":self.id}, stream=stream) - return res - - def update(self,update_message): - res = self.put(f"/chats/{self.chat_id}/sessions/{self.id}", - update_message) - res = res.json() - if res.get("code") != 0: - raise Exception(res.get("message")) - -class Message(Base): - def __init__(self, rag, res_dict): - self.content = "Hi! I am your assistant,can I help you?" - self.reference = None - self.role = "assistant" - self.prompt = None - self.id = None - super().__init__(rag, res_dict) +import json + +from .base import Base + + +class Session(Base): + def __init__(self, rag, res_dict): + self.id = None + self.name = "New session" + self.messages = [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] + for key,value in res_dict.items(): + if key =="chat_id" and value is not None: + self.chat_id = None + self.__session_type = "chat" + if key == "agent_id" and value is not None: + self.agent_id = None + self.__session_type = "agent" + super().__init__(rag, res_dict) + + def ask(self, question="",stream=True,**kwargs): + if self.__session_type == "agent": + res=self._ask_agent(question,stream) + elif self.__session_type == "chat": + res=self._ask_chat(question,stream,**kwargs) + for line in res.iter_lines(): + line = line.decode("utf-8") + if line.startswith("{"): + json_data = json.loads(line) + raise Exception(json_data["message"]) + if not line.startswith("data:"): + continue + json_data = json.loads(line[5:]) + if json_data["data"] is True or json_data["data"].get("running_status"): + continue + answer = json_data["data"]["answer"] + reference = json_data["data"].get("reference", {}) + temp_dict = { + "content": answer, + "role": "assistant" + } + if reference and "chunks" in reference: + chunks = reference["chunks"] + temp_dict["reference"] = chunks + message = Message(self.rag, temp_dict) + yield message + + def _ask_chat(self, question: str, stream: bool,**kwargs): + json_data={"question": question, "stream": True,"session_id":self.id} + json_data.update(kwargs) + res = self.post(f"/chats/{self.chat_id}/completions", + json_data, stream=stream) + return res + + def _ask_agent(self,question:str,stream:bool): + res = self.post(f"/agents/{self.agent_id}/completions", + {"question": question, "stream": True,"session_id":self.id}, stream=stream) + return res + + def update(self,update_message): + res = self.put(f"/chats/{self.chat_id}/sessions/{self.id}", + update_message) + res = res.json() + if res.get("code") != 0: + raise Exception(res.get("message")) + +class Message(Base): + def __init__(self, rag, res_dict): + self.content = "Hi! I am your assistant,can I help you?" + self.reference = None + self.role = "assistant" + self.prompt = None + self.id = None + super().__init__(rag, res_dict)