Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ jobs:
run: npm ci

- name: Run comprehensive checks
run: npm run prepublishOnly

run: npm run validate

- name: Run security audit
run: npm run audit
continue-on-error: true

- name: Validate package structure
run: npm pack --dry-run

Expand Down
14 changes: 1 addition & 13 deletions credentials/LLMWhispererApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
ICredentialType,
INodeProperties,
ICredentialTestRequest,
IAuthenticateGeneric,
} from 'n8n-workflow';

Expand Down Expand Up @@ -29,19 +28,8 @@ export class LLMWhispererApi implements ICredentialType {
type: 'generic',
properties: {
headers: {
'Authorization': '=Bearer apiKey',
'unstract-key': '={{$credentials.apiKey}}',
},
},
};

// Using external test endpoint to satisfy n8n verification requirements
// LLMWhisperer API does not provide a dedicated test connection endpoint
// httpbin.org/bearer accepts any Bearer token and returns success
test: ICredentialTestRequest = {
request: {
baseURL: 'https://httpbin.org',
url: '/bearer',
method: 'GET',
},
};
}
12 changes: 0 additions & 12 deletions credentials/UnstractApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
ICredentialType,
INodeProperties,
ICredentialTestRequest,
IAuthenticateGeneric,
} from 'n8n-workflow';

Expand Down Expand Up @@ -41,15 +40,4 @@ export class UnstractApi implements ICredentialType {
},
},
};

// Using external test endpoint to satisfy n8n verification requirements
// Unstract API does not provide a dedicated test connection endpoint
// httpbin.org/bearer accepts any Bearer token and returns success
test: ICredentialTestRequest = {
request: {
baseURL: 'https://httpbin.org',
url: '/bearer',
method: 'GET',
},
};
}
12 changes: 0 additions & 12 deletions credentials/UnstractHITLApi.credentials.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
ICredentialType,
INodeProperties,
ICredentialTestRequest,
IAuthenticateGeneric,
} from 'n8n-workflow';

Expand Down Expand Up @@ -41,15 +40,4 @@ export class UnstractHITLApi implements ICredentialType {
},
},
};

