mirror of
				https://github.com/infiniflow/ragflow.git
				synced 2025-11-04 11:49:37 +00:00 
			
		
		
		
	Feat: add data type invoke (#5126)
### 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>
This commit is contained in:
		
							parent
							
								
									7a6e70d6b3
								
							
						
					
					
						commit
						11de7599e5
					
				@ -79,7 +79,6 @@ class ExeSQL(Generate, ABC):
 | 
				
			|||||||
        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)
 | 
				
			||||||
@ -128,7 +127,6 @@ class ExeSQL(Generate, ABC):
 | 
				
			|||||||
                    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("")
 | 
				
			||||||
 | 
				
			|||||||
@ -35,12 +35,14 @@ class InvokeParam(ComponentParamBase):
 | 
				
			|||||||
        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):
 | 
				
			||||||
@ -94,22 +96,36 @@ 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,
 | 
					            if self._param.datatype.lower() == 'json':
 | 
				
			||||||
                                    json=args,
 | 
					                response = requests.put(url=url,
 | 
				
			||||||
                                    headers=headers,
 | 
					                                        json=args,
 | 
				
			||||||
                                    proxies=proxies,
 | 
					                                        headers=headers,
 | 
				
			||||||
                                    timeout=self._param.timeout)
 | 
					                                        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,
 | 
					            if self._param.datatype.lower() == 'json':
 | 
				
			||||||
                                    json=args,
 | 
					                response = requests.post(url=url,
 | 
				
			||||||
                                    headers=headers,
 | 
					                                         json=args,
 | 
				
			||||||
                                    proxies=proxies,
 | 
					                                         headers=headers,
 | 
				
			||||||
                                    timeout=self._param.timeout)
 | 
					                                         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))
 | 
				
			||||||
 | 
				
			|||||||
@ -528,6 +528,7 @@ This auto-tag feature enhances retrieval by adding another layer of domain-speci
 | 
				
			|||||||
        '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.',
 | 
				
			||||||
@ -845,7 +846,7 @@ This auto-tag feature enhances retrieval by adding another layer of domain-speci
 | 
				
			|||||||
      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:
 | 
				
			||||||
@ -1187,6 +1188,7 @@ This delimiter is used to split the input text into several text pieces echo of
 | 
				
			|||||||
      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: {
 | 
				
			||||||
 | 
				
			|||||||
@ -606,6 +606,7 @@ export const initialInvokeValues = {
 | 
				
			|||||||
}`,
 | 
					}`,
 | 
				
			||||||
  proxy: 'http://',
 | 
					  proxy: 'http://',
 | 
				
			||||||
  clean_html: false,
 | 
					  clean_html: false,
 | 
				
			||||||
 | 
					  datatype: 'json',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const initialTemplateValues = {
 | 
					export const initialTemplateValues = {
 | 
				
			||||||
 | 
				
			|||||||
@ -69,6 +69,15 @@ const InvokeForm = ({ onValuesChange, form, node }: IOperatorForm) => {
 | 
				
			|||||||
        >
 | 
					        >
 | 
				
			||||||
          <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>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user