n8n-nodes-github-copilot 3.38.25 → 3.38.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/credentials/GitHubCopilotApi.credentials.d.ts +1 -1
- package/dist/credentials/GitHubCopilotApi.credentials.js +25 -25
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.js +166 -166
- package/dist/nodes/GitHubCopilotAuthHelper/GitHubCopilotAuthHelper.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotAuthHelper/GitHubCopilotAuthHelper.node.js +539 -539
- package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.js +46 -44
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.js +82 -82
- package/dist/nodes/GitHubCopilotChatAPI/utils/helpers.d.ts +2 -2
- package/dist/nodes/GitHubCopilotChatAPI/utils/helpers.js +26 -26
- package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.d.ts +2 -2
- package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.js +12 -12
- package/dist/nodes/GitHubCopilotChatAPI/utils/index.d.ts +4 -4
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.d.ts +3 -3
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.js +19 -19
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.js +23 -23
- package/dist/nodes/GitHubCopilotChatAPI/utils/types.d.ts +5 -5
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.js +115 -106
- package/dist/nodes/GitHubCopilotEmbeddings/GitHubCopilotEmbeddings.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotEmbeddings/GitHubCopilotEmbeddings.node.js +114 -114
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.js +74 -69
- package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.d.ts +1 -1
- package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.js +181 -181
- package/dist/nodes/GitHubCopilotOpenAI/utils/index.d.ts +2 -2
- package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.d.ts +10 -10
- package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.js +53 -53
- package/dist/nodes/GitHubCopilotOpenAI/utils/types.d.ts +12 -12
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.js +120 -116
- package/dist/package.json +1 -1
- package/package.json +1 -1
|
@@ -9,21 +9,21 @@ const DynamicModelLoader_1 = require("../../shared/models/DynamicModelLoader");
|
|
|
9
9
|
class GitHubCopilotOpenAI {
|
|
10
10
|
constructor() {
|
|
11
11
|
this.description = {
|
|
12
|
-
displayName:
|
|
13
|
-
name:
|
|
14
|
-
icon:
|
|
15
|
-
group: [
|
|
12
|
+
displayName: 'GitHub Copilot OpenAI',
|
|
13
|
+
name: 'gitHubCopilotOpenAI',
|
|
14
|
+
icon: 'file:../../shared/icons/copilot.svg',
|
|
15
|
+
group: ['transform'],
|
|
16
16
|
version: 1,
|
|
17
|
-
subtitle:
|
|
18
|
-
description:
|
|
17
|
+
subtitle: '={{$parameter["model"]}}',
|
|
18
|
+
description: 'OpenAI-compatible GitHub Copilot Chat API with full support for messages, tools, and all OpenAI parameters',
|
|
19
19
|
defaults: {
|
|
20
|
-
name:
|
|
20
|
+
name: 'GitHub Copilot OpenAI',
|
|
21
21
|
},
|
|
22
|
-
inputs: [
|
|
23
|
-
outputs: [
|
|
22
|
+
inputs: ['main'],
|
|
23
|
+
outputs: ['main'],
|
|
24
24
|
credentials: [
|
|
25
25
|
{
|
|
26
|
-
name:
|
|
26
|
+
name: 'githubCopilotApi',
|
|
27
27
|
required: true,
|
|
28
28
|
},
|
|
29
29
|
],
|
|
@@ -43,20 +43,20 @@ class GitHubCopilotOpenAI {
|
|
|
43
43
|
const returnData = [];
|
|
44
44
|
for (let i = 0; i < items.length; i++) {
|
|
45
45
|
try {
|
|
46
|
-
const modelSource = this.getNodeParameter(
|
|
46
|
+
const modelSource = this.getNodeParameter('modelSource', i, 'fromList');
|
|
47
47
|
let model;
|
|
48
|
-
if (modelSource ===
|
|
49
|
-
model = this.getNodeParameter(
|
|
50
|
-
if (!model || model.trim() ===
|
|
48
|
+
if (modelSource === 'custom') {
|
|
49
|
+
model = this.getNodeParameter('customModel', i);
|
|
50
|
+
if (!model || model.trim() === '') {
|
|
51
51
|
throw new Error("Custom model name is required when using 'Custom (Manual Entry)' mode");
|
|
52
52
|
}
|
|
53
53
|
console.log(`🔧 Using custom model: ${model}`);
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
56
|
-
const selectedModel = this.getNodeParameter(
|
|
57
|
-
if (selectedModel ===
|
|
58
|
-
model = this.getNodeParameter(
|
|
59
|
-
if (!model || model.trim() ===
|
|
56
|
+
const selectedModel = this.getNodeParameter('model', i);
|
|
57
|
+
if (selectedModel === '__manual__') {
|
|
58
|
+
model = this.getNodeParameter('customModel', i);
|
|
59
|
+
if (!model || model.trim() === '') {
|
|
60
60
|
throw new Error("Custom model name is required when selecting '✏️ Enter Custom Model Name'");
|
|
61
61
|
}
|
|
62
62
|
console.log(`✏️ Using manually entered model: ${model}`);
|
|
@@ -66,11 +66,11 @@ class GitHubCopilotOpenAI {
|
|
|
66
66
|
console.log(`📋 Using model from list: ${model}`);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
const messagesInputMode = this.getNodeParameter(
|
|
69
|
+
const messagesInputMode = this.getNodeParameter('messagesInputMode', i, 'manual');
|
|
70
70
|
let messages = [];
|
|
71
71
|
let requestBodyFromJson = undefined;
|
|
72
|
-
if (messagesInputMode ===
|
|
73
|
-
const messagesJson = this.getNodeParameter(
|
|
72
|
+
if (messagesInputMode === 'json') {
|
|
73
|
+
const messagesJson = this.getNodeParameter('messagesJson', i, '[]');
|
|
74
74
|
try {
|
|
75
75
|
let parsed;
|
|
76
76
|
if (typeof messagesJson === 'object') {
|
|
@@ -94,11 +94,11 @@ class GitHubCopilotOpenAI {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
catch (error) {
|
|
97
|
-
throw new Error(`Failed to parse messages JSON: ${error instanceof Error ? error.message :
|
|
97
|
+
throw new Error(`Failed to parse messages JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
else {
|
|
101
|
-
const messagesParam = this.getNodeParameter(
|
|
101
|
+
const messagesParam = this.getNodeParameter('messages', i, {
|
|
102
102
|
message: [],
|
|
103
103
|
});
|
|
104
104
|
console.log('📥 Manual mode - messagesParam:', JSON.stringify(messagesParam, null, 2));
|
|
@@ -118,8 +118,8 @@ class GitHubCopilotOpenAI {
|
|
|
118
118
|
}
|
|
119
119
|
if (messages.length === 0) {
|
|
120
120
|
messages.push({
|
|
121
|
-
role:
|
|
122
|
-
content:
|
|
121
|
+
role: 'user',
|
|
122
|
+
content: 'Hello! How can you help me?',
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
for (let msgIndex = 0; msgIndex < messages.length; msgIndex++) {
|
|
@@ -147,7 +147,7 @@ class GitHubCopilotOpenAI {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
console.log('📤 Final messages being sent to API:', JSON.stringify(messages, null, 2));
|
|
150
|
-
const advancedOptions = this.getNodeParameter(
|
|
150
|
+
const advancedOptions = this.getNodeParameter('advancedOptions', i, {});
|
|
151
151
|
let parsedTools = [];
|
|
152
152
|
const tools = advancedOptions.tools;
|
|
153
153
|
if (tools) {
|
|
@@ -171,7 +171,7 @@ class GitHubCopilotOpenAI {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
catch (error) {
|
|
174
|
-
console.log('⚠️ Failed to parse tools, ignoring:', error instanceof Error ? error.message :
|
|
174
|
+
console.log('⚠️ Failed to parse tools, ignoring:', error instanceof Error ? error.message : 'Unknown error');
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
else {
|
|
@@ -190,7 +190,7 @@ class GitHubCopilotOpenAI {
|
|
|
190
190
|
const stream = (_e = advancedOptions.stream) !== null && _e !== void 0 ? _e : false;
|
|
191
191
|
const user = advancedOptions.user || undefined;
|
|
192
192
|
const stop = advancedOptions.stop || undefined;
|
|
193
|
-
const response_format_ui = advancedOptions.response_format ||
|
|
193
|
+
const response_format_ui = advancedOptions.response_format || 'text';
|
|
194
194
|
let response_format = undefined;
|
|
195
195
|
if (requestBodyFromJson === null || requestBodyFromJson === void 0 ? void 0 : requestBodyFromJson.response_format) {
|
|
196
196
|
response_format = requestBodyFromJson.response_format;
|
|
@@ -200,7 +200,8 @@ class GitHubCopilotOpenAI {
|
|
|
200
200
|
response_format = { type: response_format_ui };
|
|
201
201
|
console.log('📋 response_format from UI field:', JSON.stringify(response_format));
|
|
202
202
|
}
|
|
203
|
-
else if (advancedOptions.response_format &&
|
|
203
|
+
else if (advancedOptions.response_format &&
|
|
204
|
+
typeof advancedOptions.response_format === 'string') {
|
|
204
205
|
try {
|
|
205
206
|
response_format = JSON.parse(advancedOptions.response_format);
|
|
206
207
|
console.log('📋 response_format from advancedOptions:', JSON.stringify(response_format));
|
|
@@ -217,15 +218,15 @@ class GitHubCopilotOpenAI {
|
|
|
217
218
|
console.log('ℹ️ No response_format specified - using default text format');
|
|
218
219
|
}
|
|
219
220
|
const modelMapping = {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
221
|
+
'gpt-4': 'gpt-4o',
|
|
222
|
+
'gpt-4o': 'gpt-4o',
|
|
223
|
+
'gpt-4o-mini': 'gpt-4o-mini',
|
|
224
|
+
'gpt-4-turbo': 'gpt-4o',
|
|
225
|
+
'claude-3-5-sonnet': 'claude-3.5-sonnet',
|
|
226
|
+
'claude-3.5-sonnet-20241022': 'claude-3.5-sonnet',
|
|
227
|
+
o1: 'o1',
|
|
228
|
+
'o1-preview': 'o1-preview',
|
|
229
|
+
'o1-mini': 'o1-mini',
|
|
229
230
|
};
|
|
230
231
|
const copilotModel = modelMapping[model] || model;
|
|
231
232
|
const requestBody = {
|
|
@@ -257,8 +258,8 @@ class GitHubCopilotOpenAI {
|
|
|
257
258
|
}
|
|
258
259
|
if (parsedTools.length > 0) {
|
|
259
260
|
requestBody.tools = parsedTools;
|
|
260
|
-
const tool_choice = advancedOptions.tool_choice ||
|
|
261
|
-
if (tool_choice !==
|
|
261
|
+
const tool_choice = advancedOptions.tool_choice || 'auto';
|
|
262
|
+
if (tool_choice !== 'auto') {
|
|
262
263
|
requestBody.tool_choice = tool_choice;
|
|
263
264
|
}
|
|
264
265
|
}
|
|
@@ -303,7 +304,7 @@ class GitHubCopilotOpenAI {
|
|
|
303
304
|
console.log('🔍 response_format check:', (response_format === null || response_format === void 0 ? void 0 : response_format.type) === 'json_object' ? 'WILL CLEAN MARKDOWN' : 'WILL KEEP AS IS');
|
|
304
305
|
const openAIResponse = {
|
|
305
306
|
id: response.id || `chatcmpl-${Date.now()}`,
|
|
306
|
-
object: response.object ||
|
|
307
|
+
object: response.object || 'chat.completion',
|
|
307
308
|
created: response.created || Math.floor(Date.now() / 1000),
|
|
308
309
|
model: model,
|
|
309
310
|
choices: response.choices.map((choice, choiceIndex) => {
|
|
@@ -356,7 +357,7 @@ class GitHubCopilotOpenAI {
|
|
|
356
357
|
}
|
|
357
358
|
catch (error) {
|
|
358
359
|
if (this.continueOnFail()) {
|
|
359
|
-
const errorMessage = error instanceof Error ? error.message :
|
|
360
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
360
361
|
const errorString = JSON.stringify(error);
|
|
361
362
|
console.error('❌ Error occurred:', errorMessage);
|
|
362
363
|
console.error('❌ Error details:', errorString);
|
|
@@ -385,8 +386,9 @@ class GitHubCopilotOpenAI {
|
|
|
385
386
|
console.error('Failed to parse API error:', parseError);
|
|
386
387
|
}
|
|
387
388
|
const lowerMessage = cleanMessage.toLowerCase();
|
|
388
|
-
const is400Error = lowerMessage.includes(
|
|
389
|
-
(
|
|
389
|
+
const is400Error = lowerMessage.includes('400') ||
|
|
390
|
+
lowerMessage.includes('bad request') ||
|
|
391
|
+
(apiError && apiError.error && apiError.error.code === 'invalid_request_body');
|
|
390
392
|
if (is400Error) {
|
|
391
393
|
console.log('🚫 400 Bad Request detected - throwing non-retryable error');
|
|
392
394
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Bad Request (400): ${cleanMessage}`, {
|
|
@@ -394,7 +396,7 @@ class GitHubCopilotOpenAI {
|
|
|
394
396
|
description: 'The request was malformed or contains invalid parameters. Retrying will not help.',
|
|
395
397
|
});
|
|
396
398
|
}
|
|
397
|
-
let errorType =
|
|
399
|
+
let errorType = 'invalid_request_error';
|
|
398
400
|
let errorCode = null;
|
|
399
401
|
let errorParam = null;
|
|
400
402
|
let finalMessage = cleanMessage;
|
|
@@ -406,40 +408,43 @@ class GitHubCopilotOpenAI {
|
|
|
406
408
|
console.log('✅ Using GitHub Copilot API error details');
|
|
407
409
|
}
|
|
408
410
|
else {
|
|
409
|
-
if (lowerMessage.includes(
|
|
410
|
-
errorType =
|
|
411
|
-
errorCode =
|
|
412
|
-
if (lowerMessage.includes(
|
|
413
|
-
finalMessage =
|
|
411
|
+
if (lowerMessage.includes('403') || lowerMessage.includes('forbidden')) {
|
|
412
|
+
errorType = 'invalid_request_error';
|
|
413
|
+
errorCode = 'insufficient_quota';
|
|
414
|
+
if (lowerMessage.includes('access') && lowerMessage.includes('forbidden')) {
|
|
415
|
+
finalMessage =
|
|
416
|
+
'You exceeded your current quota, please check your plan and billing details.';
|
|
414
417
|
}
|
|
415
418
|
else {
|
|
416
419
|
finalMessage = cleanMessage;
|
|
417
420
|
}
|
|
418
421
|
}
|
|
419
|
-
else if (lowerMessage.includes(
|
|
420
|
-
errorType =
|
|
421
|
-
errorCode =
|
|
422
|
-
errorParam =
|
|
423
|
-
finalMessage =
|
|
422
|
+
else if (lowerMessage.includes('max') && lowerMessage.includes('token')) {
|
|
423
|
+
errorType = 'invalid_request_error';
|
|
424
|
+
errorCode = 'context_length_exceeded';
|
|
425
|
+
errorParam = 'max_tokens';
|
|
426
|
+
finalMessage =
|
|
427
|
+
"This model's maximum context length is exceeded. Please reduce the length of the messages or completion.";
|
|
424
428
|
}
|
|
425
|
-
else if (lowerMessage.includes(
|
|
426
|
-
errorType =
|
|
427
|
-
errorCode =
|
|
428
|
-
finalMessage =
|
|
429
|
+
else if (lowerMessage.includes('401') || lowerMessage.includes('unauthorized')) {
|
|
430
|
+
errorType = 'invalid_request_error';
|
|
431
|
+
errorCode = 'invalid_api_key';
|
|
432
|
+
finalMessage =
|
|
433
|
+
'Incorrect API key provided. You can find your API key at https://platform.openai.com/account/api-keys.';
|
|
429
434
|
}
|
|
430
|
-
else if (lowerMessage.includes(
|
|
431
|
-
errorType =
|
|
432
|
-
errorCode =
|
|
433
|
-
finalMessage =
|
|
435
|
+
else if (lowerMessage.includes('429') || lowerMessage.includes('rate limit')) {
|
|
436
|
+
errorType = 'rate_limit_error';
|
|
437
|
+
errorCode = 'rate_limit_exceeded';
|
|
438
|
+
finalMessage = 'Rate limit reached. Please wait before making more requests.';
|
|
434
439
|
}
|
|
435
|
-
else if (lowerMessage.includes(
|
|
436
|
-
errorType =
|
|
437
|
-
errorCode =
|
|
438
|
-
finalMessage =
|
|
440
|
+
else if (lowerMessage.includes('timeout')) {
|
|
441
|
+
errorType = 'api_error';
|
|
442
|
+
errorCode = 'timeout';
|
|
443
|
+
finalMessage = 'Request timeout. Please try again.';
|
|
439
444
|
}
|
|
440
445
|
else {
|
|
441
|
-
errorType =
|
|
442
|
-
errorCode =
|
|
446
|
+
errorType = 'api_error';
|
|
447
|
+
errorCode = 'internal_error';
|
|
443
448
|
finalMessage = cleanMessage;
|
|
444
449
|
}
|
|
445
450
|
console.log('⚠️ Using fallback error detection with cleaned message');
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { INodeProperties } from
|
|
1
|
+
import { INodeProperties } from 'n8n-workflow';
|
|
2
2
|
export declare const nodeProperties: INodeProperties[];
|