n8n-nodes-smartgent
Version:
SmartGent custom nodes for n8n - AI-powered automation and intelligent workflow integrations including LiteLLM chat completions, SharePoint file monitoring, and enterprise search
459 lines • 20.8 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SmartgentChat = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const axios_1 = __importDefault(require("axios"));
class SmartgentChat {
constructor() {
this.description = {
displayName: 'SmartGent Chat',
name: 'smartgentChat',
icon: 'file:smartgent.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["model"]}}',
description: 'Interact with SmartGent chat completions API',
defaults: {
name: 'SmartGent Chat',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'smartGentLiteLlmApi',
required: true,
},
],
requestDefaults: {
ignoreHttpStatusErrors: true,
},
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Chat Completion',
value: 'chatCompletion',
description: 'Generate a chat completion',
action: 'Generate a chat completion',
},
],
default: 'chatCompletion',
},
{
displayName: 'Model Name or ID',
name: 'model',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getModels',
},
default: '',
required: true,
description: 'The model to use for the completion. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
displayOptions: {
show: {
operation: ['chatCompletion'],
},
},
},
{
displayName: 'Messages',
name: 'messages',
placeholder: 'Add message',
type: 'fixedCollection',
default: {},
typeOptions: {
multipleValues: true,
},
description: 'The messages to generate chat completions for',
options: [
{
name: 'values',
displayName: 'Message',
values: [
{
displayName: 'Role',
name: 'role',
type: 'options',
options: [
{
name: 'System',
value: 'system',
},
{
name: 'User',
value: 'user',
},
{
name: 'Assistant',
value: 'assistant',
},
],
default: 'user',
description: 'The role of the author of this message',
},
{
displayName: 'Content Type',
name: 'contentType',
type: 'options',
options: [
{
name: 'Text Only',
value: 'text',
},
],
default: 'text',
description: 'The type of content in this message',
displayOptions: {
show: {
role: ['system'],
},
},
},
{
displayName: 'Content Type',
name: 'contentType',
type: 'options',
options: [
{
name: 'Text Only',
value: 'text',
},
{
name: 'Text + File',
value: 'mixed',
},
],
default: 'text',
description: 'The type of content in this message',
displayOptions: {
show: {
role: ['user', 'assistant'],
},
},
},
{
displayName: 'Text',
name: 'text',
type: 'string',
default: '',
description: 'The text content of the message',
displayOptions: {
show: {
contentType: ['text'],
},
},
},
{
displayName: 'Prompt Text',
name: 'promptText',
type: 'string',
default: '',
description: 'The text content of the message',
displayOptions: {
show: {
contentType: ['mixed'],
},
},
},
{
displayName: 'File URLs',
name: 'fileUrls',
placeholder: 'Add file URL',
type: 'fixedCollection',
default: {},
typeOptions: {
multipleValues: true,
},
description: 'URLs to the files to include in the message',
options: [
{
name: 'values',
displayName: 'File URL',
values: [
{
displayName: 'URL',
name: 'url',
type: 'string',
default: '',
description: 'URL to the file to include in the message',
},
],
},
],
displayOptions: {
show: {
contentType: ['mixed'],
},
},
},
],
},
],
displayOptions: {
show: {
operation: ['chatCompletion'],
},
},
},
{
displayName: 'Response Format',
name: 'responseFormat',
type: 'options',
options: [
{
name: 'Default',
value: 'default',
description: 'Default response format',
},
{
name: 'JSON Object',
value: 'json_object',
description: 'Force the response to be a valid JSON object',
},
{
name: 'Structured JSON Schema',
value: 'json_schema',
description: 'Provide a custom JSON schema for structured outputs',
},
],
default: 'default',
description: 'The format of the response',
displayOptions: {
show: {
operation: ['chatCompletion'],
},
},
},
{
displayName: 'Structured Output',
name: 'structuredOutput',
type: 'collection',
placeholder: 'Add Schema Details',
default: {},
options: [
{
displayName: 'Schema Name',
name: 'schemaName',
type: 'string',
default: '',
placeholder: 'event',
description: 'Identifier for the schema passed to the API',
},
{
displayName: 'Schema JSON',
name: 'schemaJson',
type: 'string',
typeOptions: {
rows: 5,
},
default: '',
description: 'JSON schema describing the structured response (e.g. {"type":"object","properties":{...}})',
},
],
displayOptions: {
show: {
operation: ['chatCompletion'],
responseFormat: ['json_schema'],
},
},
},
{
displayName: 'Enable Thinking',
name: 'enableThinking',
type: 'boolean',
default: false,
description: 'Whether to enable thinking mode with budget tokens',
displayOptions: {
show: {
operation: ['chatCompletion'],
},
},
},
{
displayName: 'Budget Tokens',
name: 'budgetTokens',
type: 'number',
default: 0,
description: 'The maximum number of tokens to use for thinking',
displayOptions: {
show: {
operation: ['chatCompletion'],
enableThinking: [true],
},
},
},
{
displayName: 'Temperature',
name: 'temperature',
type: 'number',
default: 0,
typeOptions: {
minValue: 0,
maxValue: 2,
numberStepSize: 0.1,
},
description: 'Controls randomness in the response. 0 = deterministic, 2 = very random.',
displayOptions: {
show: {
operation: ['chatCompletion'],
},
},
},
],
};
this.methods = {
loadOptions: {
async getModels() {
try {
const credentials = await this.getCredentials('smartGentLiteLlmApi');
const response = await axios_1.default.get(`${credentials.baseUrl}/v1/models`, {
headers: {
Authorization: `Bearer ${credentials.apiKey}`,
'Content-Type': 'application/json',
},
});
const models = response.data.data || [];
return models.map((model) => ({
name: model.id,
value: model.id,
description: `${model.object}`,
}));
}
catch (error) {
return [];
}
},
},
};
}
async execute() {
var _a;
const items = this.getInputData();
const returnData = [];
const operation = this.getNodeParameter('operation', 0);
for (let i = 0; i < items.length; i++) {
try {
if (operation === 'chatCompletion') {
const model = this.getNodeParameter('model', i);
const messagesInput = this.getNodeParameter('messages.values', i, []);
const responseFormat = this.getNodeParameter('responseFormat', i);
const enableThinking = this.getNodeParameter('enableThinking', i);
const temperature = this.getNodeParameter('temperature', i);
const credentials = await this.getCredentials('smartGentLiteLlmApi');
const messages = messagesInput.map((message) => {
var _a;
if (message.contentType === 'text') {
return {
role: message.role,
content: message.text,
};
}
else if (message.contentType === 'mixed') {
const content = [
{
type: 'text',
text: message.promptText,
},
];
const fileUrls = ((_a = message.fileUrls) === null || _a === void 0 ? void 0 : _a.values) || [];
for (const fileUrlEntry of fileUrls) {
content.push({
type: 'image_url',
image_url: {
url: fileUrlEntry.url,
},
});
}
return {
role: message.role,
content,
};
}
return {
role: message.role,
content: message.text || '',
};
});
const completionParams = {
model,
messages,
};
if (temperature !== undefined && temperature !== null) {
completionParams.temperature = temperature;
}
if (responseFormat === 'json_object') {
completionParams.response_format = { type: 'json_object' };
}
else if (responseFormat === 'json_schema') {
const structuredOutput = this.getNodeParameter('structuredOutput', i, {});
if (!structuredOutput.schemaJson) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Structured output schema JSON is required when response format is Structured JSON Schema.', { itemIndex: i });
}
let parsedSchema;
try {
parsedSchema = JSON.parse(structuredOutput.schemaJson);
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Structured output schema JSON must be valid JSON.', { itemIndex: i });
}
const schemaName = ((_a = structuredOutput.schemaName) !== null && _a !== void 0 ? _a : '').trim() !== ''
? structuredOutput.schemaName.trim()
: 'structured_response';
completionParams.response_format = {
type: 'json_schema',
json_schema: {
name: schemaName,
schema: parsedSchema,
},
};
}
if (enableThinking) {
const budgetTokens = this.getNodeParameter('budgetTokens', i);
completionParams.thinking = {
type: 'enabled',
budget_tokens: budgetTokens,
};
}
const response = await axios_1.default.post(`${credentials.baseUrl}/v1/chat/completions`, completionParams, {
headers: {
Authorization: `Bearer ${credentials.apiKey}`,
'Content-Type': 'application/json',
},
});
returnData.push({
json: response.data,
pairedItem: {
item: i,
},
});
}
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: error.message,
},
pairedItem: {
item: i,
},
});
continue;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
itemIndex: i,
});
}
}
return this.prepareOutputData(returnData);
}
}
exports.SmartgentChat = SmartgentChat;
//# sourceMappingURL=SmartgentChat.node.js.map