n8n-nodes-github-copilot 3.2.5 → 3.2.7
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/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.js +2 -8
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.js +17 -17
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.d.ts +1 -2
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.js +12 -40
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.js +8 -8
- package/package.json +1 -1
|
@@ -43,7 +43,7 @@ class GitHubCopilotChatAPI {
|
|
|
43
43
|
const advancedOptions = this.getNodeParameter('advancedOptions', i, {});
|
|
44
44
|
const includeMedia = this.getNodeParameter('includeMedia', i, false);
|
|
45
45
|
if (includeMedia) {
|
|
46
|
-
const validation = (0, modelCapabilities_1.validateModelCapabilities)(model, true,
|
|
46
|
+
const validation = (0, modelCapabilities_1.validateModelCapabilities)(model, true, false);
|
|
47
47
|
if (!validation.isValid) {
|
|
48
48
|
throw new Error(validation.errorMessage || 'Model validation failed');
|
|
49
49
|
}
|
|
@@ -83,16 +83,10 @@ class GitHubCopilotChatAPI {
|
|
|
83
83
|
},
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
else if (mediaResult.type === 'audio' && mediaResult.dataUrl) {
|
|
87
|
-
contentArray.push({
|
|
88
|
-
type: 'text',
|
|
89
|
-
text: `Please analyze this audio file: ${mediaResult.description}\n\nAudio data (base64): ${mediaResult.dataUrl}`,
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
86
|
else {
|
|
93
87
|
contentArray.push({
|
|
94
88
|
type: 'text',
|
|
95
|
-
text: `[
|
|
89
|
+
text: `[Image processing failed: ${mediaResult.description}]`,
|
|
96
90
|
});
|
|
97
91
|
}
|
|
98
92
|
}
|
|
@@ -24,12 +24,12 @@ exports.nodeProperties = [
|
|
|
24
24
|
{
|
|
25
25
|
name: 'GPT-5',
|
|
26
26
|
value: 'gpt-5',
|
|
27
|
-
description: 'OpenAI GPT-5 (Latest and most capable) ✓ Images
|
|
27
|
+
description: 'OpenAI GPT-5 (Latest and most capable) ✓ Images',
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
name: 'GPT-5 Mini',
|
|
31
31
|
value: 'gpt-5-mini',
|
|
32
|
-
description: 'OpenAI GPT-5 Mini (Faster, cost-effective) ✓ Images
|
|
32
|
+
description: 'OpenAI GPT-5 Mini (Faster, cost-effective) ✓ Images',
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
name: 'Claude Opus 4.1',
|
|
@@ -39,7 +39,7 @@ exports.nodeProperties = [
|
|
|
39
39
|
{
|
|
40
40
|
name: 'Gemini 2.5 Pro',
|
|
41
41
|
value: 'gemini-2.5-pro',
|
|
42
|
-
description: 'Google Gemini 2.5 Pro (Multimodal capabilities) ✓ Images
|
|
42
|
+
description: 'Google Gemini 2.5 Pro (Multimodal capabilities) ✓ Images',
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
name: 'Grok Code Fast 1',
|
|
@@ -49,7 +49,7 @@ exports.nodeProperties = [
|
|
|
49
49
|
{
|
|
50
50
|
name: 'GPT-4.1 Copilot',
|
|
51
51
|
value: 'gpt-4.1-copilot',
|
|
52
|
-
description: 'OpenAI GPT-4.1 specialized for coding assistance ✓ Images
|
|
52
|
+
description: 'OpenAI GPT-4.1 specialized for coding assistance ✓ Images',
|
|
53
53
|
},
|
|
54
54
|
],
|
|
55
55
|
default: 'gpt-5-mini',
|
|
@@ -78,14 +78,14 @@ exports.nodeProperties = [
|
|
|
78
78
|
description: 'System message to set the behavior of the AI model',
|
|
79
79
|
},
|
|
80
80
|
{
|
|
81
|
-
displayName: 'Include
|
|
81
|
+
displayName: 'Include Image',
|
|
82
82
|
name: 'includeMedia',
|
|
83
83
|
type: 'boolean',
|
|
84
84
|
default: false,
|
|
85
|
-
description: 'Whether to include
|
|
85
|
+
description: 'Whether to include an image file in the message. Supported formats: PNG, JPEG, GIF, WebP.',
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
|
-
displayName: '
|
|
88
|
+
displayName: 'Image Source',
|
|
89
89
|
name: 'mediaSource',
|
|
90
90
|
type: 'options',
|
|
91
91
|
displayOptions: {
|
|
@@ -97,12 +97,12 @@ exports.nodeProperties = [
|
|
|
97
97
|
{
|
|
98
98
|
name: 'Manual Input',
|
|
99
99
|
value: 'manual',
|
|
100
|
-
description: 'Provide
|
|
100
|
+
description: 'Provide image as base64 string or file path',
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
name: 'URL',
|
|
104
104
|
value: 'url',
|
|
105
|
-
description: 'Download
|
|
105
|
+
description: 'Download image from URL',
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
name: 'Binary Data',
|
|
@@ -111,10 +111,10 @@ exports.nodeProperties = [
|
|
|
111
111
|
},
|
|
112
112
|
],
|
|
113
113
|
default: 'manual',
|
|
114
|
-
description: 'Source of the
|
|
114
|
+
description: 'Source of the image data',
|
|
115
115
|
},
|
|
116
116
|
{
|
|
117
|
-
displayName: '
|
|
117
|
+
displayName: 'Image File',
|
|
118
118
|
name: 'mediaFile',
|
|
119
119
|
type: 'string',
|
|
120
120
|
displayOptions: {
|
|
@@ -125,10 +125,10 @@ exports.nodeProperties = [
|
|
|
125
125
|
},
|
|
126
126
|
default: '',
|
|
127
127
|
placeholder: 'Paste base64 string or file path',
|
|
128
|
-
description: '
|
|
128
|
+
description: 'Image file as base64 string or file path. Supported formats: PNG, JPEG, GIF, WebP.',
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
|
-
displayName: '
|
|
131
|
+
displayName: 'Image URL',
|
|
132
132
|
name: 'mediaUrl',
|
|
133
133
|
type: 'string',
|
|
134
134
|
displayOptions: {
|
|
@@ -138,11 +138,11 @@ exports.nodeProperties = [
|
|
|
138
138
|
},
|
|
139
139
|
},
|
|
140
140
|
default: '',
|
|
141
|
-
placeholder: 'https://example.com/
|
|
142
|
-
description: 'URL of the
|
|
141
|
+
placeholder: 'https://example.com/image.jpg',
|
|
142
|
+
description: 'URL of the image file to download. Supported formats: PNG, JPEG, GIF, WebP.',
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
|
-
displayName: '
|
|
145
|
+
displayName: 'Image Binary Property',
|
|
146
146
|
name: 'mediaBinaryProperty',
|
|
147
147
|
type: 'string',
|
|
148
148
|
displayOptions: {
|
|
@@ -153,7 +153,7 @@ exports.nodeProperties = [
|
|
|
153
153
|
},
|
|
154
154
|
default: 'data',
|
|
155
155
|
placeholder: 'data',
|
|
156
|
-
description: 'Name of the binary property containing the
|
|
156
|
+
description: 'Name of the binary property containing the image file',
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
displayName: 'Advanced Options',
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { IExecuteFunctions } from 'n8n-workflow';
|
|
2
2
|
export declare function processMediaFile(context: IExecuteFunctions, itemIndex: number, source: 'manual' | 'url' | 'binary', mediaFile?: string, mediaUrl?: string, binaryProperty?: string): Promise<{
|
|
3
|
-
type: 'image' | '
|
|
3
|
+
type: 'image' | 'unknown';
|
|
4
4
|
dataUrl?: string;
|
|
5
5
|
description: string;
|
|
6
6
|
mimeType: string;
|
|
7
7
|
}>;
|
|
8
8
|
export declare function isImageMimeType(mimeType: string): boolean;
|
|
9
|
-
export declare function isAudioMimeType(mimeType: string): boolean;
|
|
10
9
|
export declare function validateImageFormat(mimeType: string): {
|
|
11
10
|
isValid: boolean;
|
|
12
11
|
error?: string;
|
|
@@ -1,47 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.suggestImageConversion = exports.getFileExtensionFromMimeType = exports.validateImageFormat = exports.
|
|
3
|
+
exports.suggestImageConversion = exports.getFileExtensionFromMimeType = exports.validateImageFormat = exports.isImageMimeType = exports.processMediaFile = void 0;
|
|
4
4
|
const index_1 = require("./index");
|
|
5
5
|
async function processMediaFile(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty) {
|
|
6
6
|
try {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
throw new Error(suggestImageConversion(imageResult.mimeType));
|
|
12
|
-
}
|
|
13
|
-
return {
|
|
14
|
-
type: 'image',
|
|
15
|
-
dataUrl: `data:${imageResult.mimeType};base64,${imageResult.data}`,
|
|
16
|
-
description: `Image file: ${imageResult.filename} (${Math.round(imageResult.size / 1024)}KB, ${imageResult.mimeType})`,
|
|
17
|
-
mimeType: imageResult.mimeType,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
catch (imageError) {
|
|
21
|
-
try {
|
|
22
|
-
const audioResult = await (0, index_1.processAudioFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
|
|
23
|
-
return {
|
|
24
|
-
type: 'audio',
|
|
25
|
-
dataUrl: `data:${audioResult.mimeType};base64,${audioResult.data}`,
|
|
26
|
-
description: `Audio file: ${audioResult.filename} (${Math.round(audioResult.size / 1024)}KB)`,
|
|
27
|
-
mimeType: audioResult.mimeType,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
catch (audioError) {
|
|
31
|
-
const supportedImageFormats = ['PNG', 'JPEG', 'GIF', 'WebP'];
|
|
32
|
-
const supportedAudioFormats = ['MP3', 'WAV', 'M4A', 'OGG'];
|
|
33
|
-
throw new Error(`File is neither a valid image nor audio file.\n` +
|
|
34
|
-
`Supported image formats: ${supportedImageFormats.join(', ')}\n` +
|
|
35
|
-
`Supported audio formats: ${supportedAudioFormats.join(', ')}\n` +
|
|
36
|
-
`Image error: ${imageError instanceof Error ? imageError.message : 'Unknown'}\n` +
|
|
37
|
-
`Audio error: ${audioError instanceof Error ? audioError.message : 'Unknown'}`);
|
|
38
|
-
}
|
|
7
|
+
const imageResult = await (0, index_1.processImageFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
|
|
8
|
+
const formatValidation = validateImageFormat(imageResult.mimeType);
|
|
9
|
+
if (!formatValidation.isValid) {
|
|
10
|
+
throw new Error(suggestImageConversion(imageResult.mimeType));
|
|
39
11
|
}
|
|
12
|
+
return {
|
|
13
|
+
type: 'image',
|
|
14
|
+
dataUrl: `data:${imageResult.mimeType};base64,${imageResult.data}`,
|
|
15
|
+
description: `Image file: ${imageResult.filename} (${Math.round(imageResult.size / 1024)}KB, ${imageResult.mimeType})`,
|
|
16
|
+
mimeType: imageResult.mimeType,
|
|
17
|
+
};
|
|
40
18
|
}
|
|
41
19
|
catch (error) {
|
|
42
20
|
return {
|
|
43
21
|
type: 'unknown',
|
|
44
|
-
description: `Error processing
|
|
22
|
+
description: `Error processing image file: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
45
23
|
mimeType: 'unknown',
|
|
46
24
|
};
|
|
47
25
|
}
|
|
@@ -58,12 +36,6 @@ function isImageMimeType(mimeType) {
|
|
|
58
36
|
return supportedFormats.includes(mimeType.toLowerCase());
|
|
59
37
|
}
|
|
60
38
|
exports.isImageMimeType = isImageMimeType;
|
|
61
|
-
function isAudioMimeType(mimeType) {
|
|
62
|
-
return mimeType.startsWith('audio/') ||
|
|
63
|
-
mimeType === 'application/ogg' ||
|
|
64
|
-
mimeType === 'video/mp4';
|
|
65
|
-
}
|
|
66
|
-
exports.isAudioMimeType = isAudioMimeType;
|
|
67
39
|
function validateImageFormat(mimeType) {
|
|
68
40
|
if (!isImageMimeType(mimeType)) {
|
|
69
41
|
const supportedFormats = ['PNG', 'JPEG', 'GIF', 'WebP'];
|
|
@@ -4,21 +4,21 @@ exports.getModelInfo = exports.getSupportedModels = exports.validateModelCapabil
|
|
|
4
4
|
exports.MODEL_CAPABILITIES = {
|
|
5
5
|
'gpt-5': {
|
|
6
6
|
supportsImages: true,
|
|
7
|
-
supportsAudio:
|
|
7
|
+
supportsAudio: false,
|
|
8
8
|
maxContextTokens: 200000,
|
|
9
|
-
description: 'OpenAI GPT-5 with image support
|
|
9
|
+
description: 'OpenAI GPT-5 with image support via GitHub Copilot API',
|
|
10
10
|
},
|
|
11
11
|
'gpt-5-mini': {
|
|
12
12
|
supportsImages: true,
|
|
13
|
-
supportsAudio:
|
|
13
|
+
supportsAudio: false,
|
|
14
14
|
maxContextTokens: 128000,
|
|
15
|
-
description: 'OpenAI GPT-5 Mini with image support
|
|
15
|
+
description: 'OpenAI GPT-5 Mini with image support via GitHub Copilot API',
|
|
16
16
|
},
|
|
17
17
|
'gpt-4.1-copilot': {
|
|
18
18
|
supportsImages: true,
|
|
19
|
-
supportsAudio:
|
|
19
|
+
supportsAudio: false,
|
|
20
20
|
maxContextTokens: 128000,
|
|
21
|
-
description: 'OpenAI GPT-4.1 with image support
|
|
21
|
+
description: 'OpenAI GPT-4.1 with image support via GitHub Copilot API',
|
|
22
22
|
},
|
|
23
23
|
'claude-opus-4.1': {
|
|
24
24
|
supportsImages: false,
|
|
@@ -34,9 +34,9 @@ exports.MODEL_CAPABILITIES = {
|
|
|
34
34
|
},
|
|
35
35
|
'gemini-2.5-pro': {
|
|
36
36
|
supportsImages: true,
|
|
37
|
-
supportsAudio:
|
|
37
|
+
supportsAudio: false,
|
|
38
38
|
maxContextTokens: 1000000,
|
|
39
|
-
description: 'Google Gemini 2.5 Pro with
|
|
39
|
+
description: 'Google Gemini 2.5 Pro with image support via GitHub Copilot API',
|
|
40
40
|
},
|
|
41
41
|
'gemini-2.0-flash': {
|
|
42
42
|
supportsImages: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-github-copilot",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.7",
|
|
4
4
|
"description": "n8n community node for GitHub Copilot with CLI integration and official Chat API access to GPT-5, Claude, Gemini and more using your existing Copilot credits",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",
|