n8n-nodes-github-copilot 3.38.25 → 3.38.35
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 +2 -2
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.js +198 -125
- 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/GitHubCopilotSpeech/GitHubCopilotSpeech.node.d.ts +10 -4
- package/dist/nodes/GitHubCopilotSpeech/GitHubCopilotSpeech.node.js +8 -7
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.d.ts +6 -1
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.js +253 -116
- package/dist/package.json +1 -1
- package/dist/shared/models/GitHubCopilotModels.js +19 -2
- package/dist/shared/models/ModelVersionRequirements.js +5 -0
- package/dist/shared/utils/DynamicModelsManager.d.ts +9 -0
- package/dist/shared/utils/DynamicModelsManager.js +48 -6
- package/dist/shared/utils/FileChunkingApiUtils.d.ts +2 -2
- package/dist/shared/utils/FileChunkingApiUtils.js +15 -15
- package/dist/shared/utils/FileOptimizationUtils.d.ts +2 -2
- package/dist/shared/utils/FileOptimizationUtils.js +20 -20
- package/dist/shared/utils/GitHubCopilotApiUtils.js +6 -2
- package/dist/shared/utils/GitHubCopilotEndpoints.js +10 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GitHubCopilotChatModel = void 0;
|
|
4
4
|
const openai_1 = require("@langchain/openai");
|
|
5
|
+
const messages_1 = require("@langchain/core/messages");
|
|
5
6
|
const GitHubCopilotModels_1 = require("../../shared/models/GitHubCopilotModels");
|
|
6
7
|
const GitHubCopilotEndpoints_1 = require("../../shared/utils/GitHubCopilotEndpoints");
|
|
7
8
|
const DynamicModelLoader_1 = require("../../shared/models/DynamicModelLoader");
|
|
@@ -14,12 +15,18 @@ class GitHubCopilotChatOpenAI extends openai_1.ChatOpenAI {
|
|
|
14
15
|
this.context = context;
|
|
15
16
|
this.options = options;
|
|
16
17
|
}
|
|
18
|
+
invocationParams(options) {
|
|
19
|
+
const params = super.invocationParams(options);
|
|
20
|
+
params.model = this.model;
|
|
21
|
+
return params;
|
|
22
|
+
}
|
|
17
23
|
async _generate(messages, options) {
|
|
18
24
|
var _a;
|
|
19
25
|
if (!messages || messages.length === 0) {
|
|
20
|
-
throw new Error(
|
|
26
|
+
throw new Error('No messages provided for generation');
|
|
21
27
|
}
|
|
22
|
-
let
|
|
28
|
+
let hasVisionContent = false;
|
|
29
|
+
let copilotMessages = messages.map((msg) => {
|
|
23
30
|
let role;
|
|
24
31
|
switch (msg._getType()) {
|
|
25
32
|
case 'human':
|
|
@@ -35,19 +42,66 @@ class GitHubCopilotChatOpenAI extends openai_1.ChatOpenAI {
|
|
|
35
42
|
console.warn(`⚠️ Unknown message type: ${msg._getType()}, defaulting to 'user'`);
|
|
36
43
|
role = 'user';
|
|
37
44
|
}
|
|
38
|
-
let content =
|
|
39
|
-
|
|
45
|
+
let content = '';
|
|
46
|
+
const rawContent = msg.content;
|
|
47
|
+
if (typeof rawContent === 'string') {
|
|
48
|
+
if (rawContent.includes('data:image/') || rawContent.match(/\[.*image.*\]/i)) {
|
|
49
|
+
hasVisionContent = true;
|
|
50
|
+
console.log(`👁️ Vision content detected in string message (data URL or image reference)`);
|
|
51
|
+
}
|
|
52
|
+
content = rawContent;
|
|
40
53
|
}
|
|
41
|
-
else if (Array.isArray(
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
else if (Array.isArray(rawContent)) {
|
|
55
|
+
const hasImageContent = rawContent.some((part) => {
|
|
56
|
+
if (typeof part === 'object' && part !== null) {
|
|
57
|
+
const p = part;
|
|
58
|
+
if (p.type === 'image_url' || p.type === 'image' || p.image_url !== undefined) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (typeof p.url === 'string' && p.url.startsWith('data:image/')) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (p.image || p.imageUrl || p.image_data) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
});
|
|
70
|
+
if (hasImageContent) {
|
|
71
|
+
hasVisionContent = true;
|
|
72
|
+
console.log(`👁️ Vision content detected in array message`);
|
|
73
|
+
content = rawContent.map((part) => {
|
|
74
|
+
if (typeof part === 'object' && part !== null) {
|
|
75
|
+
const p = part;
|
|
76
|
+
if (p.type === 'text') {
|
|
77
|
+
return { type: 'text', text: String(p.text || '') };
|
|
78
|
+
}
|
|
79
|
+
else if (p.type === 'image_url' || p.type === 'image' || p.image_url) {
|
|
80
|
+
const imageUrl = (p.image_url || p.image || p);
|
|
81
|
+
const url = String((imageUrl === null || imageUrl === void 0 ? void 0 : imageUrl.url) || p.url || p.imageUrl || p.image_data || '');
|
|
82
|
+
return {
|
|
83
|
+
type: 'image_url',
|
|
84
|
+
image_url: {
|
|
85
|
+
url,
|
|
86
|
+
detail: (imageUrl === null || imageUrl === void 0 ? void 0 : imageUrl.detail) || 'auto',
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { type: 'text', text: String(part) };
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.warn(`⚠️ Complex content detected, stringifying:`, rawContent);
|
|
96
|
+
content = JSON.stringify(rawContent);
|
|
97
|
+
}
|
|
44
98
|
}
|
|
45
|
-
else if (
|
|
99
|
+
else if (rawContent === null || rawContent === undefined) {
|
|
46
100
|
content = '';
|
|
47
101
|
}
|
|
48
102
|
else {
|
|
49
|
-
console.warn(`⚠️ Non-string content detected, stringifying:`, typeof
|
|
50
|
-
content = JSON.stringify(
|
|
103
|
+
console.warn(`⚠️ Non-string content detected, stringifying:`, typeof rawContent);
|
|
104
|
+
content = JSON.stringify(rawContent);
|
|
51
105
|
}
|
|
52
106
|
return {
|
|
53
107
|
role,
|
|
@@ -55,7 +109,7 @@ class GitHubCopilotChatOpenAI extends openai_1.ChatOpenAI {
|
|
|
55
109
|
};
|
|
56
110
|
});
|
|
57
111
|
if (this.options.systemMessage && this.options.systemMessage.trim()) {
|
|
58
|
-
const hasSystemMessage = copilotMessages.some(msg => msg.role === 'system');
|
|
112
|
+
const hasSystemMessage = copilotMessages.some((msg) => msg.role === 'system');
|
|
59
113
|
if (!hasSystemMessage) {
|
|
60
114
|
copilotMessages.unshift({
|
|
61
115
|
role: 'system',
|
|
@@ -64,57 +118,65 @@ class GitHubCopilotChatOpenAI extends openai_1.ChatOpenAI {
|
|
|
64
118
|
console.log(`🔧 Added system message from options`);
|
|
65
119
|
}
|
|
66
120
|
}
|
|
67
|
-
const validMessages = copilotMessages.filter(msg => {
|
|
68
|
-
|
|
121
|
+
const validMessages = copilotMessages.filter((msg) => {
|
|
122
|
+
const isEmpty = Array.isArray(msg.content)
|
|
123
|
+
? msg.content.length === 0
|
|
124
|
+
: (!msg.content || (typeof msg.content === 'string' && msg.content.trim() === ''));
|
|
125
|
+
if (isEmpty) {
|
|
69
126
|
console.warn(`⚠️ Filtering out empty message with role: ${msg.role}`);
|
|
70
127
|
return false;
|
|
71
128
|
}
|
|
72
129
|
return true;
|
|
73
130
|
});
|
|
74
131
|
if (validMessages.length === 0) {
|
|
75
|
-
throw new Error(
|
|
132
|
+
throw new Error('No valid messages after filtering empty content');
|
|
76
133
|
}
|
|
77
134
|
const requestBody = {
|
|
78
|
-
model: this.
|
|
135
|
+
model: this.model,
|
|
79
136
|
messages: validMessages,
|
|
80
137
|
temperature: this.temperature,
|
|
81
138
|
max_tokens: this.maxTokens,
|
|
82
139
|
top_p: this.topP,
|
|
83
140
|
stream: this.options.enableStreaming || false,
|
|
84
141
|
};
|
|
85
|
-
if (this.options.tools && this.options.tools.length > 0) {
|
|
86
|
-
requestBody.tools = this.options.tools;
|
|
87
|
-
requestBody.tool_choice = this.options.tool_choice ||
|
|
88
|
-
console.log(`🔧 Request includes ${
|
|
142
|
+
if (this.options.tools && JSON.parse(this.options.tools).length > 0) {
|
|
143
|
+
requestBody.tools = JSON.parse(this.options.tools);
|
|
144
|
+
requestBody.tool_choice = this.options.tool_choice || 'auto';
|
|
145
|
+
console.log(`🔧 Request includes ${requestBody.tools.length} tools`);
|
|
89
146
|
}
|
|
90
147
|
const startTime = Date.now();
|
|
148
|
+
const shouldUseVision = hasVisionContent || this.options.enableVision === true;
|
|
149
|
+
if (shouldUseVision) {
|
|
150
|
+
console.log(`👁️ Sending vision request with Copilot-Vision-Request header (auto=${hasVisionContent}, manual=${this.options.enableVision})`);
|
|
151
|
+
}
|
|
91
152
|
try {
|
|
92
|
-
const response = await (0, GitHubCopilotApiUtils_1.makeGitHubCopilotRequest)(this.context, GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.ENDPOINTS.CHAT_COMPLETIONS, requestBody,
|
|
153
|
+
const response = await (0, GitHubCopilotApiUtils_1.makeGitHubCopilotRequest)(this.context, GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.ENDPOINTS.CHAT_COMPLETIONS, requestBody, shouldUseVision);
|
|
93
154
|
const endTime = Date.now();
|
|
94
155
|
const latency = endTime - startTime;
|
|
95
156
|
console.log(`⏱️ GitHub Copilot API call completed in ${latency}ms`);
|
|
96
157
|
if (!response.choices || response.choices.length === 0) {
|
|
97
|
-
throw new Error(
|
|
158
|
+
throw new Error('GitHub Copilot API returned no choices in response');
|
|
98
159
|
}
|
|
99
160
|
const choice = response.choices[0];
|
|
100
161
|
if (!choice.message) {
|
|
101
|
-
throw new Error(
|
|
162
|
+
throw new Error('GitHub Copilot API returned choice without message');
|
|
102
163
|
}
|
|
103
|
-
const langchainMessage = {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
tool_calls: choice.message.tool_calls,
|
|
107
|
-
};
|
|
164
|
+
const langchainMessage = new messages_1.AIMessage({
|
|
165
|
+
content: choice.message.content || '',
|
|
166
|
+
});
|
|
108
167
|
console.log(`📝 Response: role=${choice.message.role}, content_length=${((_a = choice.message.content) === null || _a === void 0 ? void 0 : _a.length) || 0}, finish_reason=${choice.finish_reason}`);
|
|
168
|
+
const generation = {
|
|
169
|
+
text: choice.message.content || '',
|
|
170
|
+
generationInfo: {
|
|
171
|
+
finish_reason: choice.finish_reason,
|
|
172
|
+
},
|
|
173
|
+
message: langchainMessage,
|
|
174
|
+
};
|
|
109
175
|
return {
|
|
110
|
-
generations: [
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
},
|
|
115
|
-
message: langchainMessage,
|
|
116
|
-
}]],
|
|
117
|
-
tokenUsage: response.usage,
|
|
176
|
+
generations: [generation],
|
|
177
|
+
llmOutput: {
|
|
178
|
+
tokenUsage: response.usage,
|
|
179
|
+
},
|
|
118
180
|
};
|
|
119
181
|
}
|
|
120
182
|
catch (error) {
|
|
@@ -128,149 +190,156 @@ class GitHubCopilotChatOpenAI extends openai_1.ChatOpenAI {
|
|
|
128
190
|
class GitHubCopilotChatModel {
|
|
129
191
|
constructor() {
|
|
130
192
|
this.description = {
|
|
131
|
-
displayName:
|
|
132
|
-
name:
|
|
133
|
-
icon:
|
|
134
|
-
group: [
|
|
193
|
+
displayName: 'GitHub Copilot Chat Model',
|
|
194
|
+
name: 'gitHubCopilotChatModel',
|
|
195
|
+
icon: 'file:../../shared/icons/copilot.svg',
|
|
196
|
+
group: ['transform'],
|
|
135
197
|
version: 1,
|
|
136
|
-
description:
|
|
198
|
+
description: 'GitHub Copilot chat model for AI workflows with full support for tools and function calling - access GPT-5, Claude, Gemini and more using your Copilot subscription',
|
|
137
199
|
defaults: {
|
|
138
|
-
name:
|
|
200
|
+
name: 'GitHub Copilot Chat Model',
|
|
139
201
|
},
|
|
140
202
|
codex: {
|
|
141
|
-
categories: [
|
|
203
|
+
categories: ['AI'],
|
|
142
204
|
subcategories: {
|
|
143
|
-
AI: [
|
|
144
|
-
|
|
205
|
+
AI: ['Language Models', 'Root Nodes'],
|
|
206
|
+
'Language Models': ['Chat Models (Recommended)'],
|
|
145
207
|
},
|
|
146
208
|
resources: {
|
|
147
209
|
primaryDocumentation: [
|
|
148
210
|
{
|
|
149
|
-
url:
|
|
211
|
+
url: 'https://docs.github.com/copilot/using-github-copilot/using-github-copilot-chat',
|
|
150
212
|
},
|
|
151
213
|
],
|
|
152
214
|
},
|
|
153
215
|
},
|
|
154
216
|
inputs: [],
|
|
155
|
-
outputs: [
|
|
156
|
-
outputNames: [
|
|
217
|
+
outputs: ['ai_languageModel'],
|
|
218
|
+
outputNames: ['Model'],
|
|
157
219
|
credentials: [
|
|
158
220
|
{
|
|
159
|
-
name:
|
|
221
|
+
name: 'githubCopilotApi',
|
|
160
222
|
required: true,
|
|
161
223
|
},
|
|
162
224
|
],
|
|
163
225
|
properties: [
|
|
164
226
|
...ModelProperties_1.CHAT_MODEL_PROPERTIES,
|
|
165
227
|
{
|
|
166
|
-
displayName:
|
|
167
|
-
name:
|
|
168
|
-
placeholder:
|
|
169
|
-
description:
|
|
170
|
-
type:
|
|
228
|
+
displayName: 'Options',
|
|
229
|
+
name: 'options',
|
|
230
|
+
placeholder: 'Add Option',
|
|
231
|
+
description: 'Additional options for the GitHub Copilot model',
|
|
232
|
+
type: 'collection',
|
|
171
233
|
default: {},
|
|
172
234
|
options: [
|
|
173
235
|
{
|
|
174
|
-
displayName:
|
|
175
|
-
name:
|
|
236
|
+
displayName: 'Temperature',
|
|
237
|
+
name: 'temperature',
|
|
176
238
|
default: 0.7,
|
|
177
239
|
typeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },
|
|
178
|
-
description:
|
|
179
|
-
type:
|
|
240
|
+
description: 'Controls randomness in output. Lower values make responses more focused.',
|
|
241
|
+
type: 'number',
|
|
180
242
|
},
|
|
181
243
|
{
|
|
182
|
-
displayName:
|
|
183
|
-
name:
|
|
244
|
+
displayName: 'Maximum Number of Tokens',
|
|
245
|
+
name: 'maxTokens',
|
|
184
246
|
default: 1000,
|
|
185
|
-
description:
|
|
186
|
-
type:
|
|
247
|
+
description: 'The maximum number of tokens to generate',
|
|
248
|
+
type: 'number',
|
|
187
249
|
typeOptions: {
|
|
188
250
|
maxValue: 32768,
|
|
189
251
|
},
|
|
190
252
|
},
|
|
191
253
|
{
|
|
192
|
-
displayName:
|
|
193
|
-
name:
|
|
254
|
+
displayName: 'Top P',
|
|
255
|
+
name: 'topP',
|
|
194
256
|
default: 1,
|
|
195
257
|
typeOptions: { maxValue: 1, minValue: 0, numberPrecision: 2 },
|
|
196
|
-
description:
|
|
197
|
-
type:
|
|
258
|
+
description: 'Controls diversity of output by nucleus sampling',
|
|
259
|
+
type: 'number',
|
|
198
260
|
},
|
|
199
261
|
{
|
|
200
|
-
displayName:
|
|
201
|
-
name:
|
|
202
|
-
type:
|
|
262
|
+
displayName: 'Enable Streaming',
|
|
263
|
+
name: 'enableStreaming',
|
|
264
|
+
type: 'boolean',
|
|
203
265
|
default: false,
|
|
204
|
-
description:
|
|
266
|
+
description: 'Enable streaming responses for real-time output (experimental)',
|
|
205
267
|
},
|
|
206
268
|
{
|
|
207
|
-
displayName:
|
|
208
|
-
name:
|
|
209
|
-
type:
|
|
210
|
-
default:
|
|
211
|
-
description:
|
|
269
|
+
displayName: 'System Message',
|
|
270
|
+
name: 'systemMessage',
|
|
271
|
+
type: 'string',
|
|
272
|
+
default: '',
|
|
273
|
+
description: 'System message to set the behavior of the assistant',
|
|
212
274
|
typeOptions: {
|
|
213
275
|
rows: 3,
|
|
214
276
|
},
|
|
215
277
|
},
|
|
216
278
|
{
|
|
217
|
-
displayName:
|
|
218
|
-
name:
|
|
219
|
-
type:
|
|
279
|
+
displayName: 'Auto Retry on 403 Error',
|
|
280
|
+
name: 'enableRetry',
|
|
281
|
+
type: 'boolean',
|
|
220
282
|
default: true,
|
|
221
|
-
description:
|
|
283
|
+
description: 'Automatically retry requests when hitting TPM (Transactions Per Minute) quota limits (HTTP 403)',
|
|
222
284
|
},
|
|
223
285
|
{
|
|
224
|
-
displayName:
|
|
225
|
-
name:
|
|
226
|
-
type:
|
|
286
|
+
displayName: 'Request Timeout (seconds)',
|
|
287
|
+
name: 'timeout',
|
|
288
|
+
type: 'number',
|
|
227
289
|
default: 120,
|
|
228
|
-
description:
|
|
290
|
+
description: 'Maximum time to wait for API response (in seconds)',
|
|
229
291
|
typeOptions: {
|
|
230
292
|
minValue: 10,
|
|
231
293
|
maxValue: 300,
|
|
232
294
|
},
|
|
233
295
|
},
|
|
234
296
|
{
|
|
235
|
-
displayName:
|
|
236
|
-
name:
|
|
237
|
-
type:
|
|
238
|
-
default:
|
|
239
|
-
description:
|
|
297
|
+
displayName: 'Tools (Function Calling)',
|
|
298
|
+
name: 'tools',
|
|
299
|
+
type: 'string',
|
|
300
|
+
default: '',
|
|
301
|
+
description: 'Optional: Array of tools/functions available to the model (OpenAI format). Leave empty if not using function calling.',
|
|
240
302
|
hint: "JSON array of tool definitions in OpenAI format. Leave this field empty if you don't need function calling.",
|
|
241
303
|
typeOptions: {
|
|
242
304
|
rows: 6,
|
|
243
305
|
},
|
|
244
306
|
},
|
|
245
307
|
{
|
|
246
|
-
displayName:
|
|
247
|
-
name:
|
|
248
|
-
type:
|
|
308
|
+
displayName: 'Tool Choice',
|
|
309
|
+
name: 'tool_choice',
|
|
310
|
+
type: 'options',
|
|
249
311
|
options: [
|
|
250
312
|
{
|
|
251
|
-
name:
|
|
252
|
-
value:
|
|
253
|
-
description:
|
|
313
|
+
name: 'Auto',
|
|
314
|
+
value: 'auto',
|
|
315
|
+
description: 'Let the model decide when to use tools',
|
|
254
316
|
},
|
|
255
317
|
{
|
|
256
|
-
name:
|
|
257
|
-
value:
|
|
258
|
-
description:
|
|
318
|
+
name: 'Required',
|
|
319
|
+
value: 'required',
|
|
320
|
+
description: 'Force the model to use at least one tool',
|
|
259
321
|
},
|
|
260
322
|
{
|
|
261
|
-
name:
|
|
262
|
-
value:
|
|
263
|
-
description:
|
|
323
|
+
name: 'None',
|
|
324
|
+
value: 'none',
|
|
325
|
+
description: 'Disable tool usage',
|
|
264
326
|
},
|
|
265
327
|
],
|
|
266
|
-
default:
|
|
267
|
-
description:
|
|
328
|
+
default: 'auto',
|
|
329
|
+
description: 'Control how the model uses tools',
|
|
268
330
|
displayOptions: {
|
|
269
331
|
show: {
|
|
270
|
-
tools: [
|
|
332
|
+
tools: ['/.+/'],
|
|
271
333
|
},
|
|
272
334
|
},
|
|
273
335
|
},
|
|
336
|
+
{
|
|
337
|
+
displayName: 'Enable Vision (Image Processing)',
|
|
338
|
+
name: 'enableVision',
|
|
339
|
+
type: 'boolean',
|
|
340
|
+
default: false,
|
|
341
|
+
description: 'Enable vision capabilities for processing images. Required when sending images via chat. Only works with vision-capable models (GPT-4o, GPT-5, Claude, etc.).',
|
|
342
|
+
},
|
|
274
343
|
],
|
|
275
344
|
},
|
|
276
345
|
],
|
|
@@ -284,10 +353,10 @@ class GitHubCopilotChatModel {
|
|
|
284
353
|
};
|
|
285
354
|
}
|
|
286
355
|
async supplyData(itemIndex) {
|
|
287
|
-
let model = this.getNodeParameter(
|
|
288
|
-
if (model ===
|
|
289
|
-
const customModel = this.getNodeParameter(
|
|
290
|
-
if (!customModel || customModel.trim() ===
|
|
356
|
+
let model = this.getNodeParameter('model', itemIndex);
|
|
357
|
+
if (model === '__manual__') {
|
|
358
|
+
const customModel = this.getNodeParameter('customModel', itemIndex);
|
|
359
|
+
if (!customModel || customModel.trim() === '') {
|
|
291
360
|
throw new Error("Custom model name is required when selecting '✏️ Enter Custom Model Name'");
|
|
292
361
|
}
|
|
293
362
|
model = customModel;
|
|
@@ -296,24 +365,24 @@ class GitHubCopilotChatModel {
|
|
|
296
365
|
else {
|
|
297
366
|
console.log(`✅ Using model from list: ${model}`);
|
|
298
367
|
}
|
|
299
|
-
const options = this.getNodeParameter(
|
|
368
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
300
369
|
const modelInfo = GitHubCopilotModels_1.GitHubCopilotModelsManager.getModelByValue(model);
|
|
301
|
-
const credentials = (await this.getCredentials(
|
|
370
|
+
const credentials = (await this.getCredentials('githubCopilotApi'));
|
|
302
371
|
const token = credentials.token;
|
|
303
372
|
if (!token) {
|
|
304
|
-
console.error(
|
|
305
|
-
throw new Error(
|
|
306
|
-
Object.keys(credentials).join(
|
|
373
|
+
console.error('❌ Available credential properties:', Object.keys(credentials));
|
|
374
|
+
throw new Error('GitHub Copilot: No token found in credentials. Available properties: ' +
|
|
375
|
+
Object.keys(credentials).join(', '));
|
|
307
376
|
}
|
|
308
|
-
const tokenPrefix = token.substring(0, Math.min(4, token.indexOf(
|
|
377
|
+
const tokenPrefix = token.substring(0, Math.min(4, token.indexOf('_') + 1)) || token.substring(0, 4);
|
|
309
378
|
const tokenSuffix = token.substring(Math.max(0, token.length - 5));
|
|
310
379
|
console.log(`🔍 GitHub Copilot ChatModel OAuth2 Debug: Using token ${tokenPrefix}...${tokenSuffix}`);
|
|
311
|
-
if (!token.startsWith(
|
|
312
|
-
!token.startsWith(
|
|
313
|
-
!token.startsWith(
|
|
380
|
+
if (!token.startsWith('gho_') &&
|
|
381
|
+
!token.startsWith('ghu_') &&
|
|
382
|
+
!token.startsWith('github_pat_')) {
|
|
314
383
|
console.warn(`⚠️ Unexpected token format: ${tokenPrefix}...${tokenSuffix}. Trying API call anyway.`);
|
|
315
384
|
}
|
|
316
|
-
const safeModel =
|
|
385
|
+
const safeModel = model || GitHubCopilotModels_1.DEFAULT_MODELS.GENERAL;
|
|
317
386
|
const safeModelInfo = modelInfo || GitHubCopilotModels_1.GitHubCopilotModelsManager.getModelByValue(GitHubCopilotModels_1.DEFAULT_MODELS.GENERAL);
|
|
318
387
|
const minVSCodeVersion = (0, ModelVersionRequirements_1.getMinVSCodeVersion)(safeModel);
|
|
319
388
|
const additionalHeaders = (0, ModelVersionRequirements_1.getAdditionalHeaders)(safeModel);
|
|
@@ -331,7 +400,7 @@ class GitHubCopilotChatModel {
|
|
|
331
400
|
}
|
|
332
401
|
}
|
|
333
402
|
catch (error) {
|
|
334
|
-
console.log(`⚠️ Failed to parse tools JSON: ${error instanceof Error ? error.message :
|
|
403
|
+
console.log(`⚠️ Failed to parse tools JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
335
404
|
}
|
|
336
405
|
}
|
|
337
406
|
const modelConfig = {
|
|
@@ -342,22 +411,26 @@ class GitHubCopilotChatModel {
|
|
|
342
411
|
maxRetries: options.enableRetry !== false ? options.maxRetries || 3 : 0,
|
|
343
412
|
...(parsedTools.length > 0 && {
|
|
344
413
|
tools: parsedTools,
|
|
345
|
-
tool_choice: options.tool_choice ||
|
|
414
|
+
tool_choice: options.tool_choice || 'auto',
|
|
346
415
|
}),
|
|
347
416
|
configuration: {
|
|
348
417
|
baseURL: GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.BASE_URL,
|
|
349
418
|
apiKey: token,
|
|
350
419
|
defaultHeaders: {
|
|
351
|
-
|
|
352
|
-
Accept:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
420
|
+
'User-Agent': 'GitHubCopilotChat/0.35.0',
|
|
421
|
+
'Accept': 'application/json',
|
|
422
|
+
'Editor-Version': `vscode/${minVSCodeVersion}`,
|
|
423
|
+
'Editor-Plugin-Version': 'copilot-chat/0.35.0',
|
|
424
|
+
'X-Request-Id': `n8n-chatmodel-${Date.now()}-${Math.random().toString(36).substring(7)}`,
|
|
425
|
+
'X-GitHub-Api-Version': '2025-05-01',
|
|
426
|
+
'X-Interaction-Type': 'copilot-chat',
|
|
427
|
+
'OpenAI-Intent': 'conversation-panel',
|
|
428
|
+
'Copilot-Integration-Id': 'vscode-chat',
|
|
356
429
|
...additionalHeaders,
|
|
357
430
|
...(options.enableVision &&
|
|
358
431
|
(safeModelInfo === null || safeModelInfo === void 0 ? void 0 : safeModelInfo.capabilities.vision) && {
|
|
359
|
-
|
|
360
|
-
|
|
432
|
+
'Copilot-Vision-Request': 'true',
|
|
433
|
+
'Copilot-Media-Request': 'true',
|
|
361
434
|
}),
|
|
362
435
|
},
|
|
363
436
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, ILoadOptionsFunctions, INodePropertyOptions } from
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
|
|
2
2
|
export declare class GitHubCopilotEmbeddings implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
methods: {
|