@archal/cli 0.7.7 → 0.7.9

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.
@@ -384,24 +384,25 @@ export function getModelCapabilities(model) {
384
384
  * @returns {string | null}
385
385
  */
386
386
  export function detectModelFamily(model) {
387
- const info = MODEL_REGISTRY[model];
387
+ const normalized = String(model ?? '').toLowerCase();
388
+ const info = MODEL_REGISTRY[normalized];
388
389
  if (info) return info.family;
389
390
 
390
391
  // Prefix-based heuristic for unregistered models
391
- if (model.startsWith('claude-opus')) return 'claude-opus';
392
- if (model.startsWith('claude-sonnet')) return 'claude-sonnet';
393
- if (model.startsWith('claude-haiku')) return 'claude-haiku';
394
- if (model.startsWith('gpt-4o-mini')) return 'gpt-4o-mini';
395
- if (model.startsWith('gpt-4o')) return 'gpt-4o';
396
- if (model.startsWith('gpt-4.1')) return 'gpt-4.1';
397
- if (model.startsWith('gpt-5')) return 'gpt-5.1';
398
- if (model.startsWith('gpt-4')) return 'gpt-4o'; // assume 4o-class
399
- if (model.startsWith('o1-mini')) return 'o1-mini';
400
- if (model.startsWith('o1')) return 'o1';
401
- if (model.startsWith('o3-mini')) return 'o3-mini';
402
- if (model.startsWith('o4-mini')) return 'o4-mini';
403
- if (model.startsWith('gemini') && model.includes('pro')) return 'gemini-pro';
404
- if (model.startsWith('gemini') && model.includes('flash')) return 'gemini-flash';
392
+ if (normalized.startsWith('claude-opus') || normalized.startsWith('opus-')) return 'claude-opus';
393
+ if (normalized.startsWith('claude-sonnet') || normalized.startsWith('sonnet-')) return 'claude-sonnet';
394
+ if (normalized.startsWith('claude-haiku') || normalized.startsWith('haiku-')) return 'claude-haiku';
395
+ if (normalized.startsWith('gpt-4o-mini')) return 'gpt-4o-mini';
396
+ if (normalized.startsWith('gpt-4o')) return 'gpt-4o';
397
+ if (normalized.startsWith('gpt-4.1')) return 'gpt-4.1';
398
+ if (normalized.startsWith('gpt-5')) return 'gpt-5.1';
399
+ if (normalized.startsWith('gpt-4')) return 'gpt-4o'; // assume 4o-class
400
+ if (normalized.startsWith('o1-mini')) return 'o1-mini';
401
+ if (normalized.startsWith('o1')) return 'o1';
402
+ if (normalized.startsWith('o3-mini')) return 'o3-mini';
403
+ if (normalized.startsWith('o4-mini')) return 'o4-mini';
404
+ if (normalized.startsWith('gemini') && normalized.includes('pro')) return 'gemini-pro';
405
+ if (normalized.startsWith('gemini') && normalized.includes('flash')) return 'gemini-flash';
405
406
 
406
407
  return null;
407
408
  }
@@ -483,12 +484,18 @@ export function isReasoningModel(model) {
483
484
  * @returns {boolean}
484
485
  */
485
486
  export function isThinkingModel(model) {
486
- const info = MODEL_REGISTRY[model];
487
+ const normalized = String(model ?? '').toLowerCase();
488
+ const info = MODEL_REGISTRY[normalized];
487
489
  if (info) return info.capabilities.supportsThinking;
488
490
  // Heuristic for unregistered models — most modern models support thinking
489
- if (model.startsWith('claude-')) return true;
490
- if (model.startsWith('gemini-2.5') || model.startsWith('gemini-3')) return true;
491
- if (model.startsWith('gpt-') || /^o[134]/.test(model)) return true;
491
+ if (
492
+ normalized.startsWith('claude-')
493
+ || normalized.startsWith('sonnet-')
494
+ || normalized.startsWith('haiku-')
495
+ || normalized.startsWith('opus-')
496
+ ) return true;
497
+ if (normalized.startsWith('gemini-2.5') || normalized.startsWith('gemini-3')) return true;
498
+ if (normalized.startsWith('gpt-') || /^o[134]/.test(normalized)) return true;
492
499
  return true; // default to true for unknown models
493
500
  }
494
501
 
@@ -26,11 +26,17 @@ import { getModelConfig, isReasoningModel, isThinkingModel, getModelCapabilities
26
26
  * @returns {'gemini' | 'anthropic' | 'openai'}
27
27
  */
28
28
  export function detectProvider(model) {
29
- if (model.startsWith('gemini-')) return 'gemini';
30
- if (model.startsWith('claude-')) return 'anthropic';
29
+ const normalized = String(model ?? '').toLowerCase();
30
+ if (normalized.startsWith('gemini-')) return 'gemini';
31
31
  if (
32
- model.startsWith('gpt-') ||
33
- /^o[134]/.test(model)
32
+ normalized.startsWith('claude-')
33
+ || normalized.startsWith('sonnet-')
34
+ || normalized.startsWith('haiku-')
35
+ || normalized.startsWith('opus-')
36
+ ) return 'anthropic';
37
+ if (
38
+ normalized.startsWith('gpt-') ||
39
+ /^o[134]/.test(normalized)
34
40
  ) return 'openai';
35
41
  // Default to OpenAI-compatible for unknown models
36
42
  return 'openai';
@@ -140,13 +146,23 @@ function getAnthropicThinkingParam(model) {
140
146
  const budget = parseThinkingBudget();
141
147
  if (budget === null) return null;
142
148
 
143
- // Opus 4.6 only supports adaptive thinking
144
- const isOpus = model.startsWith('claude-opus');
145
- if (budget === 'adaptive' || isOpus) {
149
+ // Only 4.6 series models support adaptive thinking.
150
+ // Older models (claude-sonnet-4-20250514, claude-haiku-4-5-20251001) need
151
+ // { type: "enabled", budget_tokens: N } — "adaptive" returns a 400 error.
152
+ const normalized = String(model ?? '').toLowerCase();
153
+ const supportsAdaptive = normalized.includes('-4-6') || normalized.includes('4-6-');
154
+ const isOpus = normalized.startsWith('claude-opus') || normalized.startsWith('opus-');
155
+
156
+ if (isOpus || (supportsAdaptive && budget === 'adaptive')) {
146
157
  return { type: 'adaptive' };
147
158
  }
148
159
 
149
- // Other Claude models: explicit budget
160
+ if (budget === 'adaptive') {
161
+ // For non-4.6 models with default "adaptive" budget, use a sensible fixed budget
162
+ return { type: 'enabled', budget_tokens: 10000 };
163
+ }
164
+
165
+ // Explicit numeric budget
150
166
  return { type: 'enabled', budget_tokens: budget };
151
167
  }
152
168
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archal/cli",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "Pre-deployment testing for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",