2023-11-29 03:13:55 -08:00
/* eslint-disable n8n-nodes-base/node-dirname-against-convention */
import {
NodeConnectionType ,
type IExecuteFunctions ,
type INodeType ,
type INodeTypeDescription ,
type SupplyData ,
} from 'n8n-workflow' ;
2024-03-07 02:36:36 -08:00
import { HuggingFaceInference } from '@langchain/community/llms/hf' ;
2023-11-29 03:13:55 -08:00
import { logWrapper } from '../../../utils/logWrapper' ;
import { getConnectionHintNoticeField } from '../../../utils/sharedFields' ;
export class LmOpenHuggingFaceInference implements INodeType {
description : INodeTypeDescription = {
displayName : 'Hugging Face Inference Model' ,
// eslint-disable-next-line n8n-nodes-base/node-class-description-name-miscased
name : 'lmOpenHuggingFaceInference' ,
icon : 'file:huggingface.svg' ,
group : [ 'transform' ] ,
version : 1 ,
description : 'Language Model HuggingFaceInference' ,
defaults : {
name : 'Hugging Face Inference Model' ,
} ,
codex : {
categories : [ 'AI' ] ,
subcategories : {
AI : [ 'Language Models' ] ,
} ,
resources : {
primaryDocumentation : [
{
url : 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmopenhuggingfaceinference/' ,
} ,
] ,
} ,
} ,
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
inputs : [ ] ,
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
outputs : [ NodeConnectionType . AiLanguageModel ] ,
outputNames : [ 'Model' ] ,
credentials : [
{
name : 'huggingFaceApi' ,
required : true ,
} ,
] ,
properties : [
getConnectionHintNoticeField ( [ NodeConnectionType . AiChain , NodeConnectionType . AiAgent ] ) ,
{
displayName : 'Model' ,
name : 'model' ,
type : 'string' ,
default : 'gpt2' ,
} ,
{
displayName : 'Options' ,
name : 'options' ,
placeholder : 'Add Option' ,
description : 'Additional options to add' ,
type : 'collection' ,
default : { } ,
options : [
{
displayName : 'Custom Inference Endpoint' ,
name : 'endpointUrl' ,
default : '' ,
description : 'Custom endpoint URL' ,
type : 'string' ,
} ,
{
displayName : 'Frequency Penalty' ,
name : 'frequencyPenalty' ,
default : 0 ,
typeOptions : { maxValue : 2 , minValue : - 2 , numberPrecision : 1 } ,
description :
"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim" ,
type : 'number' ,
} ,
{
displayName : 'Maximum Number of Tokens' ,
name : 'maxTokens' ,
default : 128 ,
description :
'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).' ,
type : 'number' ,
typeOptions : {
maxValue : 32768 ,
} ,
} ,
{
displayName : 'Presence Penalty' ,
name : 'presencePenalty' ,
default : 0 ,
typeOptions : { maxValue : 2 , minValue : - 2 , numberPrecision : 1 } ,
description :
"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics" ,
type : 'number' ,
} ,
{
displayName : 'Sampling Temperature' ,
name : 'temperature' ,
default : 1 ,
typeOptions : { maxValue : 1 , minValue : 0 , numberPrecision : 1 } ,
description :
'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.' ,
type : 'number' ,
} ,
{
displayName : 'Top K' ,
name : 'topK' ,
default : 1 ,
typeOptions : { maxValue : 1 , minValue : 0 , numberPrecision : 1 } ,
description :
'Controls the top tokens to consider within the sample operation to create new text' ,
type : 'number' ,
} ,
{
displayName : 'Top P' ,
name : 'topP' ,
default : 1 ,
typeOptions : { maxValue : 1 , minValue : 0 , numberPrecision : 1 } ,
description :
'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.' ,
type : 'number' ,
} ,
] ,
} ,
] ,
} ;
async supplyData ( this : IExecuteFunctions , itemIndex : number ) : Promise < SupplyData > {
const credentials = await this . getCredentials ( 'huggingFaceApi' ) ;
const modelName = this . getNodeParameter ( 'model' , itemIndex ) as string ;
const options = this . getNodeParameter ( 'options' , itemIndex , { } ) as object ;
const model = new HuggingFaceInference ( {
model : modelName ,
apiKey : credentials.apiKey as string ,
. . . options ,
} ) ;
return {
response : logWrapper ( model , this ) ,
} ;
}
}