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.
Files changed (48) hide show
  1. package/dist/credentials/GitHubCopilotApi.credentials.d.ts +1 -1
  2. package/dist/credentials/GitHubCopilotApi.credentials.js +25 -25
  3. package/dist/nodes/GitHubCopilot/GitHubCopilot.node.d.ts +1 -1
  4. package/dist/nodes/GitHubCopilot/GitHubCopilot.node.js +166 -166
  5. package/dist/nodes/GitHubCopilotAuthHelper/GitHubCopilotAuthHelper.node.d.ts +1 -1
  6. package/dist/nodes/GitHubCopilotAuthHelper/GitHubCopilotAuthHelper.node.js +539 -539
  7. package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.d.ts +1 -1
  8. package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.js +46 -44
  9. package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.d.ts +1 -1
  10. package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.js +82 -82
  11. package/dist/nodes/GitHubCopilotChatAPI/utils/helpers.d.ts +2 -2
  12. package/dist/nodes/GitHubCopilotChatAPI/utils/helpers.js +26 -26
  13. package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.d.ts +2 -2
  14. package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.js +12 -12
  15. package/dist/nodes/GitHubCopilotChatAPI/utils/index.d.ts +4 -4
  16. package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.d.ts +3 -3
  17. package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.js +19 -19
  18. package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.d.ts +1 -1
  19. package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.js +23 -23
  20. package/dist/nodes/GitHubCopilotChatAPI/utils/types.d.ts +5 -5
  21. package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.d.ts +2 -2
  22. package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.js +198 -125
  23. package/dist/nodes/GitHubCopilotEmbeddings/GitHubCopilotEmbeddings.node.d.ts +1 -1
  24. package/dist/nodes/GitHubCopilotEmbeddings/GitHubCopilotEmbeddings.node.js +114 -114
  25. package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.d.ts +1 -1
  26. package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.js +74 -69
  27. package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.d.ts +1 -1
  28. package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.js +181 -181
  29. package/dist/nodes/GitHubCopilotOpenAI/utils/index.d.ts +2 -2
  30. package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.d.ts +10 -10
  31. package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.js +53 -53
  32. package/dist/nodes/GitHubCopilotOpenAI/utils/types.d.ts +12 -12
  33. package/dist/nodes/GitHubCopilotSpeech/GitHubCopilotSpeech.node.d.ts +10 -4
  34. package/dist/nodes/GitHubCopilotSpeech/GitHubCopilotSpeech.node.js +8 -7
  35. package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.d.ts +6 -1
  36. package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.js +253 -116
  37. package/dist/package.json +1 -1
  38. package/dist/shared/models/GitHubCopilotModels.js +19 -2
  39. package/dist/shared/models/ModelVersionRequirements.js +5 -0
  40. package/dist/shared/utils/DynamicModelsManager.d.ts +9 -0
  41. package/dist/shared/utils/DynamicModelsManager.js +48 -6
  42. package/dist/shared/utils/FileChunkingApiUtils.d.ts +2 -2
  43. package/dist/shared/utils/FileChunkingApiUtils.js +15 -15
  44. package/dist/shared/utils/FileOptimizationUtils.d.ts +2 -2
  45. package/dist/shared/utils/FileOptimizationUtils.js +20 -20
  46. package/dist/shared/utils/GitHubCopilotApiUtils.js +6 -2
  47. package/dist/shared/utils/GitHubCopilotEndpoints.js +10 -1
  48. 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("No messages provided for generation");
26
+ throw new Error('No messages provided for generation');
21
27
  }
