mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-22 05:01:07 +03:00
5a37227d14
* markdown files and env examples cleanup * components update * update jsonlines description * server refractor * update telemetry * add execute custom node * add ui refractor * add username and password authenticate * correctly retrieve past images in agentflowv2 * disable e2e temporarily * add existing username and password authenticate * update migration to default workspace * update todo * blob storage migrating * throw error on agent tool call error * add missing execution import * add referral * chore: add error message when importData is undefined * migrate api keys to db * fix: data too long for column executionData * migrate api keys from json to db at init * add info on account setup * update docstore missing fields --------- Co-authored-by: chungyau97 <chungyau97@gmail.com>
139 lines
5.6 KiB
TypeScript
139 lines
5.6 KiB
TypeScript
import { BaseLanguageModel } from '@langchain/core/language_models/base'
|
|
import { PromptTemplate } from '@langchain/core/prompts'
|
|
import { APIChain } from 'langchain/chains'
|
|
import { getBaseClasses } from '../../../src/utils'
|
|
import { ICommonObject, INode, INodeData, INodeParams, IServerSideEventStreamer } from '../../../src/Interface'
|
|
import { ConsoleCallbackHandler, CustomChainHandler, additionalCallbacks } from '../../../src/handler'
|
|
|
|
export const API_URL_RAW_PROMPT_TEMPLATE = `You are given the below API Documentation:
|
|
{api_docs}
|
|
Using this documentation, generate the full API url to call for answering the user question.
|
|
You should build the API url in order to get a response that is as short as possible, while still getting the necessary information to answer the question. Pay attention to deliberately exclude any unnecessary pieces of data in the API call.
|
|
|
|
Question:{question}
|
|
API url:`
|
|
|
|
export const API_RESPONSE_RAW_PROMPT_TEMPLATE =
|
|
'Given this {api_response} response for {api_url}. use the given response to answer this {question}'
|
|
|
|
class GETApiChain_Chains implements INode {
|
|
label: string
|
|
name: string
|
|
version: number
|
|
type: string
|
|
icon: string
|
|
category: string
|
|
baseClasses: string[]
|
|
description: string
|
|
inputs: INodeParams[]
|
|
|
|
constructor() {
|
|
this.label = 'GET API Chain'
|
|
this.name = 'getApiChain'
|
|
this.version = 1.0
|
|
this.type = 'GETApiChain'
|
|
this.icon = 'get.svg'
|
|
this.category = 'Chains'
|
|
this.description = 'Chain to run queries against GET API'
|
|
this.baseClasses = [this.type, ...getBaseClasses(APIChain)]
|
|
this.inputs = [
|
|
{
|
|
label: 'Language Model',
|
|
name: 'model',
|
|
type: 'BaseLanguageModel'
|
|
},
|
|
{
|
|
label: 'API Documentation',
|
|
name: 'apiDocs',
|
|
type: 'string',
|
|
description:
|
|
'Description of how API works. Please refer to more <a target="_blank" href="https://github.com/langchain-ai/langchain/blob/master/libs/langchain/langchain/chains/api/open_meteo_docs.py">examples</a>',
|
|
rows: 4
|
|
},
|
|
{
|
|
label: 'Headers',
|
|
name: 'headers',
|
|
type: 'json',
|
|
additionalParams: true,
|
|
optional: true
|
|
},
|
|
{
|
|
label: 'URL Prompt',
|
|
name: 'urlPrompt',
|
|
type: 'string',
|
|
description: 'Prompt used to tell LLMs how to construct the URL. Must contains {api_docs} and {question}',
|
|
default: API_URL_RAW_PROMPT_TEMPLATE,
|
|
rows: 4,
|
|
additionalParams: true
|
|
},
|
|
{
|
|
label: 'Answer Prompt',
|
|
name: 'ansPrompt',
|
|
type: 'string',
|
|
description:
|
|
'Prompt used to tell LLMs how to return the API response. Must contains {api_response}, {api_url}, and {question}',
|
|
default: API_RESPONSE_RAW_PROMPT_TEMPLATE,
|
|
rows: 4,
|
|
additionalParams: true
|
|
}
|
|
]
|
|
}
|
|
|
|
async init(nodeData: INodeData): Promise<any> {
|
|
const model = nodeData.inputs?.model as BaseLanguageModel
|
|
const apiDocs = nodeData.inputs?.apiDocs as string
|
|
const headers = nodeData.inputs?.headers as string
|
|
const urlPrompt = nodeData.inputs?.urlPrompt as string
|
|
const ansPrompt = nodeData.inputs?.ansPrompt as string
|
|
|
|
const chain = await getAPIChain(apiDocs, model, headers, urlPrompt, ansPrompt)
|
|
return chain
|
|
}
|
|
|
|
async run(nodeData: INodeData, input: string, options: ICommonObject): Promise<string> {
|
|
const model = nodeData.inputs?.model as BaseLanguageModel
|
|
const apiDocs = nodeData.inputs?.apiDocs as string
|
|
const headers = nodeData.inputs?.headers as string
|
|
const urlPrompt = nodeData.inputs?.urlPrompt as string
|
|
const ansPrompt = nodeData.inputs?.ansPrompt as string
|
|
|
|
const chain = await getAPIChain(apiDocs, model, headers, urlPrompt, ansPrompt)
|
|
const loggerHandler = new ConsoleCallbackHandler(options.logger, options?.orgId)
|
|
const callbacks = await additionalCallbacks(nodeData, options)
|
|
const shouldStreamResponse = options.shouldStreamResponse
|
|
const sseStreamer: IServerSideEventStreamer = options.sseStreamer as IServerSideEventStreamer
|
|
const chatId = options.chatId
|
|
|
|
if (shouldStreamResponse) {
|
|
const handler = new CustomChainHandler(sseStreamer, chatId)
|
|
const res = await chain.run(input, [loggerHandler, handler, ...callbacks])
|
|
return res
|
|
} else {
|
|
const res = await chain.run(input, [loggerHandler, ...callbacks])
|
|
return res
|
|
}
|
|
}
|
|
}
|
|
|
|
const getAPIChain = async (documents: string, llm: BaseLanguageModel, headers: string, urlPrompt: string, ansPrompt: string) => {
|
|
const apiUrlPrompt = new PromptTemplate({
|
|
inputVariables: ['api_docs', 'question'],
|
|
template: urlPrompt ? urlPrompt : API_URL_RAW_PROMPT_TEMPLATE
|
|
})
|
|
|
|
const apiResponsePrompt = new PromptTemplate({
|
|
inputVariables: ['api_docs', 'question', 'api_url', 'api_response'],
|
|
template: ansPrompt ? ansPrompt : API_RESPONSE_RAW_PROMPT_TEMPLATE
|
|
})
|
|
|
|
const chain = APIChain.fromLLMAndAPIDocs(llm, documents, {
|
|
apiUrlPrompt,
|
|
apiResponsePrompt,
|
|
verbose: process.env.DEBUG === 'true' ? true : false,
|
|
headers: typeof headers === 'object' ? headers : headers ? JSON.parse(headers) : {}
|
|
})
|
|
return chain
|
|
}
|
|
|
|
module.exports = { nodeClass: GETApiChain_Chains }
|