converse-mcp-server 3.0.1 → 3.1.0

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/docs/API.md CHANGED
@@ -410,8 +410,8 @@ Provide models as plain name strings in the `models` array. Bare names and alias
410
410
  | Model | Aliases | Context | Output | Notes |
411
411
  |-------|---------|---------|--------|-------|
412
412
  | `claude-fable-5` | `fable`, `fable-5` | 1M | 128K | Most capable, adaptive thinking + effort, images, caching, compaction |
413
- | `claude-opus-4-8` | `opus`, `opus-4.8` | 200K (1M beta) | 128K | Complex reasoning and agentic coding |
414
- | `claude-opus-4-7`, `claude-opus-4-6` | `opus-4.7`, `opus-4.6` | 200K (1M beta) | 128K | Previous Opus generations |
413
+ | `claude-opus-5` | `opus`, `opus-5` | 1M | 128K | Most capable Opus, adaptive thinking + effort, compaction |
414
+ | `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6` | `opus-4.8`, `opus-4.7`, `opus-4.6` | 200K (1M beta) | 128K | Previous Opus generations |
415
415
  | `claude-opus-4-5-20251101`, `claude-opus-4-1-20250805` | `opus-4.5`, `opus-4.1` | 200K | 64K / 32K | Earlier Opus tiers |
416
416
  | `claude-sonnet-4-6` | `sonnet`, `sonnet-4.6` | 200K (1M beta) | 64K | Best speed/intelligence balance, adaptive thinking |
417
417
  | `claude-haiku-4-5-20251001` | `haiku`, `haiku-4.5` | 200K | 64K | Fast and intelligent |
