@link-assistant/hive-mind 1.61.0 → 1.62.1

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.
@@ -129,12 +129,25 @@ export const codexModels = {
129
129
  'gpt-4o': 'gpt-4o',
130
130
  };
131
131
 
132
+ // Qwen Code models
133
+ export const qwenModels = {
134
+ qwen: 'qwen3-coder-plus',
135
+ 'qwen-coder': 'qwen3-coder-plus',
136
+ qwen3: 'qwen3-coder-plus',
137
+ 'qwen3-coder': 'qwen3-coder',
138
+ 'qwen3-coder-plus': 'qwen3-coder-plus',
139
+ 'qwen3-coder-flash': 'qwen3-coder-flash',
140
+ 'qwen3.6-plus': 'qwen3.6-plus',
141
+ 'qwen3.6-coder-plus': 'qwen3.6-coder-plus',
142
+ };
143
+
132
144
  // Default model for each tool (Issue #1473: centralized to avoid scattered hardcoded defaults)
133
145
  export const defaultModels = {
134
146
  claude: 'sonnet',
135
147
  agent: 'nemotron-3-super-free', // Issue #1563: changed from qwen3.6-plus-free (free promotion ended) per agent PR #243
136
148
  opencode: 'grok-code-fast-1',
137
149
  codex: 'gpt-5.5',
150
+ qwen: 'qwen3-coder-plus',
138
151
  };
139
152
 
140
153
  // Models that support 1M token context window via [1m] suffix (Issue #1221, Issue #1238, Issue #1329)
@@ -214,6 +227,15 @@ export const CODEX_MODELS = {
214
227
  'gpt-4o': 'gpt-4o',
215
228
  };
216
229
 
