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
@@ -14,7 +14,7 @@ async function listAvailableModels(token, enableRetry = true, maxRetries = 3) {
14
14
  for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
15
15
  try {
16
16
  const response = await fetch(GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getModelsUrl(), {
17
- method: "GET",
17
+ method: 'GET',
18
18
  headers: GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getAuthHeaders(token),
19
19
  });
20
20
  if (!response.ok) {
@@ -55,12 +55,12 @@ async function listAvailableModels(token, enableRetry = true, maxRetries = 3) {
55
55
  }
56
56
  catch (error) {
57
57
  if (attempt >= maxRetries + 1 || !enableRetry) {
58
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
58
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
59
59
  return {
60
60
  success: false,
61
61
  timestamp: new Date().toISOString(),
62
62
  error: errorMessage,
63
- details: "Failed to fetch models from GitHub Copilot API",
63
+ details: 'Failed to fetch models from GitHub Copilot API',
64
64
  retryInfo: {
65
65
  totalAttempts: retryInfo.attempts,
66
66
  totalRetries: retryInfo.retries.length,
@@ -76,8 +76,8 @@ async function listAvailableModels(token, enableRetry = true, maxRetries = 3) {
76
76
  return {
77
77
  success: false,
78
78
  timestamp: new Date().toISOString(),
79
- error: "Maximum retry attempts exceeded",
80
- details: "Failed to fetch models after all retry attempts",
79
+ error: 'Maximum retry attempts exceeded',
80
+ details: 'Failed to fetch models after all retry attempts',
81
81
  retryInfo: {
82
82
  totalAttempts: retryInfo.attempts,
83
83
  totalRetries: retryInfo.retries.length,
@@ -91,13 +91,13 @@ async function listAvailableModels(token, enableRetry = true, maxRetries = 3) {
91
91
  async function refreshModelsCache(githubToken, enableRetry = true, maxRetries = 3) {
92
92
  const startTime = Date.now();
93
93
  try {
94
- console.log("🔄 Starting models cache refresh...");
95
- console.log("🔑 Generating OAuth token...");
94
+ console.log('🔄 Starting models cache refresh...');
95
+ console.log('🔑 Generating OAuth token...');
96
96
  const oauthToken = await OAuthTokenManager_1.OAuthTokenManager.getValidOAuthToken(githubToken);
97
97
  const cacheInfoBefore = DynamicModelsManager_1.DynamicModelsManager.getCacheInfo(oauthToken);
98
- console.log("🗑️ Clearing existing cache...");
98
+ console.log('🗑️ Clearing existing cache...');
99
99
  DynamicModelsManager_1.DynamicModelsManager.clearCache(oauthToken);
100
- console.log("📥 Fetching fresh models from API...");
100
+ console.log('📥 Fetching fresh models from API...');
101
101
  const models = await DynamicModelsManager_1.DynamicModelsManager.getAvailableModels(oauthToken);
102
102
  const cacheInfoAfter = DynamicModelsManager_1.DynamicModelsManager.getCacheInfo(oauthToken);
103
103
  const executionTime = Date.now() - startTime;
@@ -112,7 +112,7 @@ async function refreshModelsCache(githubToken, enableRetry = true, maxRetries =
112
112
  };
113
113
  models.forEach((model) => {
114
114
  var _a;
115
- const vendor = model.vendor || "Unknown";
115
+ const vendor = model.vendor || 'Unknown';
116
116
  modelsByVendor[vendor] = (modelsByVendor[vendor] || 0) + 1;
117
117
  if ((_a = model.capabilities) === null || _a === void 0 ? void 0 : _a.supports) {
118
118
  const supports = model.capabilities.supports;
@@ -132,34 +132,38 @@ async function refreshModelsCache(githubToken, enableRetry = true, maxRetries =
132
132
  });
133
133
  return {
134
134
  success: true,
135
- operation: "refreshCache",
135
+ operation: 'refreshCache',
136
136
  timestamp: new Date().toISOString(),
137
137
  executionTime: `${executionTime}ms`,
138
- message: "✅ Models cache refreshed successfully",
138
+ message: '✅ Models cache refreshed successfully',
139
139
  summary: {
140
140
  totalModels: models.length,
141
141
  modelsByVendor,
142
142
  capabilities: capabilitiesCount,
143
143
  },
144
144
  cache: {
145
- before: cacheInfoBefore ? {
146
- cached: true,
147
- modelsCount: cacheInfoBefore.modelsCount,
148
- expiresIn: `${Math.round(cacheInfoBefore.expiresIn / 1000)}s`,
149
- fetchedAt: cacheInfoBefore.fetchedAt,
150
- } : {
151
- cached: false,
152
- message: "No cache existed before refresh",
153
- },
154
- after: cacheInfoAfter ? {
155
- cached: true,
156
- modelsCount: cacheInfoAfter.modelsCount,
157
- expiresIn: `${Math.round(cacheInfoAfter.expiresIn / 1000)}s`,
158
- fetchedAt: cacheInfoAfter.fetchedAt,
159
- } : {
160
- cached: false,
161
- message: "Cache refresh failed",
162
- },
145
+ before: cacheInfoBefore
146
+ ? {
147
+ cached: true,
148
+ modelsCount: cacheInfoBefore.modelsCount,
149
+ expiresIn: `${Math.round(cacheInfoBefore.expiresIn / 1000)}s`,
150
+ fetchedAt: cacheInfoBefore.fetchedAt,
151
+ }
152
+ : {
153
+ cached: false,
154
+ message: 'No cache existed before refresh',
155
+ },
156
+ after: cacheInfoAfter
157
+ ? {
158
+ cached: true,
159
+ modelsCount: cacheInfoAfter.modelsCount,
160
+ expiresIn: `${Math.round(cacheInfoAfter.expiresIn / 1000)}s`,
161
+ fetchedAt: cacheInfoAfter.fetchedAt,
162
+ }
163
+ : {
164
+ cached: false,
165
+ message: 'Cache refresh failed',
166
+ },
163
167
  },
164
168
  models: models.map((model) => {
165
169
  var _a;
@@ -174,14 +178,14 @@ async function refreshModelsCache(githubToken, enableRetry = true, maxRetries =
174
178
  }
175
179
  catch (error) {
176
180
  const executionTime = Date.now() - startTime;
177
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
181
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
178
182
  return {
179
183
  success: false,
180
- operation: "refreshCache",
184
+ operation: 'refreshCache',
181
185
  timestamp: new Date().toISOString(),
182
186
  executionTime: `${executionTime}ms`,
183
187
  error: errorMessage,
184
- message: "❌ Failed to refresh models cache",
188
+ message: '❌ Failed to refresh models cache',
185
189
  details: error instanceof Error ? error.stack : String(error),
186
190
  };
187
191
  }
@@ -193,13 +197,13 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
193
197
  let successfulTests = 0;
194
198
  let failedTests = 0;
195
199
  try {
196
- console.log("🧪 Starting Consolidated Model Test...");
200
+ console.log('🧪 Starting Consolidated Model Test...');
197
201
  const modelsResponse = await listAvailableModels(token, enableRetry, maxRetries);
198
202
  if (!modelsResponse.success || !modelsResponse.data) {
199
203
  return {
200
204
  success: false,
201
205
  timestamp: new Date().toISOString(),
202
- error: "Failed to fetch models list for consolidated test",
206
+ error: 'Failed to fetch models list for consolidated test',
203
207
  details: modelsResponse,
204
208
  };
205
209
  }
@@ -207,8 +211,8 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
207
211
  const availableModels = allModels.filter((modelItem) => {
208
212
  var _a;
209
213
  const model = modelItem;
210
- const modelType = ((_a = model.capabilities) === null || _a === void 0 ? void 0 : _a.type);
211
- return modelType !== "embeddings";
214
+ const modelType = (_a = model.capabilities) === null || _a === void 0 ? void 0 : _a.type;
215
+ return modelType !== 'embeddings';
212
216
  });
213
217
  const testMessage = "Hello! Please respond with just 'OK' to confirm you're working.";
214
218
  console.log(`📊 Testing ${availableModels.length} chat models, ${testsPerModel} times each...`);
@@ -219,7 +223,7 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
219
223
  modelInfo: {
220
224
  id: modelId,
221
225
  name: model.name || modelId,
222
- vendor: model.vendor || "unknown",
226
+ vendor: model.vendor || 'unknown',
223
227
  capabilities: model.capabilities || {},
224
228
  },
225
229
  tests: [],
@@ -239,13 +243,13 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
239
243
  modelResults.summary.totalAttempts++;
240
244
  try {
241
245
  const response = await fetch(GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getChatCompletionsUrl(), {
242
- method: "POST",
246
+ method: 'POST',
243
247
  headers: GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getAuthHeaders(token),
244
248
  body: JSON.stringify({
245
249
  model: modelId,
246
250
  messages: [
247
251
  {
248
- role: "user",
252
+ role: 'user',
249
253
  content: testMessage,
250
254
  },
251
255
  ],
@@ -267,9 +271,9 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
267
271
  testNumber: testNum,
268
272
  success: true,
269
273
  responseTime: responseTime,
270
- response: message.content || "No content",
274
+ response: message.content || 'No content',
271
275
  usage: usage || null,
272
- finishReason: firstChoice.finish_reason || "unknown",
276
+ finishReason: firstChoice.finish_reason || 'unknown',
273
277
  timestamp: new Date().toISOString(),
274
278
  };
275
279
  modelResults.tests.push(testResult);
@@ -300,7 +304,7 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
300
304
  testNumber: testNum,
301
305
  success: false,
302
306
  responseTime: responseTime,
303
- error: error instanceof Error ? error.message : "Unknown error",
307
+ error: error instanceof Error ? error.message : 'Unknown error',
304
308
  timestamp: new Date().toISOString(),
305
309
  });
306
310
  }
@@ -344,19 +348,79 @@ async function consolidatedModelTest(token, enableRetry = true, maxRetries = 3,
344
348
  modelResults: testResults,
345
349
  recommendations: generateTestRecommendations(testResults),
346
350
  };
347
- console.log("✅ Consolidated test completed successfully!");
351
+ console.log('✅ Consolidated test completed successfully!');
348
352
  return consolidatedSummary;
349
353
  }
350
354
  catch (error) {
351
355
  return {
352
356
  success: false,
353
357
  timestamp: new Date().toISOString(),
354
- error: error instanceof Error ? error.message : "Unknown error in consolidated test",
358
+ error: error instanceof Error ? error.message : 'Unknown error in consolidated test',
355
359
  partialResults: testResults,
356
360
  testDuration: Date.now() - testStartTime,
357
361
  };
358
362
  }
359
363
  }
364
+ async function testSingleModel(token, modelId, testMessage, enableRetry = true, maxRetries = 3) {
365
+ const testStart = Date.now();
366
+ try {
367
+ console.log(`🧪 Testing single model: ${modelId}`);
368
+ const response = await fetch(GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getChatCompletionsUrl(), {
369
+ method: 'POST',
370
+ headers: GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getAuthHeaders(token),
371
+ body: JSON.stringify({
372
+ model: modelId,
373
+ messages: [
374
+ {
375
+ role: 'user',
376
+ content: testMessage,
377
+ },
378
+ ],
379
+ max_tokens: 100,
380
+ temperature: 0.1,
381
+ }),
382
+ });
383
+ const testEnd = Date.now();
384
+ const responseTime = testEnd - testStart;
385
+ if (response.ok) {
386
+ const data = (await response.json());
387
+ const choices = data.choices || [];
388
+ const firstChoice = choices[0] || {};
389
+ const message = firstChoice.message || {};
390
+ const usage = data.usage || {};
391
+ return {
392
+ success: true,
393
+ modelId: modelId,
394
+ responseTime: `${responseTime}ms`,
395
+ response: message.content || 'No content',
396
+ usage: usage,
397
+ finishReason: firstChoice.finish_reason || 'unknown',
398
+ timestamp: new Date().toISOString(),
399
+ rawResponse: data,
400
+ };
401
+ }
402
+ else {
403
+ const errorText = await response.text();
404
+ return {
405
+ success: false,
406
+ modelId: modelId,
407
+ responseTime: `${responseTime}ms`,
408
+ error: `HTTP ${response.status}: ${errorText}`,
409
+ timestamp: new Date().toISOString(),
410
+ };
411
+ }
412
+ }
413
+ catch (error) {
414
+ const testEnd = Date.now();
415
+ return {
416
+ success: false,
417
+ modelId: modelId,
418
+ responseTime: `${testEnd - testStart}ms`,
419
+ error: error instanceof Error ? error.message : 'Unknown error',
420
+ timestamp: new Date().toISOString(),
421
+ };
422
+ }
423
+ }
360
424
  function generateTestRecommendations(testResults) {
361
425
  const recommendations = [];
362
426
  const modelStats = Object.entries(testResults).map(([modelId, results]) => {
@@ -376,19 +440,19 @@ function generateTestRecommendations(testResults) {
376
440
  .slice(0, 3);
377
441
  if (bestModels.length > 0) {
378
442
  recommendations.push({
379
- type: "best_performance",
380
- title: "Top Performing Models (100% success rate)",
443
+ type: 'best_performance',
444
+ title: 'Top Performing Models (100% success rate)',
381
445
  models: bestModels,
382
- description: "These models completed all tests successfully with fastest response times",
446
+ description: 'These models completed all tests successfully with fastest response times',
383
447
  });
384
448
  }
385
449
  const problematicModels = modelStats.filter((m) => m.successRate < 80);
386
450
  if (problematicModels.length > 0) {
387
451
  recommendations.push({
388
- type: "attention_needed",
389
- title: "Models Requiring Attention (< 80% success rate)",
452
+ type: 'attention_needed',
453
+ title: 'Models Requiring Attention (< 80% success rate)',
390
454
  models: problematicModels,
391
- description: "These models had reliability issues during testing",
455
+ description: 'These models had reliability issues during testing',
392
456
  });
393
457
  }
394
458
  const vendorStats = modelStats.reduce((acc, model) => {
@@ -408,10 +472,10 @@ function generateTestRecommendations(testResults) {
408
472
  vendorData.avgResponseTime = Math.round(vendorData.avgResponseTime / vendorData.count);
409
473
  });
410
474
  recommendations.push({
411
- type: "vendor_analysis",
412
- title: "Performance by Vendor",
475
+ type: 'vendor_analysis',
476
+ title: 'Performance by Vendor',
413
477
  vendors: vendorStats,
414
- description: "Comparative analysis of model performance by vendor",
478
+ description: 'Comparative analysis of model performance by vendor',
415
479
  });
416
480
  return recommendations;
417
481
  }
@@ -419,10 +483,10 @@ async function testEmbeddingModels(githubToken, enableRetry = true, maxRetries =
419
483
  var _a, _b, _c, _d;
420
484
  const testStartTime = Date.now();
421
485
  try {
422
- console.log("🧪 Testing embedding models...");
486
+ console.log('🧪 Testing embedding models...');
423
487
  const modelsUrl = `${GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.URLS.MODELS}`;
424
488
  const modelsResponse = await fetch(modelsUrl, {
425
- method: "GET",
489
+ method: 'GET',
426
490
  headers: GitHubCopilotEndpoints_1.GitHubCopilotEndpoints.getAuthHeaders(githubToken),
427
491
  });
428
492
  if (!modelsResponse.ok) {
@@ -432,12 +496,12 @@ async function testEmbeddingModels(githubToken, enableRetry = true, maxRetries =
432
496
  const embeddingModels = modelsData.data.filter((model) => {
433
497
  var _a;
434
498
  const modelType = (_a = model.capabilities) === null || _a === void 0 ? void 0 : _a.type;
435
- return modelType === "embeddings";
499
+ return modelType === 'embeddings';
436
500
  });
437
501
  console.log(`📊 Found ${embeddingModels.length} embedding models to test`);
438
502
  const oauthToken = await OAuthTokenManager_1.OAuthTokenManager.getValidOAuthToken(githubToken);
439
503
  const testResults = {};
440
- const testText = "This is a test sentence for embeddings generation.";
504
+ const testText = 'This is a test sentence for embeddings generation.';
441
505
  for (const model of embeddingModels) {
442
506
  console.log(`\n🔬 Testing model: ${model.name} (${model.id})`);
443
507
  const modelResults = {
@@ -477,7 +541,7 @@ async function testEmbeddingModels(githubToken, enableRetry = true, maxRetries =
477
541
  }
478
542
  catch (error) {
479
543
  const testDuration = Date.now() - testStart;
480
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
544
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
481
545
  modelResults.tests.push({
482
546
  testNumber: testNum,
483
547
  success: false,
@@ -532,7 +596,7 @@ async function testEmbeddingModels(githubToken, enableRetry = true, maxRetries =
532
596
  return {
533
597
  success: false,
534
598
  timestamp: new Date().toISOString(),
535
- error: error instanceof Error ? error.message : "Unknown error in embedding models test",
599
+ error: error instanceof Error ? error.message : 'Unknown error in embedding models test',
536
600
  testDuration: Date.now() - testStartTime,
537
601
  };
538
602
  }
@@ -540,64 +604,95 @@ async function testEmbeddingModels(githubToken, enableRetry = true, maxRetries =
540
604
  class GitHubCopilotTest {
541
605
  constructor() {
542
606
  this.description = {
543
- displayName: "GitHub Copilot Test",
544
- name: "gitHubCopilotTest",
545
- icon: "file:../../shared/icons/copilot.svg",
546
- group: ["transform"],
607
+ displayName: 'GitHub Copilot Test',
608
+ name: 'gitHubCopilotTest',
609
+ icon: 'file:../../shared/icons/copilot.svg',
610
+ group: ['transform'],
547
611
  version: 1,
548
- subtitle: "={{$parameter[\"testFunction\"]}}",
549
- description: "Test GitHub Copilot API credentials with predefined functions",
612
+ subtitle: '={{$parameter["testFunction"]}}',
613
+ description: 'Test GitHub Copilot API credentials with predefined functions',
550
614
  defaults: {
551
- name: "GitHub Copilot Test",
615
+ name: 'GitHub Copilot Test',
552
616
  },
553
- inputs: ["main"],
554
- outputs: ["main"],
617
+ inputs: ['main'],
618
+ outputs: ['main'],
555
619
  credentials: [
556
620
  {
557
- name: "githubCopilotApi",
621
+ name: 'githubCopilotApi',
558
622
  required: true,
559
623
  },
560
624
  ],
561
625
  properties: [
562
626
  {
563
- displayName: "Test Function",
564
- name: "testFunction",
565
- type: "options",
627
+ displayName: 'Test Function',
628
+ name: 'testFunction',
629
+ type: 'options',
566
630
  noDataExpression: true,
567
631
  options: [
568
632
  {
569
- name: "List Available Models",
570
- value: "listModels",
571
- description: "Get all models available for your GitHub Copilot subscription",
633
+ name: 'List Available Models',
634
+ value: 'listModels',
635
+ description: 'Get all models available for your GitHub Copilot subscription',
572
636
  },
573
637
  {
574
- name: "Refresh Models Cache",
575
- value: "refreshCache",
576
- description: "Force refresh the cached models list (clears cache and fetches fresh data from API)",
638
+ name: 'Refresh Models Cache',
639
+ value: 'refreshCache',
640
+ description: 'Force refresh the cached models list (clears cache and fetches fresh data from API)',
577
641
  },
578
642
  {
579
- name: "Test Embedding Models",
580
- value: "testEmbeddings",
581
- description: "Test all embedding models (text-embedding-*) with sample text generation",
643
+ name: 'Test Embedding Models',
644
+ value: 'testEmbeddings',
645
+ description: 'Test all embedding models (text-embedding-*) with sample text generation',
582
646
  },
583
647
  {
584
- name: "Test Chat Models",
585
- value: "consolidatedTest",
586
- description: "Test all available chat models 5 times each and generate comprehensive report ⚠️ This test may take up to 2 minutes to complete",
648
+ name: 'Test Chat Models',
649
+ value: 'consolidatedTest',
650
+ description: 'Test all available chat models 5 times each and generate comprehensive report ⚠️ This test may take up to 2 minutes to complete',
651
+ },
652
+ {
653
+ name: 'Test Single Chat Model',
654
+ value: 'testSingleModel',
655
+ description: 'Test a specific chat model with a custom message',
587
656
  },
588
657
  ],
589
- default: "listModels",
590
- description: "Select the test function to execute",
658
+ default: 'listModels',
659
+ description: 'Select the test function to execute',
660
+ },
661
+ {
662
+ displayName: 'Model Name or ID',
663
+ name: 'modelId',
664
+ type: 'options',
665
+ description: 'Select the model to test. Choose from the list, or specify an ID using an expression.',
666
+ typeOptions: {
667
+ loadOptionsMethod: 'getModels',
668
+ },
669
+ displayOptions: {
670
+ show: {
671
+ testFunction: ['testSingleModel'],
672
+ },
673
+ },
674
+ default: '',
591
675
  },
592
676
  {
593
- displayName: "Tests Per Model",
594
- name: "testsPerModel",
595
- type: "number",
677
+ displayName: 'Test Message',
678
+ name: 'testMessage',
679
+ type: 'string',
680
+ default: "Hello! Please respond with just 'OK' to confirm you're working.",
681
+ displayOptions: {
682
+ show: {
683
+ testFunction: ['testSingleModel'],
684
+ },
685
+ },
686
+ },
687
+ {
688
+ displayName: 'Tests Per Model',
689
+ name: 'testsPerModel',
690
+ type: 'number',
596
691
  default: 5,
597
- description: "Number of times to test each model (affects accuracy of results)",
692
+ description: 'Number of times to test each model (affects accuracy of results)',
598
693
  displayOptions: {
599
694
  show: {
600
- testFunction: ["consolidatedTest"],
695
+ testFunction: ['consolidatedTest'],
601
696
  },
602
697
  },
603
698
  typeOptions: {
@@ -606,26 +701,26 @@ class GitHubCopilotTest {
606
701
  },
607
702
  },
608
703
  {
609
- displayName: "Advanced Options",
610
- name: "advancedOptions",
611
- type: "collection",
612
- placeholder: "Add Option",
704
+ displayName: 'Advanced Options',
705
+ name: 'advancedOptions',
706
+ type: 'collection',
707
+ placeholder: 'Add Option',
613
708
  default: {},
614
- description: "Additional options for the test execution",
709
+ description: 'Additional options for the test execution',
615
710
  options: [
616
711
  {
617
- displayName: "Auto Retry on 403 Error",
618
- name: "enableRetry",
619
- type: "boolean",
712
+ displayName: 'Auto Retry on 403 Error',
713
+ name: 'enableRetry',
714
+ type: 'boolean',
620
715
  default: true,
621
- description: "Automatically retry requests when hitting TPM (Transactions Per Minute) quota limits (HTTP 403)",
716
+ description: 'Automatically retry requests when hitting TPM (Transactions Per Minute) quota limits (HTTP 403)',
622
717
  },
623
718
  {
624
- displayName: "Max Retry Attempts",
625
- name: "maxRetries",
626
- type: "number",
719
+ displayName: 'Max Retry Attempts',
720
+ name: 'maxRetries',
721
+ type: 'number',
627
722
  default: 3,
628
- description: "Maximum number of retry attempts for 403 errors",
723
+ description: 'Maximum number of retry attempts for 403 errors',
629
724
  displayOptions: {
630
725
  show: {
631
726
  enableRetry: [true],
@@ -636,20 +731,57 @@ class GitHubCopilotTest {
636
731
  },
637
732
  ],
638
733
  };
734
+ this.methods = {
735
+ loadOptions: {
736
+ async getModels() {
737
+ const credentials = await this.getCredentials('githubCopilotApi');
738
+ const token = credentials.token;
739
+ if (!token) {
740
+ throw new Error('Credentials are required to load models');
741
+ }
742
+ try {
743
+ const oauthToken = await OAuthTokenManager_1.OAuthTokenManager.getValidOAuthToken(token);
744
+ const models = await DynamicModelsManager_1.DynamicModelsManager.getAvailableModels(oauthToken);
745
+ return models
746
+ .filter((model) => {
747
+ var _a;
748
+ const type = (_a = model.capabilities) === null || _a === void 0 ? void 0 : _a.type;
749
+ return type !== 'embeddings';
750
+ })
751
+ .map((model) => {
752
+ var _a;
753
+ const multiplier = ((_a = model.billing) === null || _a === void 0 ? void 0 : _a.multiplier)
754
+ ? ` (${model.billing.multiplier}x)`
755
+ : '';
756
+ return {
757
+ name: `${model.name || model.id}${multiplier}`,
758
+ value: model.id,
759
+ description: `${model.vendor || 'GitHub'} - ${model.id}`,
760
+ };
761
+ })
762
+ .sort((a, b) => a.name.localeCompare(b.name));
763
+ }
764
+ catch (error) {
765
+ const errorMessage = error instanceof Error ? error.message : String(error);
766
+ throw new Error(`Failed to load models: ${errorMessage}`);
767
+ }
768
+ },
769
+ },
770
+ };
639
771
  }
640
772
  async execute() {
641
773
  const items = this.getInputData();
642
774
  const returnData = [];
643
775
  for (let i = 0; i < items.length; i++) {
644
776
  try {
645
- const testFunction = this.getNodeParameter("testFunction", i);
646
- const advancedOptions = this.getNodeParameter("advancedOptions", i, {});
777
+ const testFunction = this.getNodeParameter('testFunction', i);
778
+ const advancedOptions = this.getNodeParameter('advancedOptions', i, {});
647
779
  const enableRetry = advancedOptions.enableRetry !== false;
648
780
  const maxRetries = advancedOptions.maxRetries || 3;
649
- const testsPerModel = testFunction === "consolidatedTest"
650
- ? this.getNodeParameter("testsPerModel", i)
781
+ const testsPerModel = testFunction === 'consolidatedTest'
782
+ ? this.getNodeParameter('testsPerModel', i)
651
783
  : 5;
652
- const credentials = await this.getCredentials("githubCopilotApi", i);
784
+ const credentials = await this.getCredentials('githubCopilotApi', i);
653
785
  const token = credentials.token;
654
786
  if (!token) {
655
787
  throw new Error(GitHubCopilotEndpoints_1.GITHUB_COPILOT_API.ERRORS.CREDENTIALS_REQUIRED);
@@ -659,18 +791,23 @@ class GitHubCopilotTest {
659
791
  }
660
792
  let result = {};
661
793
  switch (testFunction) {
662
- case "listModels":
794
+ case 'listModels':
663
795
  result = await listAvailableModels(token, enableRetry, maxRetries);
664
796
  break;
665
- case "refreshCache":
797
+ case 'refreshCache':
666
798
  result = await refreshModelsCache(token, enableRetry, maxRetries);
667
799
  break;
668
- case "testEmbeddings":
800
+ case 'testEmbeddings':
669
801
  result = await testEmbeddingModels(token, enableRetry, maxRetries);
670
802
  break;
671
- case "consolidatedTest":
803
+ case 'consolidatedTest':
672
804
  result = await consolidatedModelTest(token, enableRetry, maxRetries, testsPerModel);
673
805
  break;
806
+ case 'testSingleModel':
807
+ const modelId = this.getNodeParameter('modelId', i);
808
+ const testMessage = this.getNodeParameter('testMessage', i);
809
+ result = await testSingleModel(token, modelId, testMessage, enableRetry, maxRetries);
810
+ break;
674
811
  default:
675
812
  throw new Error(`Unknown test function: ${testFunction}`);
676
813
  }
@@ -680,12 +817,12 @@ class GitHubCopilotTest {
680
817
  });
681
818
  }
682
819
  catch (error) {
683
- const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
820
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
684
821
  if (this.continueOnFail()) {
685
822
  returnData.push({
686
823
  json: {
687
824
  error: errorMessage,
688
- testFunction: this.getNodeParameter("testFunction", i),
825
+ testFunction: this.getNodeParameter('testFunction', i),
689
826
  },
690
827
  pairedItem: { item: i },
691
828
  });
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-github-copilot",
3
- "version": "3.38.25",
3
+ "version": "3.38.35",
4
4
  "description": "n8n community node for GitHub Copilot with CLI integration, Chat API access, and AI Chat Model for workflows with full tools and function calling support - access GPT-5, Claude, Gemini and more using your Copilot subscription",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/sufficit/n8n-nodes-github-copilot",