n8n-nodes-openai-analytics
Version:
n8n node for OpenAI Analytics
1,198 lines • 125 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenAIAnalytics = void 0;
const openai_1 = __importDefault(require("openai"));
const openai_2 = require("./helpers/openai");
const thread_1 = require("./actions/thread");
const assistant_1 = require("./actions/assistant");
const file_1 = require("./actions/file");
const text_1 = require("./actions/text");
const embedding_1 = require("./actions/embedding");
const report_1 = require("./actions/report");
// Assistant API에서 사용할 loadOptions 메서드 정의
const loadOptions = {
// Assistant 목록을 로드하는 메서드
async getAssistants() {
// OpenAI API 옵션 초기화
const openaiOptions = {};
let credentials;
try {
const authentication = this.getNodeParameter('authentication', 'openAIAnalyticsApi');
if (authentication === 'openAIAnalyticsApi') {
credentials = await this.getCredentials('openAIAnalyticsApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organizationId) {
openaiOptions.organization = credentials.organizationId;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
else {
credentials = await this.getCredentials('openAiApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organization) {
openaiOptions.organization = credentials.organization;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
}
catch (error) {
// 자격 증명 로드 오류 시 기본값 시도
try {
credentials = await this.getCredentials('openAIAnalyticsApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organizationId) {
openaiOptions.organization = credentials.organizationId;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
catch (error) {
console.error('Error loading credentials:', error);
return [{ name: 'Error loading credentials', value: '' }];
}
}
const openai = new openai_1.default(openaiOptions);
// Assistants 목록 가져오기
try {
const assistantsList = await openai.beta.assistants.list({
limit: 100,
});
if (!assistantsList.data || assistantsList.data.length === 0) {
return [{ name: 'No assistants found', value: '' }];
}
// 이름과 ID를 포함한 옵션 목록 생성
const options = assistantsList.data.map((assistant) => ({
name: assistant.name || `Assistant (${assistant.id})`,
value: assistant.id,
}));
return options;
}
catch (error) {
console.error('Error loading assistants:', error);
return [{ name: 'Error loading assistants', value: '' }];
}
},
// 파일 목록을 로드하는 메서드
async getFiles() {
const options = this.getNodeParameter('downloadFilePurpose', 'all');
let purpose;
// 파일 목적에 따라 쿼리 파라미터 설정
if (options && options !== 'all') {
purpose = options;
}
// OpenAI API 클라이언트 초기화
const openaiCredentials = await this.getCredentials('openAiApi');
const openaiOptions = {
apiKey: openaiCredentials.apiKey,
};
// 조직이 설정된 경우 추가
if (openaiCredentials.organization) {
openaiOptions.organization = openaiCredentials.organization;
}
// 기본 URL이 설정된 경우 추가
if (openaiCredentials.baseURL) {
openaiOptions.baseURL = openaiCredentials.baseURL;
}
const openai = new openai_1.default(openaiOptions);
try {
// 파일 목록 가져오기
const response = await openai.files.list(purpose ? { purpose } : {});
// 옵션 배열로 변환
return response.data.map((file) => ({
name: `${file.filename} (${file.id})`,
value: file.id,
description: `Purpose: ${file.purpose}, Size: ${Math.round(file.bytes / 1024)} KB`,
}));
}
catch (error) {
console.error('Error loading files:', error);
return [{ name: 'Error loading files', value: '' }];
}
},
// 임베딩 모델 목록을 로드하는 메서드
async getEmbeddingModels() {
// OpenAI API 옵션 초기화
const openaiOptions = {};
let credentials;
try {
const authentication = this.getNodeParameter('authentication', 'openAIAnalyticsApi');
if (authentication === 'openAIAnalyticsApi') {
credentials = await this.getCredentials('openAIAnalyticsApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organizationId) {
openaiOptions.organization = credentials.organizationId;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
else {
credentials = await this.getCredentials('openAiApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organization) {
openaiOptions.organization = credentials.organization;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
}
catch (error) {
// 자격 증명 로드 오류 시 기본값 시도
try {
credentials = await this.getCredentials('openAIAnalyticsApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organizationId) {
openaiOptions.organization = credentials.organizationId;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
catch (error) {
console.error('Error loading credentials:', error);
return [{ name: 'Error loading credentials', value: '' }];
}
}
const openai = new openai_1.default(openaiOptions);
// 모델 목록 가져오기
try {
const modelsList = await openai.models.list();
if (!modelsList.data || modelsList.data.length === 0) {
return [{ name: 'No models found', value: '' }];
}
// 임베딩 모델만 필터링 - 더 정확한 임베딩 모델 필터링
const embeddingModels = modelsList.data.filter((model) => (model.id.includes('embedding') ||
model.id.includes('embed') ||
model.id.startsWith('text-embedding')));
// 기본 임베딩 모델 (항상 표시)
const defaultEmbeddingModels = [
{ name: 'text-embedding-3-small', value: 'text-embedding-3-small', description: '최신 임베딩 모델, 1536 차원' },
{ name: 'text-embedding-3-large', value: 'text-embedding-3-large', description: '최고 성능 임베딩 모델, 3072 차원' },
{ name: 'text-embedding-ada-002', value: 'text-embedding-ada-002', description: '이전 세대 임베딩 모델, 1536 차원' },
];
if (embeddingModels.length === 0) {
// 임베딩 모델이 없으면 기본 모델 목록만 제공
return defaultEmbeddingModels;
}
// 이름과 ID를 포함한 옵션 목록 생성
let options = embeddingModels.map((model) => ({
name: model.id,
value: model.id,
description: getEmbeddingModelDescription(model.id),
}));
// 모델 정렬: 최신 모델이 위에 오도록
options.sort((a, b) => {
// text-embedding-3 모델이 가장 위에
if (a.value.includes('text-embedding-3') && !b.value.includes('text-embedding-3'))
return -1;
if (!a.value.includes('text-embedding-3') && b.value.includes('text-embedding-3'))
return 1;
// 그 다음으로 ada-002 모델
if (a.value.includes('ada-002') && !b.value.includes('ada-002'))
return -1;
if (!a.value.includes('ada-002') && b.value.includes('ada-002'))
return 1;
// 그 외는 알파벳 순서로
return a.name.localeCompare(b.name);
});
// 기본 모델이 없으면 추가
for (const defaultModel of defaultEmbeddingModels) {
if (!options.some(option => option.value === defaultModel.value)) {
options.unshift(defaultModel);
}
}
// 중복 제거
const uniqueOptions = options.filter((option, index, self) => index === self.findIndex((t) => t.value === option.value));
return uniqueOptions;
}
catch (error) {
console.error('Error loading embedding models:', error);
// 오류 시 기본 임베딩 모델 제공
return [
{ name: 'text-embedding-3-small', value: 'text-embedding-3-small', description: '최신 임베딩 모델, 1536 차원' },
{ name: 'text-embedding-3-large', value: 'text-embedding-3-large', description: '최고 성능 임베딩 모델, 3072 차원' },
{ name: 'text-embedding-ada-002', value: 'text-embedding-ada-002', description: '이전 세대 임베딩 모델, 1536 차원' },
];
}
// 임베딩 모델 설명을 반환하는 헬퍼 함수
function getEmbeddingModelDescription(modelId) {
if (modelId === 'text-embedding-3-small')
return '최신 임베딩 모델, 1536 차원';
if (modelId === 'text-embedding-3-large')
return '최고 성능 임베딩 모델, 3072 차원';
if (modelId === 'text-embedding-ada-002')
return '이전 세대 임베딩 모델, 1536 차원';
if (modelId.includes('text-embedding-3'))
return '최신 세대 임베딩 모델';
if (modelId.includes('ada'))
return '이전 세대 임베딩 모델';
return '임베딩 모델';
}
},
// 완성 모델 목록을 로드하는 메서드
async getCompletionModels() {
// OpenAI API 옵션 초기화
const openaiOptions = {};
let credentials;
try {
const authentication = this.getNodeParameter('authentication', 'openAIAnalyticsApi');
if (authentication === 'openAIAnalyticsApi') {
credentials = await this.getCredentials('openAIAnalyticsApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organizationId) {
openaiOptions.organization = credentials.organizationId;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
else {
credentials = await this.getCredentials('openAiApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organization) {
openaiOptions.organization = credentials.organization;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
}
catch (error) {
// 자격 증명 로드 오류 시 기본값 시도
try {
credentials = await this.getCredentials('openAIAnalyticsApi');
openaiOptions.apiKey = credentials.apiKey;
if (credentials.organizationId) {
openaiOptions.organization = credentials.organizationId;
}
if (credentials.baseUrl) {
openaiOptions.baseURL = credentials.baseUrl;
}
else {
openaiOptions.baseURL = 'https://api.openai.com/v1';
}
}
catch (error) {
console.error('Error loading credentials:', error);
return [{ name: 'Error loading credentials', value: '' }];
}
}
const openai = new openai_1.default(openaiOptions);
// 모델 목록 가져오기
try {
const modelsList = await openai.models.list();
if (!modelsList.data || modelsList.data.length === 0) {
return [{ name: 'No models found', value: '' }];
}
// 완성 모델 필터링 (GPT 계열)
const completionModels = modelsList.data.filter((model) => model.id.includes('gpt') &&
!model.id.includes('embedding') &&
!model.id.includes('search'));
if (completionModels.length === 0) {
// 완성 모델이 없으면 기본 모델 목록 제공
return [
{ name: 'GPT-4.1 (gpt-4-1106-preview)', value: 'gpt-4-1106-preview' },
{ name: 'GPT-4o Mini', value: 'gpt-4o-mini' },
{ name: 'GPT-4o', value: 'gpt-4o' },
{ name: 'GPT-4 Turbo', value: 'gpt-4-turbo' },
{ name: 'GPT-4', value: 'gpt-4' },
{ name: 'GPT-3.5 Turbo', value: 'gpt-3.5-turbo' },
];
}
// 이름과 ID를 포함한 옵션 목록 생성
const options = completionModels.map((model) => ({
name: model.id,
value: model.id,
}));
// 모델 이름으로 정렬
options.sort((a, b) => a.name.localeCompare(b.name));
// 특정 모델들을 리스트의 맨 위로 이동 (우선순위 모델)
const gpt41 = 'gpt-4-1106-preview';
const gpt4o = 'gpt-4o';
const gpt4oMini = 'gpt-4o-mini';
// 특정 모델이 없으면 추가
const hasGpt41 = options.some(option => option.value === gpt41);
const hasGpt4o = options.some(option => option.value === gpt4o);
const hasGpt4oMini = options.some(option => option.value === gpt4oMini);
// 없는 모델 추가
if (!hasGpt41)
options.push({ name: 'GPT-4.1 (gpt-4-1106-preview)', value: gpt41 });
if (!hasGpt4o)
options.push({ name: 'GPT-4o', value: gpt4o });
if (!hasGpt4oMini)
options.push({ name: 'GPT-4o Mini', value: gpt4oMini });
// 우선순위 모델 찾아서 맨 위로 이동
const priorityModels = [gpt41, gpt4o, gpt4oMini];
const prioritizedOptions = [];
// 우선순위 모델 순서대로 맨 위로 이동
for (const modelId of priorityModels) {
const modelIndex = options.findIndex(option => option.value === modelId);
if (modelIndex !== -1) {
// 찾은 모델을 복사
let modelOption = options.splice(modelIndex, 1)[0];
// GPT-4.1에는 이름 수정
if (modelId === gpt41 && modelOption.name === gpt41) {
modelOption = { name: 'GPT-4.1 (gpt-4-1106-preview)', value: gpt41 };
}
prioritizedOptions.push(modelOption);
}
}
// 우선순위 모델과 나머지 모델 합치기
return [...prioritizedOptions, ...options];
}
catch (error) {
console.error('Error loading completion models:', error);
// 오류 시 기본 완성 모델 제공
return [
{ name: 'gpt-4o-mini', value: 'gpt-4o-mini' },
{ name: 'gpt-4o', value: 'gpt-4o' },
{ name: 'gpt-4', value: 'gpt-4' },
{ name: 'gpt-3.5-turbo', value: 'gpt-3.5-turbo' },
];
}
},
};
class OpenAIAnalytics {
constructor() {
this.description = {
displayName: 'OpenAI Analytics',
name: 'openAIAnalytics',
icon: 'file:openai-analytics.svg',
group: ['transform'],
version: 1,
subtitle: '={{ $parameter["operation"] + ": " + $parameter["resource"] }}',
description: 'Use OpenAI Analytics API',
defaults: {
name: 'OpenAI Analytics',
},
inputs: [{
type: 'main',
}],
outputs: [{
type: 'main',
}],
credentials: [
{
name: 'openAIAnalyticsApi',
required: true,
displayOptions: {
show: {
authentication: [
'openAIAnalyticsApi',
],
},
},
},
{
name: 'openAiApi',
required: true,
displayOptions: {
show: {
authentication: [
'openAiApi',
],
},
},
},
],
properties: [
{
displayName: 'Authentication',
name: 'authentication',
type: 'options',
options: [
{
name: 'OpenAI Analytics API',
value: 'openAIAnalyticsApi',
description: 'Use dedicated OpenAI Analytics API credentials',
},
{
name: 'OpenAI API',
value: 'openAiApi',
description: 'Use existing OpenAI API credentials',
},
],
default: 'openAIAnalyticsApi',
},
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Assistant',
value: 'assistant',
},
{
name: 'Embedding',
value: 'embedding',
},
{
name: 'File',
value: 'file',
},
{
name: 'Report',
value: 'report',
},
{
name: 'Text',
value: 'text',
},
{
name: 'Thread',
value: 'thread',
},
],
default: 'assistant',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['thread'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new thread',
action: 'Create a thread',
},
{
name: 'Add Message',
value: 'addMessage',
description: 'Add a message to a thread',
action: 'Add a message to a thread',
},
{
name: 'Run Thread',
value: 'run',
description: 'Run a thread',
action: 'Run a thread',
},
{
name: 'Check Run Status',
value: 'checkRunStatus',
description: 'Check the status of a run',
action: 'Check the status of a run',
},
{
name: 'List Messages',
value: 'listMessages',
description: 'Get messages from a thread',
action: 'Get messages from a thread',
},
{
name: 'Get Thread',
value: 'getThread',
description: 'Get a thread by ID',
action: 'Get a thread',
},
{
name: 'Create and Run Thread',
value: 'createAndRunThread',
description: '한 번에 Thread 생성, 메시지 추가, 실행 및 결과 대기',
action: 'Create run and wait for thread results',
},
{
name: 'Run Existing Thread',
value: 'runExistingThread',
description: '기존 Thread에 메시지 추가, 실행 및 결과 대기',
action: 'Run and wait for existing thread results',
},
],
default: 'create',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['assistant'],
},
},
options: [
{
name: 'Get Assistants',
value: 'getAssistants',
description: 'Get a list of assistants',
action: 'Get a list of assistants',
},
{
name: 'Create Assistant',
value: 'createAssistant',
description: 'Create a new assistant',
action: 'Create a new assistant',
}
],
default: 'getAssistants',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['file'],
},
},
options: [
{
name: 'Get Files',
value: 'getFiles',
description: 'Get a list of files',
action: 'Get a list of files',
},
{
name: 'Get File',
value: 'getFile',
description: 'Get a file by ID',
action: 'Get a file',
},
{
name: 'Upload File',
value: 'uploadFile',
description: 'Upload a file to OpenAI',
action: 'Upload a file to OpenAI',
},
{
name: 'Download File',
value: 'downloadFile',
description: 'Download content of a file',
action: 'Download content of a file',
},
],
default: 'getFiles',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['report'],
},
},
options: [
{
name: 'Generate HTML Report',
value: 'generateHtmlReport',
description: 'Generate an HTML report from text data',
action: 'Generate HTML report',
},
],
default: 'generateHtmlReport',
},
// Thread Create Operation
{
displayName: 'Initial Message',
name: 'initialMessage',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['create'],
},
},
default: '',
description: 'The initial message to add to the thread (optional)',
required: false,
},
// Thread Add Message Operation
{
displayName: 'Thread ID',
name: 'threadId',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['addMessage', 'run', 'checkRunStatus', 'listMessages'],
},
},
default: '',
description: 'The ID of the thread',
required: true,
},
{
displayName: 'Message Role',
name: 'messageRole',
type: 'options',
displayOptions: {
show: {
resource: ['thread'],
operation: ['addMessage'],
},
},
options: [
{
name: 'User',
value: 'user',
description: 'A message created by the user',
},
],
default: 'user',
description: 'The role of the entity that is creating the message',
required: true,
},
{
displayName: 'Message Content',
name: 'messageContent',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['addMessage'],
},
},
default: '',
description: 'The content of the message to add to the thread',
required: true,
},
{
displayName: 'File IDs',
name: 'fileIds',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['addMessage'],
},
},
default: '',
description: 'Comma-separated list of file IDs to attach to the message',
required: false,
},
// Thread Run Operation
{
displayName: 'Select Assistant',
name: 'threadAssistantSelection',
type: 'options',
options: [
{
name: 'From List',
value: 'fromList',
description: 'Select an assistant from the list',
},
{
name: 'By ID',
value: 'byId',
description: 'Enter the ID of the assistant',
},
],
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
},
},
default: 'fromList',
description: 'How to select the assistant',
required: true,
},
{
displayName: 'Assistant',
name: 'threadAssistantId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getAssistants',
},
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
threadAssistantSelection: ['fromList'],
},
},
default: '',
description: 'Select the assistant to use for this run',
required: true,
},
{
displayName: 'Assistant ID',
name: 'threadAssistantId',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
threadAssistantSelection: ['byId'],
},
},
default: '',
description: 'The ID of the assistant to use for the run',
required: true,
},
{
displayName: 'Wait for Completion',
name: 'threadWaitForCompletion',
type: 'boolean',
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
},
},
default: true,
description: 'Whether to wait for the run to complete before returning',
},
{
displayName: 'Maximum Poll Time (Seconds)',
name: 'threadMaxPollTime',
type: 'number',
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
threadWaitForCompletion: [true],
},
},
default: 120,
description: 'Maximum time in seconds to wait for the run to complete',
},
{
displayName: 'Instructions',
name: 'threadInstructions',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
},
},
default: '',
description: 'Override the default system instructions of the assistant',
required: false,
},
{
displayName: 'Simplify Output',
name: 'threadSimplifyOutput',
type: 'boolean',
displayOptions: {
show: {
resource: ['thread'],
operation: ['run', 'createAndRun'],
},
},
default: true,
description: 'Whether to return simplified response format',
hint: '간단한 응답 형식으로 반환할지 여부',
},
// Check Run Status Operation
{
displayName: 'Run ID',
name: 'runId',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['checkRunStatus'],
},
},
default: '',
description: 'The ID of the run',
required: true,
},
// Create and Run Thread Operation
{
displayName: 'Message Input Method',
name: 'threadMessageInputMethod',
type: 'options',
options: [
{
name: 'Single Message',
value: 'singleMessage',
description: 'Add only one message',
},
{
name: 'Multiple Messages',
value: 'multipleMessages',
description: 'Add multiple messages (can specify role)',
},
],
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
},
},
default: 'singleMessage',
description: 'Select message input method',
hint: '메시지 입력 방식 선택',
},
{
displayName: 'Initial Message',
name: 'threadInitialMessage',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadMessageInputMethod: ['singleMessage'],
},
},
default: '',
description: 'The initial message to add to the thread',
hint: 'Thread에 추가할 초기 메시지',
required: true,
},
{
displayName: 'Messages',
name: 'threadMessages',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
sortable: true,
},
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadMessageInputMethod: ['multipleMessages'],
},
},
default: {
values: [
{
role: 'user',
content: '',
},
],
},
options: [
{
displayName: 'Values',
name: 'values',
values: [
{
displayName: 'Role',
name: 'role',
type: 'options',
options: [
{
name: 'User',
value: 'user',
description: 'User message',
},
{
name: 'System',
value: 'system',
description: 'System message',
},
],
default: 'user',
description: 'Role of the message author',
hint: '메시지 작성자의 역할',
},
{
displayName: 'Content',
name: 'content',
type: 'string',
default: '',
description: 'Message content',
hint: '메시지 내용',
required: true,
},
],
},
],
description: 'List of messages to add to the thread',
hint: 'Thread에 추가할 메시지 목록',
},
{
displayName: 'File Attachment Method',
name: 'threadFileAttachmentMethod',
type: 'options',
options: [
{
name: 'Use Existing File IDs',
value: 'existingFiles',
description: 'Use file IDs already uploaded to OpenAI',
},
{
name: 'Upload Files from Previous Node',
value: 'uploadFiles',
description: 'Upload binary files from previous node',
},
{
name: 'Use Both Methods',
value: 'both',
description: 'Use both existing file IDs and upload new files',
},
{
name: 'No File Attachments',
value: 'none',
description: 'Do not attach any files',
},
],
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
},
},
default: 'none',
description: 'Select file attachment method',
hint: '파일을 첨부하는 방식 선택',
},
{
displayName: 'Binary Property',
name: 'threadBinaryPropertyName',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadFileAttachmentMethod: ['uploadFiles', 'both'],
},
},
default: 'data',
description: 'Binary property containing data from previous node (e.g. "data")',
hint: '이전 노드에서 전달된 바이너리 데이터를 포함하는 속성 이름 (예: "data")',
required: true,
},
{
displayName: 'File Purpose',
name: 'threadUploadFilePurpose',
type: 'options',
options: [
{
name: 'Assistants',
value: 'assistants',
description: 'Files for use with Assistant',
},
{
name: 'Assistants Input',
value: 'assistants_input',
description: 'Files for input to Assistant',
},
],
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadFileAttachmentMethod: ['uploadFiles', 'both'],
},
},
default: 'assistants',
description: 'Select purpose for uploaded files',
hint: '업로드할 파일의 목적 선택',
},
{
displayName: 'Enable File Attachments',
name: 'threadFileIdsEnabled',
type: 'boolean',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadFileAttachmentMethod: ['existingFiles', 'both'],
},
},
default: true,
description: 'Whether to attach existing uploaded files',
hint: '기존 업로드된 파일을 첨부할지 여부',
},
{
displayName: 'File IDs',
name: 'threadFileIds',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getFiles',
},
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadFileAttachmentMethod: ['existingFiles', 'both'],
threadFileIdsEnabled: [true],
},
},
default: [],
description: 'File IDs to attach to the thread',
hint: '스레드에 첨부할 파일 ID',
},
{
displayName: 'Wait for Completion',
name: 'threadWaitForCompletion',
type: 'boolean',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
},
},
default: true,
description: 'Whether to wait for the run to complete before returning',
hint: '실행 완료를 기다릴지 여부',
},
{
displayName: 'Maximum Poll Time (Seconds)',
name: 'threadMaxPollTime',
type: 'number',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
threadWaitForCompletion: [true],
},
},
default: 120,
description: 'Maximum time in seconds to wait for the run to complete',
hint: '실행 완료를 대기하는 최대 시간(초)',
},
{
displayName: 'Instructions',
name: 'threadInstructions',
type: 'string',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
},
},
default: '',
description: 'Override the default system instructions of the assistant',
hint: '어시스턴트의 기본 시스템 지시사항을 재정의',
required: false,
},
{
displayName: 'Simplify Output',
name: 'threadSimplifyOutput',
type: 'boolean',
displayOptions: {
show: {
resource: ['thread'],
operation: ['createAndRunThread'],
},
},
default: true,
description: 'Whether to return simplified response format',
hint: '간단한 응답 형식으로 반환할지 여부',
},
{
displayName: 'Prompt',
name: 'reportPrompt',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
rows: 4,
},
displayOptions: {
show: {
resource: ['report'],
operation: ['generateHtmlReport'],
},
},
default: 'A4용지 1장 짜리 분량으로 모던하고 깔끔한 UI 라이브러리를 사용한 디자인으로 다음 데이터를 분석하고 시각화하는 HTML 보고서를 작성해주세요.',
description: 'AI에게 보낼 보고서 생성 지시 프롬프트',
hint: 'AI에게 보낼 보고서 생성 지시 프롬프트',
required: true,
},
{
displayName: 'Input Text',
name: 'reportInputText',
type: 'string',
typeOptions: {
alwaysOpenEditWindow: true,
rows: 5,
},
displayOptions: {
show: {
resource: ['report'],
operation: ['generateHtmlReport'],
},
},
default: '',
description: '분석할 텍스트 데이터',
hint: '보고서로 변환할 텍스트 데이터를 입력하세요',
required: true,
},
{
displayName: 'OpenAI Model',
name: 'reportModel',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCompletionModels',
},
displayOptions: {
show: {
resource: ['report'],
operation: ['generateHtmlReport'],
},
},
default: 'gpt-4.1',
description: '보고서 생성에 사용할 OpenAI 모델',
hint: '보고서 생성에 사용할 OpenAI 모델',
required: true,
},
{
displayName: 'Include Default Libraries',
name: 'includeDefaultLibraries',
type: 'boolean',
displayOptions: {
show: {
resource: ['report'],
operation: ['generateHtmlReport'],
},
},
default: true,
description: '부트스트랩, 차트JS 등 기본 UI 라이브러리를 포함합니다',
hint: '부트스트랩, 차트JS 등 기본 UI 라이브러리를 포함합니다',
},
{
displayName: 'Advanced Settings',
name: 'advancedSettings',
type: 'boolean',
displayOptions: {
show: {
resource: ['report'],
operation: ['generateHtmlReport'],
},
},
default: false,
description: '생성 매개변수를 세부 조정합니다',
hint: '생성 매개변수를 세부 조정합니다',
},