Bläddra i källkod

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>
tags/v0.17.0
so95 8 månader sedan
förälder
incheckning
11de7599e5
Inget konto är kopplat till bidragsgivarens mejladress

+ 0
- 2
agent/component/exesql.py Visa fil

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("")

+ 26
- 10
agent/component/invoke.py Visa fil

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))

+ 3
- 1
web/src/locales/en.ts Visa fil

'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: {

+ 1
- 0
web/src/pages/flow/constant.tsx Visa fil

}`, }`,
proxy: 'http://', proxy: 'http://',
clean_html: false, clean_html: false,
datatype: 'json',
}; };


export const initialTemplateValues = { export const initialTemplateValues = {

+ 9
- 0
web/src/pages/flow/form/invoke-form/index.tsx Visa fil

> >
<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>
</> </>

Laddar…
Avbryt
Spara