230
+ export const QWEN_MODELS = {
231
+ ...qwenModels,
232
+ 'qwen3-coder': 'qwen3-coder',
233
+ 'qwen3-coder-plus': 'qwen3-coder-plus',
234
+ 'qwen3-coder-flash': 'qwen3-coder-flash',
235
+ 'qwen3.6-plus': 'qwen3.6-plus',
236
+ 'qwen3.6-coder-plus': 'qwen3.6-coder-plus',
237
+ };
238
+
217
239
  export const AGENT_MODELS = {
218
240
  ...agentModels,
219
241
  'opencode/grok-code': 'opencode/grok-code',
@@ -235,7 +257,7 @@ export const AGENT_MODELS = {
235
257
 
236
258
  /**
237
259
  * Get the model map object for a given tool
238
- * @param {string} tool - The tool name (claude, agent, opencode, codex)
260
+ * @param {string} tool - The tool name (claude, agent, opencode, codex, qwen)
239
261
  * @returns {Object} The model mapping for the tool
240
262
  */
241
263
  export const getModelMapForTool = tool => {
@@ -248,6 +270,8 @@ export const getModelMapForTool = tool => {
248
270
  return opencodeModels;
249
271
  case 'codex':
250
272
  return codexModels;
273
+ case 'qwen':
274
+ return qwenModels;
251
275
  default:
252
276
  return claudeModels;
253
277
  }
@@ -255,7 +279,7 @@ export const getModelMapForTool = tool => {
255
279
 
256
280
  /**
257
281
  * Get the default model for a given tool
258
- * @param {string} tool - The tool name (claude, agent, opencode, codex)
282
+ * @param {string} tool - The tool name (claude, agent, opencode, codex, qwen)
259
283
  * @returns {string} The default model alias for the tool
260
284
  */
261
285
  export const getDefaultModelForTool = tool => {
@@ -308,7 +332,7 @@ export const resolveRuntimeDefaultModel = async (tool, options = {}) => {
308
332
 
309
333
  /**
310
334
  * Map model name to full model ID for a specific tool
311
- * @param {string} tool - The tool name (claude, agent, opencode, codex)
335
+ * @param {string} tool - The tool name (claude, agent, opencode, codex, qwen)
312
336
  * @param {string} model - The model name or alias
313
337
  * @returns {string} The full model ID
314
338
  */
@@ -322,6 +346,8 @@ export const mapModelForTool = (tool, model) => {
322
346
  return opencodeModels[model] || model;
323
347
  case 'codex':
324
348
  return codexModels[model] || model;
349
+ case 'qwen':
350
+ return qwenModels[model] || model;
325
351
  default:
326
352
  return model;
327
353
  }
@@ -329,7 +355,7 @@ export const mapModelForTool = (tool, model) => {
329
355
 
330
356
  /**
331
357
  * Validate if a model is compatible with a tool
332
- * @param {string} tool - The tool name (claude, agent, opencode, codex)
358
+ * @param {string} tool - The tool name (claude, agent, opencode, codex, qwen)
333
359
  * @param {string} model - The model name or alias
334
360
  * @returns {boolean} True if the model is compatible with the tool
335
361
  */
@@ -345,6 +371,8 @@ export const isModelCompatibleWithTool = (tool, model) => {
345
371
  return mappedModel.includes('/') || Object.keys(opencodeModels).includes(model);
346
372
  case 'codex':
347
373
  return Object.keys(codexModels).includes(model) || mappedModel.startsWith('gpt-');
374
+ case 'qwen':
375
+ return Object.keys(qwenModels).includes(model) || mappedModel.startsWith('qwen');
348
376
  default:
349
377
  return true;
350
378
  }
@@ -365,6 +393,8 @@ export const getValidModelsForTool = tool => {
365
393
  return Object.keys(opencodeModels);
366
394
  case 'codex':
367
395
  return Object.keys(codexModels);
396
+ case 'qwen':
397
+ return Object.keys(qwenModels);
368
398
  default:
369
399
  return [];
370
400
  }
@@ -377,6 +407,7 @@ export const primaryModelNames = {
377
407
  opencode: ['grok', 'gpt4o'],
378
408
  codex: ['gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.3-codex', 'gpt-5.3-codex-spark'],
379
409
  agent: ['nemotron-3-super-free', 'minimax-m2.5-free', 'big-pickle', 'gpt-5-nano', 'glm-5-free', 'deepseek-r1-free'],
410
+ qwen: ['qwen3-coder-plus', 'qwen3-coder', 'qwen3-coder-flash'],
380
411
  };
381
412
 
382
413
  /**
@@ -416,7 +447,7 @@ export const validateToolModelCompatibility = (tool, model) => {
416
447
 
417
448
  /**
418
449
  * Get the model map for a given tool (validation-extended version with full ID entries)
419
- * @param {string} tool - The tool name ('claude', 'opencode', 'codex', 'agent')
450
+ * @param {string} tool - The tool name ('claude', 'opencode', 'codex', 'agent', 'qwen')
420
451
  * @returns {Object} The model mapping for the tool
421
452
  */
422
453
  const getValidationModelMapForTool = tool => {
@@ -427,6 +458,8 @@ const getValidationModelMapForTool = tool => {
427
458
  return CODEX_MODELS;
428
459
  case 'agent':
429
460
  return AGENT_MODELS;
461
+ case 'qwen':
462
+ return QWEN_MODELS;
430
463
  case 'claude':
431
464
  default:
432
465
  return CLAUDE_MODELS;
@@ -435,7 +468,7 @@ const getValidationModelMapForTool = tool => {
435
468
 
436
469
  /**
437
470
  * Get the list of available model names for a tool (for display in help/error messages)
438
- * @param {string} tool - The tool name ('claude', 'opencode', 'codex', 'agent')
471
+ * @param {string} tool - The tool name ('claude', 'opencode', 'codex', 'agent', 'qwen')
439
472
  * @returns {string[]} Array of available model short names
440
473
  */
441
474
  export const getAvailableModelNames = tool => {
@@ -574,7 +607,7 @@ export const supports1mContext = (model, tool = 'claude') => {
574
607
  * Validate a model name against the available models for a tool
575
608
  * Supports [1m] suffix for 1 million token context (Issue #1221)
576
609
  * @param {string} model - The model name to validate (e.g., "opus", "opus[1m]", "claude-opus-4-6[1m]")
577
- * @param {string} tool - The tool name ('claude', 'opencode', 'codex')
610
+ * @param {string} tool - The tool name ('claude', 'opencode', 'codex', 'agent', 'qwen')
578
611
  * @returns {{ valid: boolean, message?: string, suggestions?: string[], mappedModel?: string, has1mSuffix?: boolean }}
579
612
  */
580
613
  export const validateModelName = (model, tool = 'claude') => {
@@ -647,7 +680,7 @@ export const validateModelName = (model, tool = 'claude') => {
647
680
  * Validate model name and exit with error if invalid
648
681
  * This is the main entry point for model validation in solve.mjs, hive.mjs, etc.
649
682
  * @param {string} model - The model name to validate
650
- * @param {string} tool - The tool name ('claude', 'opencode', 'codex')
683
+ * @param {string} tool - The tool name ('claude', 'opencode', 'codex', 'agent', 'qwen')
651
684
  * @param {Function} exitFn - Function to call for exiting (default: process.exit)
652
685
  * @returns {Promise<boolean>} True if valid, exits process if invalid
653
686
  */
@@ -682,7 +715,7 @@ export const formatAvailableModelsForHelp = (tool = 'claude') => {
682
715
 
683
716
  /**
684
717
  * Map tool identifier to user-friendly display name.
685
- * @param {string|null} tool - The tool identifier (claude, codex, opencode, agent)
718
+ * @param {string|null} tool - The tool identifier (claude, codex, opencode, agent, qwen)
686
719
  * @returns {string} User-friendly display name
687
720
  */
688
721
  export const getToolDisplayName = tool => {
@@ -696,6 +729,8 @@ export const getToolDisplayName = tool => {
696
729
  return 'OpenCode';
697
730
  case 'agent':
698
731
  return 'Agent CLI';
732
+ case 'qwen':
733
+ return 'Qwen Code';
699
734
  default:
700
735
  return 'AI tool';
701
736
  }
@@ -817,7 +852,7 @@ const doesRequestedMatchActual = (requestedModel, actualModelId, tool) => {
817
852
  *
818
853
  * @param {Object} options - Model info options
819
854
  * @param {string|null} options.requestedModel - The model requested via --model flag
820
- * @param {string|null} options.tool - The tool used (claude, agent, opencode, codex)
855
+ * @param {string|null} options.tool - The tool used (claude, agent, opencode, codex, qwen)
821
856
  * @param {Object|null} options.pricingInfo - Pricing info from tool result
822
857
  * @param {Object|null} options.modelInfo - Pre-fetched model metadata from models.dev
823
858
  * @param {Array<{modelId: string, modelInfo: Object|null}>|null} options.modelsUsed - Actual models used from CLI JSON output
@@ -928,7 +963,7 @@ export const resolveDefaultFallbackModel = (tool, model) => {
928
963
  *
929
964
  * @param {Object} options
930
965
  * @param {string|null} options.requestedModel - The --model flag value
931
- * @param {string|null} options.tool - The tool used (claude, agent, opencode, codex)
966
+ * @param {string|null} options.tool - The tool used (claude, agent, opencode, codex, qwen)
932
967
  * @param {Object|null} options.pricingInfo - Pricing info from tool result
933
968
  * @param {Array<string>|null} options.actualModelIds - Actual model IDs from CLI JSON output
934
969
  * @returns {Promise<string>} Formatted markdown model info section