// Using external test endpoint to satisfy n8n verification requirements
// Unstract HITL API does not provide a dedicated test connection endpoint
// httpbin.org/bearer accepts any Bearer token and returns success
test: ICredentialTestRequest = {
request: {
baseURL: 'https://httpbin.org',
url: '/bearer',
method: 'GET',
},
};
}
16 changes: 4 additions & 12 deletions nodes/LlmWhisperer/LlmWhisperer.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ export class LlmWhisperer implements INodeType {
const returnData: INodeExecutionData[] = [];

try {
const credentials = await this.getCredentials('llmWhispererApi');
const apiKey = credentials.apiKey as string;
const { helpers, logger } = this;

for (let i = 0; i < items.length; i++) {
Expand Down Expand Up @@ -231,7 +229,6 @@ export class LlmWhisperer implements INodeType {
method: 'POST' as IHttpRequestMethods,
url: `${host}/api/v2/whisper`,
headers: {
'unstract-key': `${apiKey}`,
'Content-Type': 'application/octet-stream',
},
body: fileBuffer,
Expand All @@ -256,7 +253,7 @@ export class LlmWhisperer implements INodeType {
logger.info('Making API request to LLMWhisperer API...');
let result: any;
try {
result = await helpers.request(requestOptions);
result = await helpers.httpRequestWithAuthentication.call(this, 'llmWhispererApi', requestOptions);
} catch (requestError) {
logger.error('Error during LLMWhisperer API request:', requestError);
throw requestError;
Expand All @@ -276,12 +273,9 @@ export class LlmWhisperer implements INodeType {
while (status !== 'processed' && status !== 'error') {
await sleep(2000);

const statusResult = await helpers.request({
const statusResult = await helpers.httpRequestWithAuthentication.call(this, 'llmWhispererApi', {
method: 'GET' as IHttpRequestMethods,
url: `${host}/api/v2/whisper-status`,
headers: {
'unstract-key': `${apiKey}`,
},
qs: {
whisper_hash: whisperHash,
},
Expand Down Expand Up @@ -311,12 +305,9 @@ export class LlmWhisperer implements INodeType {
}

if (status === 'processed') {
const retrieveResult = await helpers.request({
const retrieveResult = await helpers.httpRequestWithAuthentication.call(this, 'llmWhispererApi', {
method: 'GET' as IHttpRequestMethods,
url: `${host}/api/v2/whisper-retrieve`,
headers: {
'unstract-key': `${apiKey}`,
},
qs: {
whisper_hash: whisperHash,
},
Expand All @@ -327,6 +318,7 @@ export class LlmWhisperer implements INodeType {
delete retrieveResultContent.webhook_metadata;
returnData.push({
json: retrieveResultContent,
pairedItem: { item: i },
});
}
}
Expand Down
12 changes: 3 additions & 9 deletions nodes/Unstract/Unstract.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export class Unstract implements INodeType {

try {
const credentials = await this.getCredentials('unstractApi');
const apiKey = credentials.apiKey as string;
const orgId = credentials.orgId as string;
const { helpers, logger } = this;

Expand Down Expand Up @@ -158,15 +157,12 @@ export class Unstract implements INodeType {
const requestOptions = {
method: 'POST' as IHttpRequestMethods,
url: `${host}/deployment/api/${orgId}/${deploymentName}/`,
headers: {
'Authorization': `Bearer ${apiKey}`,
},
formData,
timeout: 5 * 60 * 1000,
};

logger.info('Making API request to Unstract API...');
const result = await helpers.request(requestOptions);
const result = await helpers.httpRequestWithAuthentication.call(this, 'unstractApi', requestOptions);
let resultContent = JSON.parse(result).message;
let executionStatus = resultContent.execution_status;

Expand All @@ -180,14 +176,11 @@ export class Unstract implements INodeType {
const statusRequestOptions = {
method: 'GET' as IHttpRequestMethods,
url: `${host}${statusApi}`,
headers: {
'Authorization': `Bearer ${apiKey}`,
},
timeout: 5 * 60 * 1000,
};

try {
const statusResult = await helpers.request(statusRequestOptions);
const statusResult = await helpers.httpRequestWithAuthentication.call(this, 'unstractApi', statusRequestOptions);
resultContent = JSON.parse(statusResult);
executionStatus = resultContent.status;
} catch (error: any) {
Expand Down Expand Up @@ -217,6 +210,7 @@ export class Unstract implements INodeType {

returnData.push({
json: resultContent,
pairedItem: { item: i },
});
}

Expand Down
16 changes: 9 additions & 7 deletions nodes/UnstractHitlFetch/UnstractHitlFetch.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export class UnstractHitlFetch implements INodeType {
const returnData: INodeExecutionData[] = [];

const credentials = await this.getCredentials('unstractHITLApi');
const hitlKey = credentials.HITLKey as string;
const orgId = credentials.orgId as string;
const helpers = this.helpers;

Expand All @@ -73,23 +72,26 @@ export class UnstractHitlFetch implements INodeType {
const options = {
method: 'GET' as IHttpRequestMethods,
url,
headers: {
Authorization: `Bearer ${hitlKey}`,
},
};

try {
const response = await helpers.request(options);
const response = await helpers.httpRequestWithAuthentication.call(this, 'unstractHITLApi', options);
const parsed = typeof response === 'string' ? JSON.parse(response) : response;

if (parsed.error) {
if (parsed.error === 'No approved items available.') {
returnData.push({ json: { message: 'No approved items available', hasData: false } });
returnData.push({
json: { message: 'No approved items available', hasData: false },
pairedItem: { item: i }
});
} else {
throw new NodeOperationError(this.getNode(), `API Error: ${parsed.error}`);
}
} else if (parsed.data) {
returnData.push({ json: { ...parsed.data, hasData: true } });
returnData.push({
json: { ...parsed.data, hasData: true },
pairedItem: { item: i }
});
} else {
throw new NodeOperationError(this.getNode(), 'Unexpected response format.');
}
Expand Down
16 changes: 6 additions & 10 deletions nodes/UnstractHitlPush/UnstractHitlPush.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ export class UnstractHitlPush implements INodeType {

try {
const credentials = await this.getCredentials('unstractApi');
const apiKey = credentials.apiKey as string;
const orgId = credentials.orgId as string;
const { helpers, logger } = this;

Expand Down Expand Up @@ -159,15 +158,12 @@ export class UnstractHitlPush implements INodeType {
const requestOptions = {
method: 'POST' as IHttpRequestMethods,
url: `${host}/deployment/api/${orgId}/${deploymentName}/`,
headers: {
Authorization: `Bearer ${apiKey}`,
},
formData,
timeout: 5 * 60 * 1000,
};

logger.info('[HITL] Sending file to Unstract HITL API...');
const result = await helpers.request(requestOptions);
const result = await helpers.httpRequestWithAuthentication.call(this, 'unstractApi', requestOptions);
let resultContent = JSON.parse(result).message;
let executionStatus = resultContent.execution_status;

Expand All @@ -181,14 +177,11 @@ export class UnstractHitlPush implements INodeType {
const pollRequest = {
method: 'GET' as IHttpRequestMethods,
url: `${host}${statusApi}`,
headers: {
Authorization: `Bearer ${apiKey}`,
},
timeout: 5 * 60 * 1000,
};

try {
const pollResult = await helpers.request(pollRequest);
const pollResult = await helpers.httpRequestWithAuthentication.call(this, 'unstractApi', pollRequest);
resultContent = JSON.parse(pollResult);
executionStatus = resultContent.status;
} catch (error: any) {
Expand Down Expand Up @@ -216,7 +209,10 @@ export class UnstractHitlPush implements INodeType {
}
}

returnData.push({ json: resultContent });
returnData.push({
json: resultContent,
pairedItem: { item: i }
});
}

return [returnData];
Expand Down
72 changes: 27 additions & 45 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading