converse-mcp-server 2.19.1 → 2.19.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "converse-mcp-server",
3
- "version": "2.19.1",
3
+ "version": "2.19.3",
4
4
  "description": "Converse MCP Server - Converse with other LLMs with chat and consensus tools",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -54,6 +54,7 @@ const SUPPORTED_MODELS = {
54
54
  supportsImages: false,
55
55
  supportsTemperature: false,
56
56
  supportsWebSearch: false,
57
+ supportsReasoningEffort: true,
57
58
  timeout: 120000,
58
59
  description: 'OpenAI GPT-5 Mini via Copilot subscription',
59
60
  aliases: [],
@@ -67,6 +68,7 @@ const SUPPORTED_MODELS = {
67
68
  supportsImages: false,
68
69
  supportsTemperature: false,
69
70
  supportsWebSearch: false,
71
+ supportsReasoningEffort: true,
70
72
  timeout: 120000,
71
73
  description: 'OpenAI GPT-5.1 via Copilot subscription',
72
74
  aliases: [],
@@ -80,6 +82,7 @@ const SUPPORTED_MODELS = {
80
82
  supportsImages: false,
81
83
  supportsTemperature: false,
82
84
  supportsWebSearch: false,
85
+ supportsReasoningEffort: true,
83
86
  timeout: 300000,
84
87
  description: 'OpenAI GPT-5.1 Codex via Copilot subscription',
85
88
  aliases: [],
@@ -93,6 +96,7 @@ const SUPPORTED_MODELS = {
93
96
  supportsImages: false,
94
97
  supportsTemperature: false,
95
98
  supportsWebSearch: false,
99
+ supportsReasoningEffort: true,
96
100
  timeout: 300000,
97
101
  description: 'OpenAI GPT-5.1 Codex Mini via Copilot subscription',
98
102
  aliases: [],
@@ -106,6 +110,7 @@ const SUPPORTED_MODELS = {
106
110
  supportsImages: false,
107
111
  supportsTemperature: false,
108
112
  supportsWebSearch: false,
113
+ supportsReasoningEffort: true,
109
114
  timeout: 600000,
110
115
  description: 'OpenAI GPT-5.1 Codex Max via Copilot subscription',
111
116
  aliases: [],
@@ -119,6 +124,7 @@ const SUPPORTED_MODELS = {
119
124
  supportsImages: false,
120
125
  supportsTemperature: false,
121
126
  supportsWebSearch: false,
127
+ supportsReasoningEffort: true,
122
128
  timeout: 120000,
123
129
  description: 'OpenAI GPT-5.2 via Copilot subscription',
124
130
  aliases: ['gpt-5'],
@@ -132,6 +138,7 @@ const SUPPORTED_MODELS = {
132
138
  supportsImages: false,
133
139
  supportsTemperature: false,
134
140
  supportsWebSearch: false,
141
+ supportsReasoningEffort: true,
135
142
  timeout: 300000,
136
143
  description: 'OpenAI GPT-5.2 Codex via Copilot subscription',
137
144
  aliases: [],
@@ -145,6 +152,7 @@ const SUPPORTED_MODELS = {
145
152
  supportsImages: false,
146
153
  supportsTemperature: false,
147
154
  supportsWebSearch: false,
155
+ supportsReasoningEffort: true,
148
156
  timeout: 300000,
149
157
  description: 'OpenAI GPT-5.3 Codex via Copilot subscription',
150
158
  aliases: ['codex'],
@@ -451,6 +459,37 @@ function resolveModelAlias(name) {
451
459
  return null;
452
460
  }
453
461
 
462
+ /**
463
+ * Look up model config from SUPPORTED_MODELS by name or alias.
464
+ * Strips copilot: prefix and falls back to the base copilot config.
465
+ */
466
+ function findModelConfig(modelName) {
467
+ if (typeof modelName !== 'string') return null;
468
+
469
+ let name = modelName;
470
+ if (name.toLowerCase().startsWith('copilot:')) {
471
+ name = name.slice('copilot:'.length).trim();
472
+ }
473
+ if (!name) return SUPPORTED_MODELS.copilot;
474
+
475
+ const nameLower = name.toLowerCase();
476
+
477
+ if (SUPPORTED_MODELS[nameLower]) {
478
+ return SUPPORTED_MODELS[nameLower];
479
+ }
480
+
481
+ for (const config of Object.values(SUPPORTED_MODELS)) {
482
+ if (
483
+ config.aliases &&
484
+ config.aliases.some((alias) => alias.toLowerCase() === nameLower)
485
+ ) {
486
+ return config;
487
+ }
488
+ }
489
+
490
+ return null;
491
+ }
492
+
454
493
  /**
455
494
  * Resolve model to pass to SDK session
456
495
  * Precedence: explicit model param > config COPILOT_MODEL > omit (SDK default)
@@ -524,6 +563,25 @@ function mapReasoningEffort(effort) {
524
563
  return mapping[effort] || undefined;
525
564
  }
526
565
 
566
+ /**
567
+ * Check if a model supports reasoning effort via the Copilot SDK's models.list API.
568
+ * Results are cached by the SDK internally.
569
+ * Returns true if supported, false if not, or undefined if the check fails.
570
+ */
571
+ async function checkReasoningSupport(client, modelId) {
572
+ try {
573
+ const models = await client.listModels();
574
+ const match = models.find((m) => m.id === modelId);
575
+ if (match) {
576
+ return match.capabilities?.supports?.reasoningEffort === true;
577
+ }
578
+ return undefined;
579
+ } catch (err) {
580
+ debugLog('[Copilot SDK] Failed to query model capabilities: %s', err.message);
581
+ return undefined;
582
+ }
583
+ }
584
+
527
585
  async function* createStreamingGenerator(client, prompt, options, signal, config) {
528
586
  const { model, timeout = 120000, reasoning_effort } = options;
529
587
 
@@ -542,12 +600,46 @@ async function* createStreamingGenerator(client, prompt, options, signal, config
542
600
  if (reasoning_effort) {
543
601
  const mapped = mapReasoningEffort(reasoning_effort);
544
602
  if (mapped) {
545
- sessionConfig.reasoningEffort = mapped;
546
- debugLog(`[Copilot SDK] Setting reasoningEffort: ${mapped} (from ${reasoning_effort})`);
603
+ const effectiveModel = sessionModel || model;
604
+ const modelDef = findModelConfig(effectiveModel);
605
+
606
+ let supported;
607
+ if (modelDef && modelDef.supportsReasoningEffort !== undefined) {
608
+ // Known model with explicit flag — use it directly (fast path)
609
+ supported = modelDef.supportsReasoningEffort;
610
+ } else {
611
+ // Unknown model or no static flag — query the SDK
612
+ supported = await checkReasoningSupport(client, effectiveModel);
613
+ }
614
+
615
+ if (supported === true) {
616
+ sessionConfig.reasoningEffort = mapped;
617
+ debugLog(`[Copilot SDK] Setting reasoningEffort: ${mapped} (from ${reasoning_effort})`);
618
+ } else if (supported === false) {
619
+ debugLog(`[Copilot SDK] Model "${effectiveModel}" does not support reasoningEffort (ignored)`);
620
+ } else {
621
+ // Could not determine — try optimistically, retry without on failure
622
+ sessionConfig.reasoningEffort = mapped;
623
+ debugLog(`[Copilot SDK] Model "${effectiveModel}" support unknown — trying reasoningEffort: ${mapped}`);
624
+ }
547
625
  }
548
626
  }
549
627
 
550
- const session = await client.createSession(sessionConfig);
628
+ let session;
629
+ try {
630
+ session = await client.createSession(sessionConfig);
631
+ } catch (err) {
632
+ if (
633
+ sessionConfig.reasoningEffort &&
634
+ /does not support reasoning effort/i.test(err.message)
635
+ ) {
636
+ debugLog('[Copilot SDK] Model rejected reasoningEffort — retrying without it');
637
+ delete sessionConfig.reasoningEffort;
638
+ session = await client.createSession(sessionConfig);
639
+ } else {
640
+ throw err;
641
+ }
642
+ }
551
643
 
552
644
  try {
553
645
  yield {
@@ -716,7 +808,7 @@ export const copilotProvider = {
716
808
  const prompt = convertMessagesToPrompt(messages);
717
809
 
718
810
  const sessionModel = resolveSessionModel(model, config);
719
- const modelConfig = SUPPORTED_MODELS.copilot;
811
+ const modelConfig = findModelConfig(sessionModel || model) || SUPPORTED_MODELS.copilot;
720
812
  const invokeOptions = {
721
813
  model,
722
814
  timeout: modelConfig.timeout,
@@ -831,29 +923,6 @@ export const copilotProvider = {
831
923
  },
832
924
 
833
925
  getModelConfig(modelName) {
834
- if (typeof modelName !== 'string') return null;
835
-
836
- let name = modelName;
837
- if (name.toLowerCase().startsWith('copilot:')) {
838
- name = name.slice('copilot:'.length).trim();
839
- }
840
- if (!name) return SUPPORTED_MODELS.copilot;
841
-
842
- const nameLower = name.toLowerCase();
843
-
844
- if (SUPPORTED_MODELS[nameLower]) {
845
- return SUPPORTED_MODELS[nameLower];
846
- }
847
-
848
- for (const config of Object.values(SUPPORTED_MODELS)) {
849
- if (
850
- config.aliases &&
851
- config.aliases.some((alias) => alias.toLowerCase() === nameLower)
852
- ) {
853
- return config;
854
- }
855
- }
856
-
857
- return null;
926
+ return findModelConfig(modelName);
858
927
  },
859
928
  };
package/src/tools/chat.js CHANGED
@@ -1149,7 +1149,7 @@ chatTool.inputSchema = {
1149
1149
  model: {
1150
1150
  type: 'string',
1151
1151
  description:
1152
- 'AI model to use. Examples: "auto" (recommended), "codex", "gemini", "claude", "gpt-5", "grok-4-0709". Defaults to auto-selection.',
1152
+ 'AI model to use. Examples: "auto" (recommended), "codex", "gemini", "claude", "copilot", "copilot:codex". Defaults to auto-selection.',
1153
1153
  },
1154
1154
  files: {
1155
1155
  type: 'array',
@@ -1705,7 +1705,7 @@ consensusTool.inputSchema = {
1705
1705
  items: { type: 'string' },
1706
1706
  minItems: 1,
1707
1707
  description:
1708
- 'List of models to consult. Example: ["codex", "gemini", "claude"]',
1708
+ 'List of models to consult. Examples: ["codex", "gemini", "claude", "copilot", "copilot:codex"]',
1709
1709
  },
1710
1710
  files: {
1711
1711
  type: 'array',
@@ -1747,7 +1747,7 @@ consensusTool.inputSchema = {
1747
1747
  type: 'string',
1748
1748
  enum: ['none', 'minimal', 'low', 'medium', 'high', 'max'],
1749
1749
  description:
1750
- 'Reasoning depth for thinking models. Examples: "none" (no reasoning, fastest - GPT-5.1+ only), "low" (light analysis), "medium" (balanced), "high" (complex analysis). Default: "medium"',
1750
+ 'Reasoning depth for thinking models. Examples: "none" (no reasoning, fastest), "low" (light analysis), "medium" (balanced), "high" (complex analysis). Default: "medium"',
1751
1751
  default: 'medium',
1752
1752
  },
1753
1753
  use_websearch: {