Skip to content

Commit

Permalink
Bugfix/Restore Requests Tool (FlowiseAI#2513)
Browse files Browse the repository at this point in the history
restore requests tool
  • Loading branch information
HenryHengZJ authored May 29, 2024
1 parent 2878af6 commit 48ac815
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 0 deletions.
72 changes: 72 additions & 0 deletions packages/components/nodes/tools/RequestsGet/RequestsGet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
import { desc, RequestParameters, RequestsGetTool } from './core'

class RequestsGet_Tools implements INode {
label: string
name: string
version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]

constructor() {
this.label = 'Requests Get'
this.name = 'requestsGet'
this.version = 1.0
this.type = 'RequestsGet'
this.icon = 'requestsget.svg'
this.category = 'Tools'
this.description = 'Execute HTTP GET requests'
this.baseClasses = [this.type, ...getBaseClasses(RequestsGetTool)]
this.inputs = [
{
label: 'URL',
name: 'url',
type: 'string',
description:
'Agent will make call to this exact URL. If not specified, agent will try to figure out itself from AIPlugin if provided',
additionalParams: true,
optional: true
},
{
label: 'Description',
name: 'description',
type: 'string',
rows: 4,
default: desc,
description: 'Acts like a prompt to tell agent when it should use this tool',
additionalParams: true,
optional: true
},
{
label: 'Headers',
name: 'headers',
type: 'json',
additionalParams: true,
optional: true
}
]
}

async init(nodeData: INodeData): Promise<any> {
const headers = nodeData.inputs?.headers as string
const url = nodeData.inputs?.url as string
const description = nodeData.inputs?.description as string

const obj: RequestParameters = {}
if (url) obj.url = url
if (description) obj.description = description
if (headers) {
const parsedHeaders = typeof headers === 'object' ? headers : JSON.parse(headers)
obj.headers = parsedHeaders
}

return new RequestsGetTool(obj)
}
}

module.exports = { nodeClass: RequestsGet_Tools }
46 changes: 46 additions & 0 deletions packages/components/nodes/tools/RequestsGet/core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import fetch from 'node-fetch'
import { Tool } from '@langchain/core/tools'

export const desc = `A portal to the internet. Use this when you need to get specific content from a website.
Input should be a url (i.e. https://www.google.com). The output will be the text response of the GET request.`

export interface Headers {
[key: string]: string
}

export interface RequestParameters {
headers?: Headers
url?: string
description?: string
maxOutputLength?: number
}

export class RequestsGetTool extends Tool {
name = 'requests_get'
url = ''
description = desc
maxOutputLength = 2000
headers = {}

constructor(args?: RequestParameters) {
super()
this.url = args?.url ?? this.url
this.headers = args?.headers ?? this.headers
this.description = args?.description ?? this.description
this.maxOutputLength = args?.maxOutputLength ?? this.maxOutputLength
}

/** @ignore */
async _call(input: string) {
const inputUrl = !this.url ? input : this.url

if (process.env.DEBUG === 'true') console.info(`Making GET API call to ${inputUrl}`)

const res = await fetch(inputUrl, {
headers: this.headers
})

const text = await res.text()
return text.slice(0, this.maxOutputLength)
}
}
6 changes: 6 additions & 0 deletions packages/components/nodes/tools/RequestsGet/requestsget.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 86 additions & 0 deletions packages/components/nodes/tools/RequestsPost/RequestsPost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses } from '../../../src/utils'
import { RequestParameters, desc, RequestsPostTool } from './core'

class RequestsPost_Tools implements INode {
label: string
name: string
version: number
description: string
type: string
icon: string
category: string
baseClasses: string[]
inputs: INodeParams[]

constructor() {
this.label = 'Requests Post'
this.name = 'requestsPost'
this.version = 1.0
this.type = 'RequestsPost'
this.icon = 'requestspost.svg'
this.category = 'Tools'
this.description = 'Execute HTTP POST requests'
this.baseClasses = [this.type, ...getBaseClasses(RequestsPostTool)]
this.inputs = [
{
label: 'URL',
name: 'url',
type: 'string',
description:
'Agent will make call to this exact URL. If not specified, agent will try to figure out itself from AIPlugin if provided',
additionalParams: true,
optional: true
},
{
label: 'Body',
name: 'body',
type: 'json',
description:
'JSON body for the POST request. If not specified, agent will try to figure out itself from AIPlugin if provided',
additionalParams: true,
optional: true
},
{
label: 'Description',
name: 'description',
type: 'string',
rows: 4,
default: desc,
description: 'Acts like a prompt to tell agent when it should use this tool',
additionalParams: true,
optional: true
},
{
label: 'Headers',
name: 'headers',
type: 'json',
additionalParams: true,
optional: true
}
]
}

async init(nodeData: INodeData): Promise<any> {
const headers = nodeData.inputs?.headers as string
const url = nodeData.inputs?.url as string
const description = nodeData.inputs?.description as string
const body = nodeData.inputs?.body as string

const obj: RequestParameters = {}
if (url) obj.url = url
if (description) obj.description = description
if (headers) {
const parsedHeaders = typeof headers === 'object' ? headers : JSON.parse(headers)
obj.headers = parsedHeaders
}
if (body) {
const parsedBody = typeof body === 'object' ? body : JSON.parse(body)
obj.body = parsedBody
}

return new RequestsPostTool(obj)
}
}

module.exports = { nodeClass: RequestsPost_Tools }
72 changes: 72 additions & 0 deletions packages/components/nodes/tools/RequestsPost/core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Tool } from '@langchain/core/tools'
import fetch from 'node-fetch'

export const desc = `Use this when you want to POST to a website.
Input should be a json string with two keys: "url" and "data".
The value of "url" should be a string, and the value of "data" should be a dictionary of
key-value pairs you want to POST to the url as a JSON body.
Be careful to always use double quotes for strings in the json string
The output will be the text response of the POST request.`

export interface Headers {
[key: string]: string
}

export interface Body {
[key: string]: any
}

export interface RequestParameters {
headers?: Headers
body?: Body
url?: string
description?: string
maxOutputLength?: number
}

export class RequestsPostTool extends Tool {
name = 'requests_post'
url = ''
description = desc
maxOutputLength = Infinity
headers = {}
body = {}

constructor(args?: RequestParameters) {
super()
this.url = args?.url ?? this.url
this.headers = args?.headers ?? this.headers
this.body = args?.body ?? this.body
this.description = args?.description ?? this.description
this.maxOutputLength = args?.maxOutputLength ?? this.maxOutputLength
}

/** @ignore */
async _call(input: string) {
try {
let inputUrl = ''
let inputBody = {}
if (Object.keys(this.body).length || this.url) {
if (this.url) inputUrl = this.url
if (Object.keys(this.body).length) inputBody = this.body
} else {
const { url, data } = JSON.parse(input)
inputUrl = url
inputBody = data
}

if (process.env.DEBUG === 'true') console.info(`Making POST API call to ${inputUrl} with body ${JSON.stringify(inputBody)}`)

const res = await fetch(inputUrl, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(inputBody)
})

const text = await res.text()
return text.slice(0, this.maxOutputLength)
} catch (error) {
return `${error}`
}
}
}
7 changes: 7 additions & 0 deletions packages/components/nodes/tools/RequestsPost/requestspost.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 48ac815

Please sign in to comment.