### What problem does this PR solve? ``` Invoke agent To be able to interact dynamically with the API, there is a customizable Data Type JSON or FormData, the default is JSON ``` ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Co-authored-by: Kevin Hu <kevinhu.sh@gmail.com>tags/v0.17.0
| ans = self.get_input() | ans = self.get_input() | ||||
| ans = "".join([str(a) for a in ans["content"]]) if "content" in ans else "" | ans = "".join([str(a) for a in ans["content"]]) if "content" in ans else "" | ||||
| ans = self._refactor(ans) | ans = self._refactor(ans) | ||||
| logging.info("db_type: ", self._param.db_type) | |||||
| if self._param.db_type in ["mysql", "mariadb"]: | if self._param.db_type in ["mysql", "mariadb"]: | ||||
| db = pymysql.connect(db=self._param.database, user=self._param.username, host=self._param.host, | db = pymysql.connect(db=self._param.database, user=self._param.username, host=self._param.host, | ||||
| port=self._param.port, password=self._param.password) | port=self._param.port, password=self._param.password) | ||||
| single_sql = self._refactor(single_sql) | single_sql = self._refactor(single_sql) | ||||
| if self._loop > self._param.loop: | if self._loop > self._param.loop: | ||||
| sql_res.append({"content": "Can't query the correct data via SQL statement."}) | sql_res.append({"content": "Can't query the correct data via SQL statement."}) | ||||
| # raise Exception("Maximum loop time exceeds. Can't query the correct data via SQL statement.") | |||||
| db.close() | db.close() | ||||
| if not sql_res: | if not sql_res: | ||||
| return ExeSQL.be_output("") | return ExeSQL.be_output("") |
| self.url = "" | self.url = "" | ||||
| self.timeout = 60 | self.timeout = 60 | ||||
| self.clean_html = False | self.clean_html = False | ||||
| self.datatype = "json" # New parameter to determine data posting type | |||||
| def check(self): | def check(self): | ||||
| self.check_valid_value(self.method.lower(), "Type of content from the crawler", ['get', 'post', 'put']) | self.check_valid_value(self.method.lower(), "Type of content from the crawler", ['get', 'post', 'put']) | ||||
| self.check_empty(self.url, "End point URL") | self.check_empty(self.url, "End point URL") | ||||
| self.check_positive_integer(self.timeout, "Timeout time in second") | self.check_positive_integer(self.timeout, "Timeout time in second") | ||||
| self.check_boolean(self.clean_html, "Clean HTML") | self.check_boolean(self.clean_html, "Clean HTML") | ||||
| self.check_valid_value(self.datatype.lower(), "Data post type", ['json', 'formdata']) # Check for valid datapost value | |||||
| class Invoke(ComponentBase, ABC): | class Invoke(ComponentBase, ABC): | ||||
| return Invoke.be_output(response.text) | return Invoke.be_output(response.text) | ||||
| if method == 'put': | if method == 'put': | ||||
| response = requests.put(url=url, | |||||
| json=args, | |||||
| headers=headers, | |||||
| proxies=proxies, | |||||
| timeout=self._param.timeout) | |||||
| if self._param.datatype.lower() == 'json': | |||||
| response = requests.put(url=url, | |||||
| json=args, | |||||
| headers=headers, | |||||
| proxies=proxies, | |||||
| timeout=self._param.timeout) | |||||
| else: | |||||
| response = requests.put(url=url, | |||||
| data=args, | |||||
| headers=headers, | |||||
| proxies=proxies, | |||||
| timeout=self._param.timeout) | |||||
| if self._param.clean_html: | if self._param.clean_html: | ||||
| sections = HtmlParser()(None, response.content) | sections = HtmlParser()(None, response.content) | ||||
| return Invoke.be_output("\n".join(sections)) | return Invoke.be_output("\n".join(sections)) | ||||
| return Invoke.be_output(response.text) | return Invoke.be_output(response.text) | ||||
| if method == 'post': | if method == 'post': | ||||
| response = requests.post(url=url, | |||||
| json=args, | |||||
| headers=headers, | |||||
| proxies=proxies, | |||||
| timeout=self._param.timeout) | |||||
| if self._param.datatype.lower() == 'json': | |||||
| response = requests.post(url=url, | |||||
| json=args, | |||||
| headers=headers, | |||||
| proxies=proxies, | |||||
| timeout=self._param.timeout) | |||||
| else: | |||||
| response = requests.post(url=url, | |||||
| data=args, | |||||
| headers=headers, | |||||
| proxies=proxies, | |||||
| timeout=self._param.timeout) | |||||
| if self._param.clean_html: | if self._param.clean_html: | ||||
| sections = HtmlParser()(None, response.content) | sections = HtmlParser()(None, response.content) | ||||
| return Invoke.be_output("\n".join(sections)) | return Invoke.be_output("\n".join(sections)) |
| 'Allows sentence rewriting with the specified language or defaults to the latest question if not selected.', | 'Allows sentence rewriting with the specified language or defaults to the latest question if not selected.', | ||||
| avatarHidden: 'Hide avatar', | avatarHidden: 'Hide avatar', | ||||
| locale: 'Locale', | locale: 'Locale', | ||||
| selectLanguage: 'Select a language', | |||||
| reasoning: 'Reasoning', | reasoning: 'Reasoning', | ||||
| reasoningTip: | reasoningTip: | ||||
| 'It will trigger reasoning process like Deepseek-R1/OpenAI o1. Integrates an agentic search process into the reasoning workflow, allowing models itself to dynamically retrieve external knowledge whenever they encounter uncertain information.', | 'It will trigger reasoning process like Deepseek-R1/OpenAI o1. Integrates an agentic search process into the reasoning workflow, allowing models itself to dynamically retrieve external knowledge whenever they encounter uncertain information.', | ||||
| bingDescription: | bingDescription: | ||||
| 'A component that searches from https://www.bing.com/, allowing you to specify the number of search results using TopN. It supplements the existing knowledge bases. Please note that this requires an API key from microsoft.com.', | 'A component that searches from https://www.bing.com/, allowing you to specify the number of search results using TopN. It supplements the existing knowledge bases. Please note that this requires an API key from microsoft.com.', | ||||
| apiKey: 'API KEY', | apiKey: 'API KEY', | ||||
| country: 'Country&Region', | |||||
| country: 'Country & Region', | |||||
| language: 'Language', | language: 'Language', | ||||
| googleScholar: 'Google Scholar', | googleScholar: 'Google Scholar', | ||||
| googleScholarDescription: | googleScholarDescription: | ||||
| addCategory: 'Add category', | addCategory: 'Add category', | ||||
| categoryName: 'Category name', | categoryName: 'Category name', | ||||
| nextStep: 'Next step', | nextStep: 'Next step', | ||||
| datatype: 'MINE type of the HTTP request', | |||||
| insertVariableTip: `Enter / Insert variables`, | insertVariableTip: `Enter / Insert variables`, | ||||
| }, | }, | ||||
| footer: { | footer: { |
| }`, | }`, | ||||
| proxy: 'http://', | proxy: 'http://', | ||||
| clean_html: false, | clean_html: false, | ||||
| datatype: 'json', | |||||
| }; | }; | ||||
| export const initialTemplateValues = { | export const initialTemplateValues = { |
| > | > | ||||
| <Switch /> | <Switch /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item name={'datatype'} label={t('flow.datatype')}> | |||||
| <Select | |||||
| options={[ | |||||
| { value: 'json', label: 'application/json' }, | |||||
| { value: 'formdata', label: 'multipart/form-data' }, | |||||
| ]} | |||||
| allowClear={true} | |||||
| ></Select> | |||||
| </Form.Item> | |||||
| <DynamicVariablesForm node={node}></DynamicVariablesForm> | <DynamicVariablesForm node={node}></DynamicVariablesForm> | ||||
| </Form> | </Form> | ||||
| </> | </> |