n8n-nodes-github-copilot 3.2.6 → 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.
@@ -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, 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: `[Media processing failed: ${mediaResult.description}]`,
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 ✓ Audio',
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 ✓ Audio',
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 ✓ Audio',
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 ✓ Audio',
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 Media',
81
+ displayName: 'Include Image',
82
82
  name: 'includeMedia',
83
83
  type: 'boolean',
84
84
  default: false,
85
- description: 'Whether to include a media file in the message. Supported: Images (PNG, JPEG, GIF, WebP) and Audio files. Type is auto-detected.',
85
+ description: 'Whether to include an image file in the message. Supported formats: PNG, JPEG, GIF, WebP.',
86
86
  },
87
87
  {
88
- displayName: 'Media Source',
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 media as base64 string or file path',
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 media from URL',
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 media data',
114
+ description: 'Source of the image data',
115
115
  },
116
116
  {
117
- displayName: 'Media File',
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: 'Media file as base64 string or file path (Images: PNG/JPEG/GIF/WebP, Audio: MP3/WAV/M4A)',
128
+ description: 'Image file as base64 string or file path. Supported formats: PNG, JPEG, GIF, WebP.',
129
129
  },
130
130
  {
131
- displayName: 'Media URL',
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/file.jpg',
142
- description: 'URL of the media file to download and include (Images: PNG/JPEG/GIF/WebP, Audio: MP3/WAV/M4A)',
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: 'Media Binary Property',
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 media file',
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' | 'audio' | 'unknown';
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,151 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.suggestImageConversion = exports.getFileExtensionFromMimeType = exports.validateImageFormat = exports.isAudioMimeType = exports.isImageMimeType = exports.processMediaFile = void 0;
3
+ exports.suggestImageConversion = exports.getFileExtensionFromMimeType = exports.validateImageFormat = exports.isImageMimeType = exports.processMediaFile = void 0;
4
4
  const index_1 = require("./index");
5
- async function detectMimeType(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty) {
6
- var _a, _b;
7
- try {
8
- if (source === 'binary') {
9
- const binaryData = context.getInputData()[itemIndex].binary;
10
- if (binaryData && binaryProperty && binaryData[binaryProperty]) {
11
- return binaryData[binaryProperty].mimeType || 'application/octet-stream';
12
- }
13
- }
14
- else if (source === 'url' && mediaUrl) {
15
- const extension = (_a = mediaUrl.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
16
- const extToMime = {
17
- 'png': 'image/png',
18
- 'jpg': 'image/jpeg',
19
- 'jpeg': 'image/jpeg',
20
- 'gif': 'image/gif',
21
- 'webp': 'image/webp',
22
- 'mp3': 'audio/mpeg',
23
- 'wav': 'audio/wav',
24
- 'm4a': 'audio/mp4',
25
- 'ogg': 'audio/ogg',
26
- 'mp4': 'video/mp4'
27
- };
28
- return extToMime[extension || ''] || 'application/octet-stream';
29
- }
30
- else if (source === 'manual' && mediaFile) {
31
- if (mediaFile.startsWith('data:')) {
32
- const mimeMatch = mediaFile.match(/data:([^;]+)/);
33
- if (mimeMatch)
34
- return mimeMatch[1];
35
- }
36
- const extension = (_b = mediaFile.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase();
37
- const extToMime = {
38
- 'png': 'image/png',
39
- 'jpg': 'image/jpeg',
40
- 'jpeg': 'image/jpeg',
41
- 'gif': 'image/gif',
42
- 'webp': 'image/webp',
43
- 'mp3': 'audio/mpeg',
44
- 'wav': 'audio/wav',
45
- 'm4a': 'audio/mp4',
46
- 'ogg': 'audio/ogg',
47
- 'mp4': 'video/mp4'
48
- };
49
- return extToMime[extension || ''] || 'application/octet-stream';
50
- }
51
- }
52
- catch (error) {
53
- }
54
- return 'application/octet-stream';
55
- }
56
5
  async function processMediaFile(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty) {
57
6
  try {
58
- const detectedMimeType = await detectMimeType(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
59
- const isLikelyImage = isImageMimeType(detectedMimeType);
60
- const isLikelyAudio = isAudioMimeType(detectedMimeType);
61
- if (isLikelyAudio && !isLikelyImage) {
62
- try {
63
- const audioResult = await (0, index_1.processAudioFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
64
- return {
65
- type: 'audio',
66
- dataUrl: `data:${audioResult.mimeType};base64,${audioResult.data}`,
67
- description: `Audio file: ${audioResult.filename} (${Math.round(audioResult.size / 1024)}KB, ${audioResult.mimeType})`,
68
- mimeType: audioResult.mimeType,
69
- };
70
- }
71
- catch (audioError) {
72
- throw new Error(`Audio processing failed: ${audioError instanceof Error ? audioError.message : 'Unknown error'}`);
73
- }
74
- }
75
- else if (isLikelyImage && !isLikelyAudio) {
76
- try {
77
- const imageResult = await (0, index_1.processImageFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
78
- const formatValidation = validateImageFormat(imageResult.mimeType);
79
- if (!formatValidation.isValid) {
80
- throw new Error(suggestImageConversion(imageResult.mimeType));
81
- }
82
- return {
83
- type: 'image',
84
- dataUrl: `data:${imageResult.mimeType};base64,${imageResult.data}`,
85
- description: `Image file: ${imageResult.filename} (${Math.round(imageResult.size / 1024)}KB, ${imageResult.mimeType})`,
86
- mimeType: imageResult.mimeType,
87
- };
88
- }
89
- catch (imageError) {
90
- throw new Error(`Image processing failed: ${imageError instanceof Error ? imageError.message : 'Unknown error'}`);
91
- }
92
- }
93
- else {
94
- if (detectedMimeType.includes('mpeg') || detectedMimeType.includes('mp3')) {
95
- try {
96
- const audioResult = await (0, index_1.processAudioFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
97
- return {
98
- type: 'audio',
99
- dataUrl: `data:${audioResult.mimeType};base64,${audioResult.data}`,
100
- description: `Audio file: ${audioResult.filename} (${Math.round(audioResult.size / 1024)}KB, ${audioResult.mimeType})`,
101
- mimeType: audioResult.mimeType,
102
- };
103
- }
104
- catch (audioError) {
105
- throw new Error(`MPEG audio processing failed: ${audioError instanceof Error ? audioError.message : 'Unknown error'}`);
106
- }
107
- }
108
- else {
109
- try {
110
- const imageResult = await (0, index_1.processImageFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
111
- const formatValidation = validateImageFormat(imageResult.mimeType);
112
- if (!formatValidation.isValid) {
113
- throw new Error(suggestImageConversion(imageResult.mimeType));
114
- }
115
- return {
116
- type: 'image',
117
- dataUrl: `data:${imageResult.mimeType};base64,${imageResult.data}`,
118
- description: `Image file: ${imageResult.filename} (${Math.round(imageResult.size / 1024)}KB, ${imageResult.mimeType})`,
119
- mimeType: imageResult.mimeType,
120
- };
121
- }
122
- catch (imageError) {
123
- try {
124
- const audioResult = await (0, index_1.processAudioFile)(context, itemIndex, source, mediaFile, mediaUrl, binaryProperty);
125
- return {
126
- type: 'audio',
127
- dataUrl: `data:${audioResult.mimeType};base64,${audioResult.data}`,
128
- description: `Audio file: ${audioResult.filename} (${Math.round(audioResult.size / 1024)}KB, ${audioResult.mimeType})`,
129
- mimeType: audioResult.mimeType,
130
- };
131
- }
132
- catch (audioError) {
133
- const supportedImageFormats = ['PNG', 'JPEG', 'GIF', 'WebP'];
134
- const supportedAudioFormats = ['MP3', 'WAV', 'M4A', 'OGG'];
135
- throw new Error(`File is neither a valid image nor audio file (detected MIME: ${detectedMimeType}).\n` +
136
- `Supported image formats: ${supportedImageFormats.join(', ')}\n` +
137
- `Supported audio formats: ${supportedAudioFormats.join(', ')}\n` +
138
- `Image error: ${imageError instanceof Error ? imageError.message : 'Unknown'}\n` +
139
- `Audio error: ${audioError instanceof Error ? audioError.message : 'Unknown'}`);
140
- }
141
- }
142
- }
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));
143
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
+ };
144
18
  }
145
19
  catch (error) {
146
20
  return {
147
21
  type: 'unknown',
148
- description: `Error processing media file: ${error instanceof Error ? error.message : 'Unknown error'}`,
22
+ description: `Error processing image file: ${error instanceof Error ? error.message : 'Unknown error'}`,
149
23
  mimeType: 'unknown',
150
24
  };
151
25
  }
@@ -162,12 +36,6 @@ function isImageMimeType(mimeType) {
162
36
  return supportedFormats.includes(mimeType.toLowerCase());
163
37
  }
164
38
  exports.isImageMimeType = isImageMimeType;
165
- function isAudioMimeType(mimeType) {
166
- return mimeType.startsWith('audio/') ||
167
- mimeType === 'application/ogg' ||
168
- mimeType === 'video/mp4';
169
- }
170
- exports.isAudioMimeType = isAudioMimeType;
171
39
  function validateImageFormat(mimeType) {
172
40
  if (!isImageMimeType(mimeType)) {
173
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: true,
7
+ supportsAudio: false,
8
8
  maxContextTokens: 200000,
9
- description: 'OpenAI GPT-5 with image support and audio analysis via GitHub Copilot API',
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: true,
13
+ supportsAudio: false,
14
14
  maxContextTokens: 128000,
15
- description: 'OpenAI GPT-5 Mini with image support and audio analysis via GitHub Copilot API',
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: true,
19
+ supportsAudio: false,
20
20
  maxContextTokens: 128000,
21
- description: 'OpenAI GPT-4.1 with image support and audio analysis via GitHub Copilot API',
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: true,
37
+ supportsAudio: false,
38
38
  maxContextTokens: 1000000,
39
- description: 'Google Gemini 2.5 Pro with multimodal support via GitHub Copilot API',
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.6",
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",