@@ -467,7 +467,7 @@ Any other model works via its full `provider/model` slug (e.g. `anthropic/claude
467
467
  **Claude** is available through the Claude Agent SDK, using Claude Code CLI authentication instead of an API key:
468
468
 
469
469
  - **Model**: `claude` (aliases: `claude-sdk`, `claude-code`) — defaults to Claude Fable 5
470
- - **Model selection**: `claude:fable` (Claude Fable 5) or `claude:opus` (Claude Opus 4.8); unknown `claude:`-prefixed names pass through to the SDK (e.g. `claude:claude-sonnet-4-6`)
470
+ - **Model selection**: `claude:fable` (Claude Fable 5) or `claude:opus` (Claude Opus 5); unknown `claude:`-prefixed names pass through to the SDK (e.g. `claude:claude-sonnet-4-6`)
471
471
  - **Authentication**: `claude login` — no `ANTHROPIC_API_KEY` needed
472
472
  - **Direct file access**: reads files from the working directory
473
473
  - `reasoning_effort` and sampling parameters are managed by the SDK
@@ -501,7 +501,7 @@ agy
501
501
  Reach these with the `copilot:` namespace (e.g. `copilot:gpt-5.6-terra`); uses your GitHub Copilot subscription (`gh auth login`) — no API key needed:
502
502
 
503
503
  - **OpenAI**: `gpt-5.6-sol` (aliases: `gpt-5.6`, `gpt-5`), `gpt-5.6-terra`, `gpt-5.6-luna` (all accept `reasoning_effort`)
504
- - **Anthropic**: `claude-fable-5` (alias: `fable`), `claude-sonnet-5` (alias: `sonnet`), `claude-opus-4.8` (aliases: `opus`, `claude`)
504
+ - **Anthropic**: `claude-fable-5` (alias: `fable`), `claude-sonnet-5` (alias: `sonnet`), `claude-opus-5` (aliases: `opus`, `claude`), `claude-opus-4.8`
505
505
  - **Google**: `gemini-3.1-pro-preview` (aliases: `gemini`, `gemini-3.1-pro`), `gemini-3.5-flash` (alias: `gemini-flash`)
506
506
  - Any other `copilot:<id>` is forwarded to the Copilot backend verbatim
507
507
 
@@ -519,9 +519,9 @@ Use `"auto"` for automatic selection, or specify exact models:
519
519
  "z-ai/glm-5.2" // OpenRouter (full slug)
520
520
  "z-ai/glm-5.2:online" // OpenRouter with web search opt-in
521
521
  "fable" // Anthropic API (-> claude-fable-5)
522
- "opus" // Anthropic API (-> claude-opus-4-8)
522
+ "opus" // Anthropic API (-> claude-opus-5)
523
523
  "claude" // Claude Agent SDK (-> Claude Fable 5)
524
- "claude:opus" // Claude Agent SDK (Claude Opus 4.8)
524
+ "claude:opus" // Claude Agent SDK (Claude Opus 5)
525
525
  "gemini" // Antigravity CLI (Gemini 3.1 Pro)
526
526
  "copilot:gpt-5.6-terra" // GitHub Copilot SDK
527
527
  ```
package/docs/PROVIDERS.md CHANGED
@@ -45,8 +45,8 @@ This guide documents all supported AI providers in the Converse MCP Server and t
45
45
  - **Environment Variable**: `ANTHROPIC_API_KEY`
46
46
  - **Supported Models**:
47
47
  - `claude-fable-5` (alias `fable`) - Most capable model for demanding reasoning and long-horizon agentic work (1M context, 128K output)
48
- - `claude-opus-4-8` (alias `opus`) - Most capable Opus for complex reasoning and agentic coding (128K output)
49
- - `claude-opus-4-7`, `claude-opus-4-6` - Previous Opus generations with adaptive thinking (128K output)
48
+ - `claude-opus-5` (alias `opus`) - Most capable Opus for complex agentic coding and deep reasoning (1M context, 128K output)
49
+ - `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6` - Previous Opus generations with adaptive thinking (128K output)
50
50
  - `claude-opus-4-5-20251101`, `claude-opus-4-1-20250805` - Legacy Opus models (64K / 32K output)
51
51
  - `claude-sonnet-4-6` (alias `sonnet`) - Best combination of speed and intelligence with adaptive thinking (64K output)
52
52
  - `claude-sonnet-4-5-20250929` - Legacy Sonnet (64K output)
@@ -194,7 +194,7 @@ agy
194
194
  - **Supported Models**:
195
195
  - `claude` (aliases: `claude-sdk`, `claude-code`) - Defaults to Claude Fable 5
196
196
  - `claude:fable` - Claude Fable 5 explicitly
197
- - `claude:opus` - Claude Opus 4.8
197
+ - `claude:opus` - Claude Opus 5
198
198
  - Other `claude:`-prefixed names pass through to the SDK (e.g. `claude:claude-sonnet-4-6`)
199
199
 
200
200
  **Key Features:**
@@ -215,7 +215,7 @@ agy
215
215
  - **Supported Models** (reach them with the `copilot:` namespace, e.g. `copilot:gpt-5.6-terra`):
216
216
  - `copilot` - Uses Copilot's default or env-configured model
217
217
  - OpenAI: `gpt-5.6-sol` (aliases: bare `gpt-5.6`, `gpt-5`), `gpt-5.6-terra` (recommended balanced tier), `gpt-5.6-luna`
218
- - Anthropic: `claude-fable-5` (alias: `fable`), `claude-sonnet-5` (alias: `sonnet`), `claude-opus-4.8` (aliases: `opus`, `claude`)
218
+ - Anthropic: `claude-fable-5` (alias: `fable`), `claude-sonnet-5` (alias: `sonnet`), `claude-opus-5` (aliases: `opus`, `claude`), `claude-opus-4.8`
219
219
  - Google: `gemini-3.1-pro-preview` (aliases: `gemini`, `gemini-3.1-pro`), `gemini-3.5-flash` (alias: `gemini-flash`)
220
220
  - **Reasoning**: The `gpt-5.6-sol`/`terra`/`luna` tiers accept `reasoning_effort`.
221
221
  - **Explicit pass-through**: Any other `copilot:<id>` model string is forwarded to the Copilot backend verbatim, so IDs outside the curated list still work while the backend accepts them.
@@ -336,10 +336,10 @@ The `models` array always holds plain model-name strings. Each string routes as
336
336
  ```text
337
337
  "gpt-5.6" // OpenAI (keyword match)
338
338
  "fable" // Anthropic (keyword match -> claude-fable-5)
339
- "opus" // Anthropic (keyword match -> claude-opus-4-8)
339
+ "opus" // Anthropic (keyword match -> claude-opus-5)
340
340
  "sonnet" // Anthropic (keyword match -> claude-sonnet-4-6)
341
341
  "claude" // Claude Agent SDK (defaults to Claude Fable 5)
342
- "claude:opus" // Claude Agent SDK (Claude Opus 4.8)
342
+ "claude:opus" // Claude Agent SDK (Claude Opus 5)
343
343
  "gemini-2.5-pro" // Google (keyword match)
344
344
  "grok-4.5" // X.AI (keyword match)
345
345
  "mistral-large" // Mistral (alias -> mistral-large-2512)
@@ -371,7 +371,7 @@ The `models` array always holds plain model-name strings. Each string routes as
371
371
 
372
372
  ### Model Not Found
373
373
  - Use exact model identifiers as listed above
374
- - Some providers support aliases (e.g., "fable" → "claude-fable-5", "opus" → "claude-opus-4-8")
374
+ - Some providers support aliases (e.g., "fable" → "claude-fable-5", "opus" → "claude-opus-5")
375
375
  - Note: bare "claude" routes to the Claude Agent SDK provider, not the Anthropic API
376
376
  - Check provider documentation for model availability in your region
377
377
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "converse-mcp-server",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
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",
@@ -93,29 +93,29 @@
93
93
  ".env.example"
94
94
  ],
95
95
  "dependencies": {
96
- "@anthropic-ai/claude-agent-sdk": "^0.3.201",
97
- "@anthropic-ai/sdk": "^0.110.0",
98
- "@github/copilot-sdk": "^1.0.5",
99
- "@google/genai": "^2.10.0",
96
+ "@anthropic-ai/claude-agent-sdk": "^0.3.215",
97
+ "@anthropic-ai/sdk": "^0.112.3",
98
+ "@github/copilot-sdk": "^1.0.7",
99
+ "@google/genai": "^2.12.0",
100
100
  "@lydell/node-pty": "1.2.0-beta.12",
101
- "@mistralai/mistralai": "^2.4.1",
101
+ "@mistralai/mistralai": "^2.5.0",
102
102
  "@modelcontextprotocol/sdk": "^1.29.0",
103
- "@openai/codex-sdk": "^0.144.1",
103
+ "@openai/codex-sdk": "^0.144.6",
104
104
  "ai": "^6.0.208",
105
105
  "cors": "^2.8.6",
106
106
  "dotenv": "^17.4.2",
107
107
  "express": "^5.2.1",
108
- "lru-cache": "^11.5.1",
108
+ "lru-cache": "^11.5.2",
109
109
  "nanoid": "^5.1.16",
110
- "openai": "^6.45.0",
110
+ "openai": "^6.48.0",
111
111
  "p-limit": "^7.3.0",
112
- "vite": "^8.1.3"
112
+ "vite": "^8.1.5"
113
113
  },
114
114
  "devDependencies": {
115
- "@vitest/coverage-v8": "^4.1.9",
115
+ "@vitest/coverage-v8": "^4.1.10",
116
116
  "cross-env": "^10.1.0",
117
- "eslint": "^10.6.0",
117
+ "eslint": "^10.7.0",
118
118
  "rimraf": "^6.1.3",
119
- "vitest": "^4.1.9"
119
+ "vitest": "^4.1.10"
120
120
  }
121
121
  }
@@ -38,6 +38,32 @@ const SUPPORTED_MODELS = {
38
38
  'fable',
39
39
  ],
40
40
  },
41
+ 'claude-opus-5': {
42
+ modelName: 'claude-opus-5',
43
+ friendlyName: 'Claude Opus 5',
44
+ contextWindow: 1000000, // 1M context by default - no beta header required
45
+ maxOutputTokens: 128000,
46
+ supportsStreaming: true,
47
+ supportsImages: true,
48
+ supportsWebSearch: false,
49
+ supportsThinking: true,
50
+ supportsAdaptiveThinking: true, // Thinking is on by default; adaptive is the only on-mode
51
+ timeout: 600000,
52
+ supportsEffort: true,
53
+ effortGA: true,
54
+ supportsCompaction: true,
55
+ description:
56
+ 'Claude Opus 5 - Most capable Opus for complex agentic coding and deep reasoning',
57
+ aliases: [
58
+ 'claude-opus-5',
59
+ 'claude-5-opus',
60
+ 'opus-5',
61
+ 'opus5',
62
+ 'claude-opus-5.0',
63
+ 'opus',
64
+ 'claude-opus',
65
+ ],
66
+ },
41
67
  'claude-opus-4-8': {
42
68
  modelName: 'claude-opus-4-8',
43
69
  friendlyName: 'Claude Opus 4.8',
@@ -56,7 +82,7 @@ const SUPPORTED_MODELS = {
56
82
  supports1MContext: true,
57
83
  supportsCompaction: true,
58
84
  description:
59
- 'Claude Opus 4.8 - Most capable model for complex reasoning and agentic coding',
85
+ 'Claude Opus 4.8 - Previous Opus generation for complex reasoning and agentic coding',
60
86
  aliases: [
61
87
  'claude-opus-4-8',
62
88
  'claude-4.8-opus',
@@ -66,8 +92,6 @@ const SUPPORTED_MODELS = {
66
92
  'opus4.8',
67
93
  'opus4-8',
68
94
  'claude-opus-4.8',
69
- 'opus',
70
- 'claude-opus',
71
95
  ],
72
96
  },
73
97
  'claude-opus-4-7': {
@@ -291,7 +315,7 @@ const THINKING_BUDGETS = {
291
315
  };
292
316
 
293
317
  /**
294
- * Effort parameter mapping for Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6, and Opus 4.5
318
+ * Effort parameter mapping for Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6, and Opus 4.5
295
319
  * Maps reasoning_effort values to Anthropic's effort parameter values
296
320
  */
297
321
  const EFFORT_MAP = {
@@ -43,17 +43,17 @@ const SUPPORTED_MODELS = {
43
43
  ],
44
44
  },
45
45
  opus: {
46
- modelName: 'claude-opus-4-8',
47
- friendlyName: 'Claude Opus 4.8 (via Agent SDK)',
48
- contextWindow: 200000,
46
+ modelName: 'claude-opus-5',
47
+ friendlyName: 'Claude Opus 5 (via Agent SDK)',
48
+ contextWindow: 1000000,
49
49
  maxOutputTokens: 128000,
50
50
  supportsStreaming: true,
51
51
  supportsImages: true, // Supported via streaming input mode
52
52
  supportsWebSearch: false, // SDK accesses files directly, not web
53
53
  timeout: 600000, // 10 minutes
54
54
  description:
55
- 'Claude Opus 4.8 via Agent SDK - requires claude login authentication',
56
- aliases: ['claude:opus', 'claude-opus-4-8'],
55
+ 'Claude Opus 5 via Agent SDK - requires claude login authentication',
56
+ aliases: ['claude:opus', 'claude-opus-5'],
57
57
  },
58
58
  };
59
59
 
@@ -481,7 +481,7 @@ export const claudeProvider = {
481
481
  debugLog('[Claude SDK] Using streaming input mode for image support');
482
482
  }
483
483
 
484
- // Resolve requested model (claude/claude:fable -> claude-fable-5, claude:opus -> claude-opus-4-8)
484
+ // Resolve requested model (claude/claude:fable -> claude-fable-5, claude:opus -> claude-opus-5)
485
485
  const sdkModel = resolveSdkModel(model);
486
486
  debugLog(`[Claude SDK] Resolved model "${model}" -> "${sdkModel}"`);
487
487
 
@@ -27,6 +27,11 @@ const SUPPORTED_MODELS = {
27
27
  supportsStreaming: true,
28
28
  supportsImages: true, // Codex SDK 0.118+ supports images via --image (local_image input)
29
29
  supportsWebSearch: false, // Codex accesses files directly, not web
30
+ // Reasoning tiers this model's backend actually accepts. GPT-5.6 dropped
31
+ // 'minimal' and added 'none', while the SDK's ModelReasoningEffort type
32
+ // still advertises the pre-5.6 set — the backend is the authority, so the
33
+ // accepted tiers are declared per model and requests are clamped onto them.
34
+ supportedEfforts: ['none', 'low', 'medium', 'high', 'xhigh'],
30
35
  timeout: 600000, // 10 minutes
31
36
  description:
32
37
  'OpenAI Codex agentic coding assistant with local file access and tool execution (GPT-5.6)',
@@ -212,20 +217,77 @@ async function getThreadIdFromContinuation(
212
217
  }
213
218
 
214
219
  /**
215
- * Map tool-level reasoning_effort values to Codex SDK's ModelReasoningEffort.
216
- * Tool enum: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'max'
217
- * SDK enum: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
220
+ * Every Codex reasoning tier, weakest to strongest. Used to clamp a requested
221
+ * tier onto the set a given model actually accepts.
218
222
  */
219
- function mapReasoningEffort(effort) {
220
- const mapping = {
221
- none: 'minimal',
222
- minimal: 'minimal',
223
- low: 'low',
224
- medium: 'medium',
225
- high: 'high',
226
- max: 'xhigh',
227
- };
228
- return mapping[effort] || 'medium';
223
+ const EFFORT_LADDER = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh'];
224
+
225
+ /**
226
+ * Tool-level reasoning_effort values translated to their Codex equivalent.
227
+ * Tool enum: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'max'
228
+ */
229
+ const EFFORT_ALIASES = {
230
+ none: 'none',
231
+ minimal: 'minimal',
232
+ low: 'low',
233
+ medium: 'medium',
234
+ high: 'high',
235
+ max: 'xhigh',
236
+ };
237
+
238
+ /**
239
+ * Map a tool-level reasoning_effort onto a tier the target model accepts.
240
+ *
241
+ * When the requested tier isn't in the model's supported set, the nearest
242
+ * *stronger* tier wins: nudging 'minimal' up to 'low' keeps reasoning on,
243
+ * where falling back to 'none' would silently switch it off.
244
+ *
245
+ * @param {string} effort - Tool-level reasoning_effort value
246
+ * @param {string[]} [supported] - Tiers the model accepts
247
+ * @returns {string} A tier from `supported`
248
+ */
249
+ export function mapReasoningEffort(effort, supported = EFFORT_LADDER) {
250
+ const desired = EFFORT_ALIASES[effort] || 'medium';
251
+ if (supported.includes(desired)) {
252
+ return desired;
253
+ }
254
+
255
+ const rank = EFFORT_LADDER.indexOf(desired);
256
+ const stronger = EFFORT_LADDER.slice(rank + 1).find((tier) =>
257
+ supported.includes(tier),
258
+ );
259
+ if (stronger) {
260
+ return stronger;
261
+ }
262
+
263
+ const weaker = EFFORT_LADDER.slice(0, rank)
264
+ .reverse()
265
+ .find((tier) => supported.includes(tier));
266
+ return weaker || 'medium';
267
+ }
268
+
269
+ /**
270
+ * Resolve a user-facing model name to its entry in SUPPORTED_MODELS.
271
+ * @param {string} modelName
272
+ * @returns {Object|null}
273
+ */
274
+ function findModelConfig(modelName) {
275
+ const modelNameLower = String(modelName || '').toLowerCase();
276
+
277
+ if (SUPPORTED_MODELS[modelNameLower]) {
278
+ return SUPPORTED_MODELS[modelNameLower];
279
+ }
280
+
281
+ for (const config of Object.values(SUPPORTED_MODELS)) {
282
+ if (
283
+ config.aliases &&
284
+ config.aliases.some((alias) => alias.toLowerCase() === modelNameLower)
285
+ ) {
286
+ return config;
287
+ }
288
+ }
289
+
290
+ return null;
229
291
  }
230
292
 
231
293
  /**
@@ -350,7 +412,16 @@ export const codexProvider = {
350
412
  };
351
413
 
352
414
  if (reasoning_effort) {
353
- threadOptions.modelReasoningEffort = mapReasoningEffort(reasoning_effort);
415
+ const supportedEfforts =
416
+ findModelConfig(model)?.supportedEfforts ||
417
+ SUPPORTED_MODELS.codex.supportedEfforts;
418
+ const mappedEffort = mapReasoningEffort(reasoning_effort, supportedEfforts);
419
+ threadOptions.modelReasoningEffort = mappedEffort;
420
+ if (mappedEffort !== EFFORT_ALIASES[reasoning_effort]) {
421
+ debugLog(
422
+ `[Codex] reasoning_effort "${reasoning_effort}" not supported by ${model} — using "${mappedEffort}"`,
423
+ );
424
+ }
354
425
  }
355
426
 
356
427
  const thread = threadId
@@ -479,23 +550,6 @@ export const codexProvider = {
479
550
  * Get model configuration for specific model
480
551
  */
481
552
  getModelConfig(modelName) {
482
- const modelNameLower = modelName.toLowerCase();
483
-
484
- // Check exact match
485
- if (SUPPORTED_MODELS[modelNameLower]) {
486
- return SUPPORTED_MODELS[modelNameLower];
487
- }
488
-
489
- // Check aliases
490
- for (const [_name, config] of Object.entries(SUPPORTED_MODELS)) {
491
- if (
492
- config.aliases &&
493
- config.aliases.some((alias) => alias.toLowerCase() === modelNameLower)
494
- ) {
495
- return config;
496
- }
497
- }
498
-
499
- return null;
553
+ return findModelConfig(modelName);
500
554
  },
501
555
  };
@@ -36,6 +36,9 @@ const SUPPORTED_MODELS = {
36
36
  // OpenAI models
37
37
  // Bare `gpt-5.6` (and the legacy `gpt-5` shortcut) route to Sol, matching
38
38
  // Copilot's own bare-alias behavior. Terra is the recommended balanced tier.
39
+ // `codex` and `gpt` point at the latest GPT tier (reachable only via the
40
+ // `copilot:` namespace — bare `codex` routes to the Codex provider and bare
41
+ // `gpt*` keyword-routes to OpenAI before Copilot's catalog is consulted).
39
42
  'gpt-5.6-sol': {
40
43
  modelName: 'gpt-5.6-sol',
41
44
  friendlyName: 'GPT-5.6 Sol (via Copilot)',
@@ -47,7 +50,7 @@ const SUPPORTED_MODELS = {
47
50
  supportsReasoningEffort: true,
48
51
  timeout: 600000,
49
52
  description: 'OpenAI GPT-5.6 Sol via Copilot subscription',
50
- aliases: ['gpt-5.6', 'gpt-5'],
53
+ aliases: ['gpt-5.6', 'gpt-5', 'gpt', 'codex'],
51
54
  },
52
55
  'gpt-5.6-terra': {
53
56
  modelName: 'gpt-5.6-terra',
@@ -101,6 +104,18 @@ const SUPPORTED_MODELS = {
101
104
  description: 'Anthropic Claude Sonnet 5 via Copilot subscription',
102
105
  aliases: ['sonnet'],
103
106
  },
107
+ 'claude-opus-5': {
108
+ modelName: 'claude-opus-5',
109
+ friendlyName: 'Claude Opus 5 (via Copilot)',
110
+ contextWindow: 200000,
111
+ maxOutputTokens: 32768,
112
+ supportsStreaming: true,
113
+ supportsImages: false,
114
+ supportsWebSearch: false,
115
+ timeout: 600000,
116
+ description: 'Anthropic Claude Opus 5 via Copilot subscription',
117
+ aliases: ['opus', 'claude'],
118
+ },
104
119
  'claude-opus-4.8': {
105
120
  modelName: 'claude-opus-4.8',
106
121
  friendlyName: 'Claude Opus 4.8 (via Copilot)',
@@ -111,7 +126,7 @@ const SUPPORTED_MODELS = {
111
126
  supportsWebSearch: false,
112
127
  timeout: 600000,
113
128
  description: 'Anthropic Claude Opus 4.8 via Copilot subscription',
114
- aliases: ['opus', 'claude'],
129
+ aliases: [],
115
130
  },
116
131
 
117
132
  // Google models