22
- let copilotMessages = messages.map(msg => {
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 = msg.content;
39
- if (typeof content === 'string') {
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(content)) {
42
- console.warn(`⚠️ Complex content detected, stringifying:`, content);
43
- content = JSON.stringify(content);
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 (content === null || content === undefined) {
99
+ else if (rawContent === null || rawContent === undefined) {
46
100
  content = '';
47
101
  }
48
102
  else {
49
- console.warn(`⚠️ Non-string content detected, stringifying:`, typeof content);
50
- content = JSON.stringify(content);
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
- if (!msg.content || msg.content.trim() === '') {
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("No valid messages after filtering empty content");
132
+ throw new Error('No valid messages after filtering empty content');
76
133
  }
77
134
  const requestBody = {
78
- model: this.modelName || this.model,
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 || "auto";
88
- console.log(`🔧 Request includes ${this.options.tools.length} tools`);
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, false);
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("GitHub Copilot API returned no choices in response");
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("GitHub Copilot API returned choice without message");
162
+ throw new Error('GitHub Copilot API returned choice without message');
102
163
  }
103
- const langchainMessage = {
104
- _getType: () => choice.message.role,
105
- content: choice.message.content || "",
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
- text: choice.message.content || "",
112
- generationInfo: {
113
- finish_reason: choice.finish_reason,
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: "GitHub Copilot Chat Model",
132
- name: "gitHubCopilotChatModel",
133
- icon: "file:../../shared/icons/copilot.svg",
134
- group: ["transform"],
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: "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",
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: "GitHub Copilot Chat Model",
200
+ name: 'GitHub Copilot Chat Model',
139
201
  },
140
202
  codex: {
141
- categories: ["AI"],
203
+ categories: ['AI'],
142
204
  subcategories: {
143
- AI: ["Language Models", "Root Nodes"],
144
- "Language Models": ["Chat Models (Recommended)"],
205
+ AI: ['Language Models', 'Root Nodes'],
206
+ 'Language Models': ['Chat Models (Recommended)'],
145
207
  },
146
208
  resources: {
147
209
  primaryDocumentation: [
148
210
  {
149
- url: "https://docs.github.com/copilot/using-github-copilot/using-github-copilot-chat",
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: ["ai_languageModel"],
156
- outputNames: ["Model"],
217
+ outputs: ['ai_languageModel'],
218
+ outputNames: ['Model'],
157
219
  credentials: [
158
220
  {
159
- name: "githubCopilotApi",
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: "Options",
167
- name: "options",
168
- placeholder: "Add Option",
169
- description: "Additional options for the GitHub Copilot model",
170
- type: "collection",
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: "Temperature",
175
- name: "temperature",
236
+ displayName: 'Temperature',
237
+ name: 'temperature',
176
238
  default: 0.7,
177
239
  typeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },
178
- description: "Controls randomness in output. Lower values make responses more focused.",
179
- type: "number",
240
+ description: 'Controls randomness in output. Lower values make responses more focused.',
241
+ type: 'number',
180
242
  },
181
243
  {
182
- displayName: "Maximum Number of Tokens",
183
- name: "maxTokens",
244
+ displayName: 'Maximum Number of Tokens',
245
+ name: 'maxTokens',
184
246
  default: 1000,
185
- description: "The maximum number of tokens to generate",
186
- type: "number",
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: "Top P",
193
- name: "topP",
254
+ displayName: 'Top P',
255
+ name: 'topP',
194
256
  default: 1,
195
257
  typeOptions: { maxValue: 1, minValue: 0, numberPrecision: 2 },
196
- description: "Controls diversity of output by nucleus sampling",
197
- type: "number",
258
+ description: 'Controls diversity of output by nucleus sampling',
259
+ type: 'number',
198
260
  },
199
261
  {
200
- displayName: "Enable Streaming",
201
- name: "enableStreaming",
202
- type: "boolean",
262
+ displayName: 'Enable Streaming',
263
+ name: 'enableStreaming',
264
+ type: 'boolean',
203
265
  default: false,
204
- description: "Enable streaming responses for real-time output (experimental)",
266
+ description: 'Enable streaming responses for real-time output (experimental)',
205
267
  },
206
268
  {
207
- displayName: "System Message",
208
- name: "systemMessage",
209
- type: "string",
210
- default: "",
211
- description: "System message to set the behavior of the assistant",
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: "Auto Retry on 403 Error",
218
- name: "enableRetry",
219
- type: "boolean",
279
+ displayName: 'Auto Retry on 403 Error',
280
+ name: 'enableRetry',
281
+ type: 'boolean',
220
282
  default: true,
221
- description: "Automatically retry requests when hitting TPM (Transactions Per Minute) quota limits (HTTP 403)",
283
+ description: 'Automatically retry requests when hitting TPM (Transactions Per Minute) quota limits (HTTP 403)',
222
284
  },
223
285
  {
224
- displayName: "Request Timeout (seconds)",
225
- name: "timeout",
226
- type: "number",
286
+ displayName: 'Request Timeout (seconds)',
287
+ name: 'timeout',
288
+ type: 'number',
227
289
  default: 120,
228
- description: "Maximum time to wait for API response (in seconds)",
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: "Tools (Function Calling)",
236
- name: "tools",
237
- type: "string",
238
- default: "",
239
- description: "Optional: Array of tools/functions available to the model (OpenAI format). Leave empty if not using function calling.",
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: "Tool Choice",
247
- name: "tool_choice",
248
- type: "options",
308
+ displayName: 'Tool Choice',
309
+ name: 'tool_choice',
310
+ type: 'options',
249
311
  options: [
250
312
  {
251
- name: "Auto",
252
- value: "auto",
253
- description: "Let the model decide when to use tools",
313
+ name: 'Auto',
314
+ value: 'auto',
315
+ description: 'Let the model decide when to use tools',
254
316
  },
255
317
  {
256
- name: "Required",
257
- value: "required",
258
- description: "Force the model to use at least one tool",
318
+ name: 'Required',
319
+ value: 'required',
320
+ description: 'Force the model to use at least one tool',
259
321
  },
260
322
  {
261
- name: "None",
262
- value: "none",
263
- description: "Disable tool usage",
323
+ name: 'None',
324
+ value: 'none',
325
+ description: 'Disable tool usage',
264
326
  },
265
327
  ],
266
- default: "auto",
267
- description: "Control how the model uses tools",
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("model", itemIndex);
288
- if (model === "__manual__") {
289
- const customModel = this.getNodeParameter("customModel", itemIndex);
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("options", itemIndex, {});
368
+ const options = this.getNodeParameter('options', itemIndex, {});
300
369
  const modelInfo = GitHubCopilotModels_1.GitHubCopilotModelsManager.getModelByValue(model);
301
- const credentials = (await this.getCredentials("githubCopilotApi"));
370
+ const credentials = (await this.getCredentials('githubCopilotApi'));
302
371
  const token = credentials.token;
303
372
  if (!token) {
304
- console.error("❌ Available credential properties:", Object.keys(credentials));
305
- throw new Error("GitHub Copilot: No token found in credentials. Available properties: " +
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("_") + 1)) || token.substring(0, 4);
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("gho_") &&
312
- !token.startsWith("ghu_") &&
313
- !token.startsWith("github_pat_")) {
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 = modelInfo ? model : GitHubCopilotModels_1.DEFAULT_MODELS.GENERAL;
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 : "Unknown error"}`);
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 || "auto",
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
- "User-Agent": "GitHubCopilotChat/1.0.0 n8n/3.10.1",
352
- Accept: "application/json",
353
- "Editor-Version": `vscode/${minVSCodeVersion}`,
354
- "Editor-Plugin-Version": "copilot-chat/0.12.0",
355
- "X-Request-Id": `n8n-chatmodel-${Date.now()}-${Math.random().toString(36).substring(7)}`,
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
- "Copilot-Vision-Request": "true",
360
- "Copilot-Media-Request": "true",
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 "n8n-workflow";
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: {