@compilr-dev/sdk 0.18.8 → 0.18.10
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/dist/config.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/models/index.d.ts +2 -1
- package/dist/models/index.js +3 -1
- package/dist/models/model-registry.d.ts +18 -0
- package/dist/models/model-registry.js +166 -110
- package/dist/models/model-tiers.d.ts +3 -1
- package/dist/models/model-tiers.js +21 -29
- package/dist/models/ollama-discovery.d.ts +63 -0
- package/dist/models/ollama-discovery.js +172 -0
- package/dist/models/providers.js +34 -24
- package/dist/provider.js +16 -0
- package/package.json +2 -2
package/dist/config.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface CapabilitiesConfig {
|
|
|
49
49
|
/**
|
|
50
50
|
* Supported provider types for auto-detection
|
|
51
51
|
*/
|
|
52
|
-
export type ProviderType = 'claude' | 'openai' | 'gemini' | 'ollama' | 'together' | 'groq' | 'fireworks' | 'perplexity' | 'openrouter' | 'custom';
|
|
52
|
+
export type ProviderType = 'claude' | 'openai' | 'gemini' | 'ollama' | 'ollama-anthropic' | 'together' | 'groq' | 'fireworks' | 'perplexity' | 'openrouter' | 'custom';
|
|
53
53
|
/**
|
|
54
54
|
* Tool configuration for controlling which tools are available
|
|
55
55
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export type { Preset } from './presets/index.js';
|
|
|
45
45
|
export type { AnyTool } from './presets/types.js';
|
|
46
46
|
export { resolveProvider, detectProviderFromEnv, createProviderFromType } from './provider.js';
|
|
47
47
|
export { DEFAULT_MODELS, getContextWindow, DEFAULT_CONTEXT_WINDOW } from './models.js';
|
|
48
|
-
export { type ModelTier, type TierInfo, type ProviderModelMap, MODEL_TIERS, TIER_INFO, isValidTier, type ThinkingFormat, type ModelStatus, type ModelInfo, MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription, getModelForTier, getTierMappings, getTierDisplayName, getShortModelName, getDefaultTierMappings, type ProviderMetadata, type OthersProviderModel, PROVIDER_METADATA, TOGETHER_MODELS, GROQ_MODELS, FIREWORKS_MODELS, PERPLEXITY_MODELS, OPENROUTER_MODELS, getModelsForOthersProvider, getOthersProviders, getProviderMetadata, isOthersProvider, } from './models/index.js';
|
|
48
|
+
export { type ModelTier, type TierInfo, type ProviderModelMap, MODEL_TIERS, TIER_INFO, isValidTier, type ThinkingFormat, type ModelStatus, type ModelInfo, MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, modelSupportsTools, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription, getModelForTier, getTierMappings, getTierDisplayName, getShortModelName, getDefaultTierMappings, type ProviderMetadata, type OthersProviderModel, PROVIDER_METADATA, TOGETHER_MODELS, GROQ_MODELS, FIREWORKS_MODELS, PERPLEXITY_MODELS, OPENROUTER_MODELS, getModelsForOthersProvider, getOthersProviders, getProviderMetadata, isOthersProvider, type OllamaModelInfo, type OllamaModelsResult, OLLAMA_ANTHROPIC_MIN_VERSION, listOllamaModels, getOllamaVersion, isOllamaAnthropicCompatible, clearOllamaModelsCache, formatOllamaModelSize, getOllamaModelDisplayName, getOllamaModelDescription, } from './models/index.js';
|
|
49
49
|
export { assembleTools, deduplicateTools } from './tools.js';
|
|
50
50
|
export { MetaToolsRegistry, createMetaTools, META_TOOLS_SYSTEM_PROMPT_PREFIX, } from './meta-tools/index.js';
|
|
51
51
|
export type { MetaToolStats, MetaTools, FallbackOptions } from './meta-tools/index.js';
|
package/dist/index.js
CHANGED
|
@@ -83,9 +83,9 @@ export { DEFAULT_MODELS, getContextWindow, DEFAULT_CONTEXT_WINDOW } from './mode
|
|
|
83
83
|
// =============================================================================
|
|
84
84
|
// Model Registry, Tiers, Providers (full model system)
|
|
85
85
|
// =============================================================================
|
|
86
|
-
export { MODEL_TIERS, TIER_INFO, isValidTier, MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription,
|
|
86
|
+
export { MODEL_TIERS, TIER_INFO, isValidTier, MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, modelSupportsTools, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription,
|
|
87
87
|
// Model tiers (pure, settings-free)
|
|
88
|
-
getModelForTier, getTierMappings, getTierDisplayName, getShortModelName, getDefaultTierMappings, PROVIDER_METADATA, TOGETHER_MODELS, GROQ_MODELS, FIREWORKS_MODELS, PERPLEXITY_MODELS, OPENROUTER_MODELS, getModelsForOthersProvider, getOthersProviders, getProviderMetadata, isOthersProvider, } from './models/index.js';
|
|
88
|
+
getModelForTier, getTierMappings, getTierDisplayName, getShortModelName, getDefaultTierMappings, PROVIDER_METADATA, TOGETHER_MODELS, GROQ_MODELS, FIREWORKS_MODELS, PERPLEXITY_MODELS, OPENROUTER_MODELS, getModelsForOthersProvider, getOthersProviders, getProviderMetadata, isOthersProvider, OLLAMA_ANTHROPIC_MIN_VERSION, listOllamaModels, getOllamaVersion, isOllamaAnthropicCompatible, clearOllamaModelsCache, formatOllamaModelSize, getOllamaModelDisplayName, getOllamaModelDescription, } from './models/index.js';
|
|
89
89
|
// =============================================================================
|
|
90
90
|
// Tool Assembly
|
|
91
91
|
// =============================================================================
|
package/dist/models/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Models Module — Barrel Export
|
|
3
3
|
*/
|
|
4
4
|
export { type ModelTier, type TierInfo, type ProviderModelMap, MODEL_TIERS, TIER_INFO, isValidTier, } from './types.js';
|
|
5
|
-
export { type ThinkingFormat, type ModelStatus, type ModelInfo, MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription, } from './model-registry.js';
|
|
5
|
+
export { type ThinkingFormat, type ModelStatus, type ModelInfo, MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, modelSupportsTools, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription, } from './model-registry.js';
|
|
6
6
|
export { getModelForTier, getTierMappings, getTierDisplayName, getShortModelName, getDefaultTierMappings, } from './model-tiers.js';
|
|
7
7
|
export { type ProviderMetadata, type OthersProviderModel, PROVIDER_METADATA, TOGETHER_MODELS, GROQ_MODELS, FIREWORKS_MODELS, PERPLEXITY_MODELS, OPENROUTER_MODELS, getModelsForOthersProvider, getOthersProviders, getProviderMetadata, isOthersProvider, } from './providers.js';
|
|
8
|
+
export { type OllamaModelInfo, type OllamaModelsResult, OLLAMA_ANTHROPIC_MIN_VERSION, listOllamaModels, getOllamaVersion, isOllamaAnthropicCompatible, clearOllamaModelsCache, formatOllamaModelSize, getOllamaModelDisplayName, getOllamaModelDescription, } from './ollama-discovery.js';
|
package/dist/models/index.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
// Types & constants
|
|
5
5
|
export { MODEL_TIERS, TIER_INFO, isValidTier, } from './types.js';
|
|
6
6
|
// Model registry
|
|
7
|
-
export { MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription, } from './model-registry.js';
|
|
7
|
+
export { MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getModelInfo, isKnownModel, isModelSupported, modelSupportsImages, modelSupportsTools, getThinkingFormat, getStatusIndicator, getStatusLabel, getDefaultModelForTier, areThinkingFormatsCompatible, shouldClearHistoryOnModelChange, getModelContextWindow, getModelDisplayName, getModelDescription, } from './model-registry.js';
|
|
8
8
|
// Model tiers (pure, settings-free)
|
|
9
9
|
export { getModelForTier, getTierMappings, getTierDisplayName, getShortModelName, getDefaultTierMappings, } from './model-tiers.js';
|
|
10
10
|
// Provider metadata
|
|
11
11
|
export { PROVIDER_METADATA, TOGETHER_MODELS, GROQ_MODELS, FIREWORKS_MODELS, PERPLEXITY_MODELS, OPENROUTER_MODELS, getModelsForOthersProvider, getOthersProviders, getProviderMetadata, isOthersProvider, } from './providers.js';
|
|
12
|
+
// Ollama discovery (host-agnostic — list installed models + version gate)
|
|
13
|
+
export { OLLAMA_ANTHROPIC_MIN_VERSION, listOllamaModels, getOllamaVersion, isOllamaAnthropicCompatible, clearOllamaModelsCache, formatOllamaModelSize, getOllamaModelDisplayName, getOllamaModelDescription, } from './ollama-discovery.js';
|
|
@@ -34,6 +34,11 @@ export interface ModelInfo {
|
|
|
34
34
|
/** Whether the model accepts image inputs (vision / multimodal). When unset,
|
|
35
35
|
* callers fall back to a provider/id heuristic — see modelSupportsImages(). */
|
|
36
36
|
supportsImages?: boolean;
|
|
37
|
+
/** Whether the model supports native tool / function calling. When unset,
|
|
38
|
+
* callers fall back to a provider/id heuristic — see modelSupportsTools().
|
|
39
|
+
* Set explicitly to `false` for models with weak/absent tool support (e.g.
|
|
40
|
+
* some small local models) so callers can warn or filter. */
|
|
41
|
+
supportsTools?: boolean;
|
|
37
42
|
/** Default tier mapping (fast/balanced/powerful) - undefined if not a default */
|
|
38
43
|
defaultTier?: ModelTier;
|
|
39
44
|
/** Thinking block format this model uses */
|
|
@@ -86,6 +91,19 @@ export declare function isModelSupported(modelId: string): boolean;
|
|
|
86
91
|
* dropping an attached image (canvas-robustness: image on a text-only model).
|
|
87
92
|
*/
|
|
88
93
|
export declare function modelSupportsImages(modelId: string): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Whether a model supports native tool / function calling.
|
|
96
|
+
*
|
|
97
|
+
* Uses the registry's `supportsTools` when set; otherwise infers from the
|
|
98
|
+
* provider/id — all modern Claude, Gemini, and GPT-4o/4.1/5 support tools, as
|
|
99
|
+
* do the hosted OpenAI-compatible aggregators (Together/Groq/Fireworks/
|
|
100
|
+
* OpenRouter). Perplexity Sonar (search) and reasoning-only local models
|
|
101
|
+
* (deepseek-r1, mistral, codellama) do not. Defaults to TRUE for anything
|
|
102
|
+
* unrecognized — the wired providers all send the tools param, so a false
|
|
103
|
+
* negative would needlessly disable tools; genuinely tool-incapable models are
|
|
104
|
+
* marked `supportsTools: false` explicitly in the registry.
|
|
105
|
+
*/
|
|
106
|
+
export declare function modelSupportsTools(modelId: string): boolean;
|
|
89
107
|
/**
|
|
90
108
|
* Get the thinking format for a model.
|
|
91
109
|
* Returns 'none' for unknown models (safe default).
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
*/
|
|
18
18
|
export const MODEL_REGISTRY = [
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
|
-
// Claude Models (Anthropic) — Current generation
|
|
20
|
+
// Claude Models (Anthropic) — Current generation
|
|
21
|
+
// Fable 5 / Opus 4.8 / Sonnet 5 / Haiku 4.5. The 4.6+ family is 1M-context
|
|
22
|
+
// native (no beta opt-in). All support text+image input and tool use.
|
|
21
23
|
// ---------------------------------------------------------------------------
|
|
22
24
|
{
|
|
23
25
|
id: 'claude-haiku-4-5-20251001',
|
|
@@ -25,69 +27,84 @@ export const MODEL_REGISTRY = [
|
|
|
25
27
|
description: 'Fast, low cost',
|
|
26
28
|
provider: 'claude',
|
|
27
29
|
supportsImages: true,
|
|
30
|
+
supportsTools: true,
|
|
28
31
|
defaultTier: 'fast',
|
|
29
32
|
thinkingFormat: 'claude',
|
|
30
33
|
status: 'supported',
|
|
31
34
|
contextWindow: 200000,
|
|
32
35
|
},
|
|
33
36
|
{
|
|
34
|
-
id: 'claude-sonnet-
|
|
35
|
-
displayName: 'Sonnet
|
|
37
|
+
id: 'claude-sonnet-5',
|
|
38
|
+
displayName: 'Sonnet 5',
|
|
36
39
|
description: 'Balanced (recommended)',
|
|
37
40
|
provider: 'claude',
|
|
38
41
|
supportsImages: true,
|
|
42
|
+
supportsTools: true,
|
|
39
43
|
defaultTier: 'balanced',
|
|
40
44
|
thinkingFormat: 'claude',
|
|
41
45
|
status: 'supported',
|
|
42
|
-
contextWindow:
|
|
43
|
-
extendedContextWindow: 1000000,
|
|
46
|
+
contextWindow: 1000000,
|
|
44
47
|
},
|
|
45
48
|
{
|
|
46
|
-
id: 'claude-opus-4-
|
|
47
|
-
displayName: 'Opus 4.
|
|
49
|
+
id: 'claude-opus-4-8',
|
|
50
|
+
displayName: 'Opus 4.8',
|
|
48
51
|
description: 'Most capable',
|
|
49
52
|
provider: 'claude',
|
|
50
53
|
supportsImages: true,
|
|
54
|
+
supportsTools: true,
|
|
51
55
|
defaultTier: 'powerful',
|
|
52
56
|
thinkingFormat: 'claude',
|
|
53
57
|
status: 'supported',
|
|
54
|
-
contextWindow:
|
|
55
|
-
|
|
58
|
+
contextWindow: 1000000,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'claude-fable-5',
|
|
62
|
+
displayName: 'Fable 5',
|
|
63
|
+
description: 'Highest capability, long-running agents',
|
|
64
|
+
provider: 'claude',
|
|
65
|
+
supportsImages: true,
|
|
66
|
+
supportsTools: true,
|
|
67
|
+
thinkingFormat: 'claude',
|
|
68
|
+
status: 'supported',
|
|
69
|
+
contextWindow: 1000000,
|
|
70
|
+
notes: 'Flagship: adaptive thinking always on; premium pricing ($10/$50 per MTok)',
|
|
56
71
|
},
|
|
57
72
|
// Legacy Claude models (still supported)
|
|
58
73
|
{
|
|
59
|
-
id: 'claude-
|
|
60
|
-
displayName: '
|
|
74
|
+
id: 'claude-opus-4-7',
|
|
75
|
+
displayName: 'Opus 4.7',
|
|
61
76
|
description: 'Previous generation',
|
|
62
77
|
provider: 'claude',
|
|
63
78
|
supportsImages: true,
|
|
79
|
+
supportsTools: true,
|
|
64
80
|
thinkingFormat: 'claude',
|
|
65
81
|
status: 'supported',
|
|
66
|
-
contextWindow:
|
|
67
|
-
notes: 'Legacy — consider upgrading to
|
|
82
|
+
contextWindow: 1000000,
|
|
83
|
+
notes: 'Legacy — consider upgrading to Opus 4.8',
|
|
68
84
|
},
|
|
69
85
|
{
|
|
70
|
-
id: 'claude-opus-4-
|
|
71
|
-
displayName: 'Opus 4.
|
|
86
|
+
id: 'claude-opus-4-6',
|
|
87
|
+
displayName: 'Opus 4.6',
|
|
72
88
|
description: 'Previous generation',
|
|
73
89
|
provider: 'claude',
|
|
74
90
|
supportsImages: true,
|
|
91
|
+
supportsTools: true,
|
|
75
92
|
thinkingFormat: 'claude',
|
|
76
93
|
status: 'supported',
|
|
77
|
-
contextWindow:
|
|
78
|
-
notes: 'Legacy — consider upgrading to Opus 4.
|
|
94
|
+
contextWindow: 1000000,
|
|
95
|
+
notes: 'Legacy — consider upgrading to Opus 4.8',
|
|
79
96
|
},
|
|
80
97
|
{
|
|
81
|
-
id: 'claude-sonnet-4-
|
|
82
|
-
displayName: 'Sonnet 4',
|
|
98
|
+
id: 'claude-sonnet-4-6',
|
|
99
|
+
displayName: 'Sonnet 4.6',
|
|
83
100
|
description: 'Previous generation',
|
|
84
101
|
provider: 'claude',
|
|
85
102
|
supportsImages: true,
|
|
103
|
+
supportsTools: true,
|
|
86
104
|
thinkingFormat: 'claude',
|
|
87
105
|
status: 'supported',
|
|
88
|
-
contextWindow:
|
|
89
|
-
|
|
90
|
-
notes: 'Legacy',
|
|
106
|
+
contextWindow: 1000000,
|
|
107
|
+
notes: 'Legacy — consider upgrading to Sonnet 5',
|
|
91
108
|
},
|
|
92
109
|
// ---------------------------------------------------------------------------
|
|
93
110
|
// Gemini Models (Google)
|
|
@@ -163,12 +180,26 @@ export const MODEL_REGISTRY = [
|
|
|
163
180
|
// ---------------------------------------------------------------------------
|
|
164
181
|
// OpenAI Models
|
|
165
182
|
// ---------------------------------------------------------------------------
|
|
183
|
+
{
|
|
184
|
+
id: 'gpt-5.2-2025-12-11',
|
|
185
|
+
displayName: 'GPT-5.2',
|
|
186
|
+
description: 'Most capable',
|
|
187
|
+
provider: 'openai',
|
|
188
|
+
supportsImages: true,
|
|
189
|
+
supportsTools: true,
|
|
190
|
+
defaultTier: 'powerful',
|
|
191
|
+
thinkingFormat: 'none',
|
|
192
|
+
status: 'supported',
|
|
193
|
+
contextWindow: 400000,
|
|
194
|
+
notes: 'Latest generation',
|
|
195
|
+
},
|
|
166
196
|
{
|
|
167
197
|
id: 'gpt-4o',
|
|
168
198
|
displayName: 'GPT-4o',
|
|
169
199
|
description: 'Balanced (recommended)',
|
|
170
200
|
provider: 'openai',
|
|
171
201
|
supportsImages: true,
|
|
202
|
+
supportsTools: true,
|
|
172
203
|
defaultTier: 'balanced',
|
|
173
204
|
thinkingFormat: 'none',
|
|
174
205
|
status: 'supported',
|
|
@@ -180,151 +211,139 @@ export const MODEL_REGISTRY = [
|
|
|
180
211
|
description: 'Fast, low cost',
|
|
181
212
|
provider: 'openai',
|
|
182
213
|
supportsImages: true,
|
|
214
|
+
supportsTools: true,
|
|
183
215
|
defaultTier: 'fast',
|
|
184
216
|
thinkingFormat: 'none',
|
|
185
217
|
status: 'supported',
|
|
186
218
|
contextWindow: 128000,
|
|
187
219
|
},
|
|
188
220
|
{
|
|
189
|
-
id: 'gpt-
|
|
190
|
-
displayName: 'GPT-
|
|
191
|
-
description: '
|
|
221
|
+
id: 'gpt-5-mini-2025-08-07',
|
|
222
|
+
displayName: 'GPT-5 Mini',
|
|
223
|
+
description: 'Balanced, latest generation',
|
|
192
224
|
provider: 'openai',
|
|
193
225
|
supportsImages: true,
|
|
194
|
-
|
|
226
|
+
supportsTools: true,
|
|
195
227
|
thinkingFormat: 'none',
|
|
196
228
|
status: 'supported',
|
|
197
|
-
contextWindow:
|
|
229
|
+
contextWindow: 400000,
|
|
198
230
|
},
|
|
199
|
-
// GPT-5 models (if available)
|
|
200
231
|
{
|
|
201
232
|
id: 'gpt-5-nano-2025-08-07',
|
|
202
233
|
displayName: 'GPT-5 Nano',
|
|
203
|
-
description: 'Fast,
|
|
204
|
-
provider: 'openai',
|
|
205
|
-
supportsImages: true,
|
|
206
|
-
thinkingFormat: 'none',
|
|
207
|
-
status: 'experimental',
|
|
208
|
-
contextWindow: 128000,
|
|
209
|
-
notes: 'Latest generation',
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
id: 'gpt-5-mini-2025-08-07',
|
|
213
|
-
displayName: 'GPT-5 Mini',
|
|
214
|
-
description: 'Balanced, experimental',
|
|
215
|
-
provider: 'openai',
|
|
216
|
-
supportsImages: true,
|
|
217
|
-
thinkingFormat: 'none',
|
|
218
|
-
status: 'experimental',
|
|
219
|
-
contextWindow: 128000,
|
|
220
|
-
notes: 'Latest generation',
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
id: 'gpt-5.2-2025-12-11',
|
|
224
|
-
displayName: 'GPT-5.2',
|
|
225
|
-
description: 'Most capable, experimental',
|
|
234
|
+
description: 'Fast, latest generation',
|
|
226
235
|
provider: 'openai',
|
|
227
236
|
supportsImages: true,
|
|
237
|
+
supportsTools: true,
|
|
228
238
|
thinkingFormat: 'none',
|
|
229
|
-
status: '
|
|
230
|
-
contextWindow:
|
|
231
|
-
notes: 'Latest generation',
|
|
239
|
+
status: 'supported',
|
|
240
|
+
contextWindow: 400000,
|
|
232
241
|
},
|
|
233
242
|
// ---------------------------------------------------------------------------
|
|
234
243
|
// Ollama Models (Local)
|
|
235
244
|
// ---------------------------------------------------------------------------
|
|
236
245
|
{
|
|
237
|
-
id: 'llama3.2:
|
|
238
|
-
displayName: 'Llama 3.2
|
|
246
|
+
id: 'llama3.2:3b',
|
|
247
|
+
displayName: 'Llama 3.2 3B',
|
|
239
248
|
description: 'Fast, small',
|
|
240
249
|
provider: 'ollama',
|
|
250
|
+
supportsTools: true,
|
|
241
251
|
defaultTier: 'fast',
|
|
242
252
|
thinkingFormat: 'none',
|
|
243
253
|
status: 'supported',
|
|
244
|
-
notes: 'Requires: ollama pull llama3.2:
|
|
254
|
+
notes: 'Requires: ollama pull llama3.2:3b',
|
|
245
255
|
},
|
|
246
256
|
{
|
|
247
|
-
id: '
|
|
248
|
-
displayName: '
|
|
249
|
-
description: '
|
|
257
|
+
id: 'qwen2.5:7b',
|
|
258
|
+
displayName: 'Qwen 2.5 7B',
|
|
259
|
+
description: 'Balanced, multilingual',
|
|
250
260
|
provider: 'ollama',
|
|
251
|
-
|
|
261
|
+
supportsTools: true,
|
|
262
|
+
defaultTier: 'balanced',
|
|
252
263
|
thinkingFormat: 'none',
|
|
253
264
|
status: 'supported',
|
|
254
|
-
notes: 'Requires: ollama pull
|
|
265
|
+
notes: 'Tool-capable. Requires: ollama pull qwen2.5:7b',
|
|
255
266
|
},
|
|
256
267
|
{
|
|
257
|
-
id: '
|
|
258
|
-
displayName: '
|
|
259
|
-
description: '
|
|
268
|
+
id: 'llama3.3:70b',
|
|
269
|
+
displayName: 'Llama 3.3 70B',
|
|
270
|
+
description: 'Most capable',
|
|
260
271
|
provider: 'ollama',
|
|
261
|
-
|
|
272
|
+
supportsTools: true,
|
|
273
|
+
defaultTier: 'powerful',
|
|
262
274
|
thinkingFormat: 'none',
|
|
263
275
|
status: 'supported',
|
|
264
|
-
notes: 'Requires: ollama pull
|
|
276
|
+
notes: 'Requires: ollama pull llama3.3:70b',
|
|
265
277
|
},
|
|
266
278
|
{
|
|
267
|
-
id: '
|
|
268
|
-
displayName: '
|
|
269
|
-
description: 'Strong
|
|
279
|
+
id: 'qwen2.5:32b',
|
|
280
|
+
displayName: 'Qwen 2.5 32B',
|
|
281
|
+
description: 'Strong multilingual',
|
|
270
282
|
provider: 'ollama',
|
|
283
|
+
supportsTools: true,
|
|
271
284
|
thinkingFormat: 'none',
|
|
272
285
|
status: 'supported',
|
|
273
|
-
notes: 'Requires: ollama pull
|
|
286
|
+
notes: 'Requires: ollama pull qwen2.5:32b',
|
|
274
287
|
},
|
|
275
288
|
{
|
|
276
|
-
id: '
|
|
277
|
-
displayName: '
|
|
278
|
-
description: '
|
|
289
|
+
id: 'deepseek-r1:14b',
|
|
290
|
+
displayName: 'DeepSeek R1 14B',
|
|
291
|
+
description: 'Reasoning (no tools)',
|
|
279
292
|
provider: 'ollama',
|
|
293
|
+
supportsTools: false,
|
|
280
294
|
thinkingFormat: 'none',
|
|
281
295
|
status: 'supported',
|
|
282
|
-
notes: 'Requires: ollama pull
|
|
296
|
+
notes: 'Reasoning model — limited/no function calling. Requires: ollama pull deepseek-r1:14b',
|
|
283
297
|
},
|
|
284
298
|
{
|
|
285
|
-
id: '
|
|
286
|
-
displayName: '
|
|
287
|
-
description: 'Strong
|
|
299
|
+
id: 'deepseek-r1:32b',
|
|
300
|
+
displayName: 'DeepSeek R1 32B',
|
|
301
|
+
description: 'Strong reasoning (no tools)',
|
|
288
302
|
provider: 'ollama',
|
|
303
|
+
supportsTools: false,
|
|
289
304
|
thinkingFormat: 'none',
|
|
290
305
|
status: 'supported',
|
|
291
|
-
notes: 'Requires: ollama pull
|
|
306
|
+
notes: 'Reasoning model — limited/no function calling. Requires: ollama pull deepseek-r1:32b',
|
|
292
307
|
},
|
|
293
308
|
{
|
|
294
309
|
id: 'mistral:7b',
|
|
295
310
|
displayName: 'Mistral 7B',
|
|
296
|
-
description: 'Fast, efficient',
|
|
311
|
+
description: 'Fast, efficient (no tools)',
|
|
297
312
|
provider: 'ollama',
|
|
313
|
+
supportsTools: false,
|
|
298
314
|
thinkingFormat: 'none',
|
|
299
315
|
status: 'supported',
|
|
300
|
-
notes: 'Requires: ollama pull mistral:7b',
|
|
316
|
+
notes: 'Weak/no native tool calling. Requires: ollama pull mistral:7b',
|
|
301
317
|
},
|
|
302
318
|
{
|
|
303
319
|
id: 'codellama:13b',
|
|
304
320
|
displayName: 'Code Llama 13B',
|
|
305
|
-
description: 'Code-focused',
|
|
321
|
+
description: 'Code-focused (no tools)',
|
|
306
322
|
provider: 'ollama',
|
|
323
|
+
supportsTools: false,
|
|
307
324
|
thinkingFormat: 'none',
|
|
308
325
|
status: 'supported',
|
|
309
|
-
notes: '
|
|
326
|
+
notes: 'No native tool calling. Requires: ollama pull codellama:13b',
|
|
310
327
|
},
|
|
311
328
|
// ---------------------------------------------------------------------------
|
|
312
329
|
// Together AI Models (OpenAI-compatible)
|
|
313
330
|
// ---------------------------------------------------------------------------
|
|
314
331
|
{
|
|
315
|
-
id: 'meta-llama/Llama-3.
|
|
316
|
-
displayName: 'Llama 3.
|
|
332
|
+
id: 'meta-llama/Llama-3.1-8B-Instruct-Turbo',
|
|
333
|
+
displayName: 'Llama 3.1 8B Instruct',
|
|
317
334
|
description: 'Fast, low cost',
|
|
318
335
|
provider: 'together',
|
|
336
|
+
supportsTools: true,
|
|
319
337
|
defaultTier: 'fast',
|
|
320
338
|
thinkingFormat: 'none',
|
|
321
339
|
status: 'supported',
|
|
322
340
|
},
|
|
323
341
|
{
|
|
324
|
-
id: 'meta-llama/Llama-3.
|
|
325
|
-
displayName: 'Llama 3.
|
|
342
|
+
id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo',
|
|
343
|
+
displayName: 'Llama 3.3 70B Instruct',
|
|
326
344
|
description: 'Balanced',
|
|
327
345
|
provider: 'together',
|
|
346
|
+
supportsTools: true,
|
|
328
347
|
defaultTier: 'balanced',
|
|
329
348
|
thinkingFormat: 'none',
|
|
330
349
|
status: 'supported',
|
|
@@ -334,6 +353,7 @@ export const MODEL_REGISTRY = [
|
|
|
334
353
|
displayName: 'DeepSeek R1 70B',
|
|
335
354
|
description: 'Most capable',
|
|
336
355
|
provider: 'together',
|
|
356
|
+
supportsTools: true,
|
|
337
357
|
defaultTier: 'powerful',
|
|
338
358
|
thinkingFormat: 'none',
|
|
339
359
|
status: 'supported',
|
|
@@ -342,19 +362,21 @@ export const MODEL_REGISTRY = [
|
|
|
342
362
|
// Groq Models (OpenAI-compatible, fast inference)
|
|
343
363
|
// ---------------------------------------------------------------------------
|
|
344
364
|
{
|
|
345
|
-
id: 'llama-3.
|
|
346
|
-
displayName: 'Llama 3.
|
|
365
|
+
id: 'llama-3.1-8b-instant',
|
|
366
|
+
displayName: 'Llama 3.1 8B',
|
|
347
367
|
description: 'Fast, low cost',
|
|
348
368
|
provider: 'groq',
|
|
369
|
+
supportsTools: true,
|
|
349
370
|
defaultTier: 'fast',
|
|
350
371
|
thinkingFormat: 'none',
|
|
351
372
|
status: 'supported',
|
|
352
373
|
},
|
|
353
374
|
{
|
|
354
|
-
id: 'llama-3.
|
|
355
|
-
displayName: 'Llama 3.
|
|
375
|
+
id: 'llama-3.3-70b-versatile',
|
|
376
|
+
displayName: 'Llama 3.3 70B',
|
|
356
377
|
description: 'Balanced',
|
|
357
378
|
provider: 'groq',
|
|
379
|
+
supportsTools: true,
|
|
358
380
|
defaultTier: 'balanced',
|
|
359
381
|
thinkingFormat: 'none',
|
|
360
382
|
status: 'supported',
|
|
@@ -364,6 +386,7 @@ export const MODEL_REGISTRY = [
|
|
|
364
386
|
displayName: 'DeepSeek R1 70B',
|
|
365
387
|
description: 'Most capable',
|
|
366
388
|
provider: 'groq',
|
|
389
|
+
supportsTools: true,
|
|
367
390
|
defaultTier: 'powerful',
|
|
368
391
|
thinkingFormat: 'none',
|
|
369
392
|
status: 'supported',
|
|
@@ -372,19 +395,21 @@ export const MODEL_REGISTRY = [
|
|
|
372
395
|
// Fireworks AI Models (OpenAI-compatible)
|
|
373
396
|
// ---------------------------------------------------------------------------
|
|
374
397
|
{
|
|
375
|
-
id: 'accounts/fireworks/models/llama-
|
|
376
|
-
displayName: 'Llama 3.
|
|
398
|
+
id: 'accounts/fireworks/models/llama-v3p1-8b-instruct',
|
|
399
|
+
displayName: 'Llama 3.1 8B',
|
|
377
400
|
description: 'Fast, low cost',
|
|
378
401
|
provider: 'fireworks',
|
|
402
|
+
supportsTools: true,
|
|
379
403
|
defaultTier: 'fast',
|
|
380
404
|
thinkingFormat: 'none',
|
|
381
405
|
status: 'supported',
|
|
382
406
|
},
|
|
383
407
|
{
|
|
384
|
-
id: 'accounts/fireworks/models/llama-
|
|
385
|
-
displayName: 'Llama 3.
|
|
408
|
+
id: 'accounts/fireworks/models/llama-v3p3-70b-instruct',
|
|
409
|
+
displayName: 'Llama 3.3 70B',
|
|
386
410
|
description: 'Balanced',
|
|
387
411
|
provider: 'fireworks',
|
|
412
|
+
supportsTools: true,
|
|
388
413
|
defaultTier: 'balanced',
|
|
389
414
|
thinkingFormat: 'none',
|
|
390
415
|
status: 'supported',
|
|
@@ -394,6 +419,7 @@ export const MODEL_REGISTRY = [
|
|
|
394
419
|
displayName: 'DeepSeek R1',
|
|
395
420
|
description: 'Most capable',
|
|
396
421
|
provider: 'fireworks',
|
|
422
|
+
supportsTools: true,
|
|
397
423
|
defaultTier: 'powerful',
|
|
398
424
|
thinkingFormat: 'none',
|
|
399
425
|
status: 'supported',
|
|
@@ -402,61 +428,67 @@ export const MODEL_REGISTRY = [
|
|
|
402
428
|
// Perplexity Models (Search-augmented AI)
|
|
403
429
|
// ---------------------------------------------------------------------------
|
|
404
430
|
{
|
|
405
|
-
id: '
|
|
406
|
-
displayName: 'Sonar
|
|
431
|
+
id: 'sonar',
|
|
432
|
+
displayName: 'Sonar',
|
|
407
433
|
description: 'Fast, low cost',
|
|
408
434
|
provider: 'perplexity',
|
|
435
|
+
supportsTools: false,
|
|
409
436
|
defaultTier: 'fast',
|
|
410
437
|
thinkingFormat: 'none',
|
|
411
438
|
status: 'supported',
|
|
412
|
-
notes: '
|
|
439
|
+
notes: 'Real-time web search; no function calling',
|
|
413
440
|
},
|
|
414
441
|
{
|
|
415
|
-
id: '
|
|
416
|
-
displayName: 'Sonar
|
|
442
|
+
id: 'sonar-pro',
|
|
443
|
+
displayName: 'Sonar Pro',
|
|
417
444
|
description: 'Balanced',
|
|
418
445
|
provider: 'perplexity',
|
|
446
|
+
supportsTools: false,
|
|
419
447
|
defaultTier: 'balanced',
|
|
420
448
|
thinkingFormat: 'none',
|
|
421
449
|
status: 'supported',
|
|
422
|
-
notes: '
|
|
450
|
+
notes: 'Real-time web search; no function calling',
|
|
423
451
|
},
|
|
424
452
|
{
|
|
425
|
-
id: '
|
|
426
|
-
displayName: 'Sonar
|
|
453
|
+
id: 'sonar-reasoning-pro',
|
|
454
|
+
displayName: 'Sonar Reasoning Pro',
|
|
427
455
|
description: 'Most capable',
|
|
428
456
|
provider: 'perplexity',
|
|
457
|
+
supportsTools: false,
|
|
429
458
|
defaultTier: 'powerful',
|
|
430
459
|
thinkingFormat: 'none',
|
|
431
460
|
status: 'supported',
|
|
432
|
-
notes: '
|
|
461
|
+
notes: 'Real-time web search + reasoning; no function calling',
|
|
433
462
|
},
|
|
434
463
|
// ---------------------------------------------------------------------------
|
|
435
464
|
// OpenRouter Models (Aggregator - access many providers)
|
|
436
465
|
// ---------------------------------------------------------------------------
|
|
437
466
|
{
|
|
438
|
-
id: 'meta-llama/llama-3.
|
|
439
|
-
displayName: 'Llama 3.
|
|
467
|
+
id: 'meta-llama/llama-3.1-8b-instruct',
|
|
468
|
+
displayName: 'Llama 3.1 8B',
|
|
440
469
|
description: 'Fast, low cost',
|
|
441
470
|
provider: 'openrouter',
|
|
471
|
+
supportsTools: true,
|
|
442
472
|
defaultTier: 'fast',
|
|
443
473
|
thinkingFormat: 'none',
|
|
444
474
|
status: 'supported',
|
|
445
475
|
},
|
|
446
476
|
{
|
|
447
|
-
id: 'anthropic/claude-sonnet-
|
|
448
|
-
displayName: 'Claude Sonnet
|
|
477
|
+
id: 'anthropic/claude-sonnet-5',
|
|
478
|
+
displayName: 'Claude Sonnet 5',
|
|
449
479
|
description: 'Balanced (via OpenRouter)',
|
|
450
480
|
provider: 'openrouter',
|
|
481
|
+
supportsTools: true,
|
|
451
482
|
defaultTier: 'balanced',
|
|
452
483
|
thinkingFormat: 'none',
|
|
453
484
|
status: 'supported',
|
|
454
485
|
},
|
|
455
486
|
{
|
|
456
|
-
id: 'anthropic/claude-opus-4-
|
|
457
|
-
displayName: 'Claude Opus 4.
|
|
487
|
+
id: 'anthropic/claude-opus-4-8',
|
|
488
|
+
displayName: 'Claude Opus 4.8',
|
|
458
489
|
description: 'Most capable (via OpenRouter)',
|
|
459
490
|
provider: 'openrouter',
|
|
491
|
+
supportsTools: true,
|
|
460
492
|
defaultTier: 'powerful',
|
|
461
493
|
thinkingFormat: 'none',
|
|
462
494
|
status: 'supported',
|
|
@@ -538,6 +570,29 @@ export function modelSupportsImages(modelId) {
|
|
|
538
570
|
return true;
|
|
539
571
|
return false;
|
|
540
572
|
}
|
|
573
|
+
/**
|
|
574
|
+
* Whether a model supports native tool / function calling.
|
|
575
|
+
*
|
|
576
|
+
* Uses the registry's `supportsTools` when set; otherwise infers from the
|
|
577
|
+
* provider/id — all modern Claude, Gemini, and GPT-4o/4.1/5 support tools, as
|
|
578
|
+
* do the hosted OpenAI-compatible aggregators (Together/Groq/Fireworks/
|
|
579
|
+
* OpenRouter). Perplexity Sonar (search) and reasoning-only local models
|
|
580
|
+
* (deepseek-r1, mistral, codellama) do not. Defaults to TRUE for anything
|
|
581
|
+
* unrecognized — the wired providers all send the tools param, so a false
|
|
582
|
+
* negative would needlessly disable tools; genuinely tool-incapable models are
|
|
583
|
+
* marked `supportsTools: false` explicitly in the registry.
|
|
584
|
+
*/
|
|
585
|
+
export function modelSupportsTools(modelId) {
|
|
586
|
+
const info = getModelInfo(modelId);
|
|
587
|
+
if (info?.supportsTools !== undefined)
|
|
588
|
+
return info.supportsTools;
|
|
589
|
+
const id = modelId.toLowerCase();
|
|
590
|
+
if (id.includes('sonar'))
|
|
591
|
+
return false;
|
|
592
|
+
if (/deepseek-r1|mistral|codellama/.test(id))
|
|
593
|
+
return false;
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
541
596
|
/**
|
|
542
597
|
* Get the thinking format for a model.
|
|
543
598
|
* Returns 'none' for unknown models (safe default).
|
|
@@ -629,6 +684,7 @@ function getProviderContextLimitFallback(provider) {
|
|
|
629
684
|
case 'openai':
|
|
630
685
|
return 128000;
|
|
631
686
|
case 'ollama':
|
|
687
|
+
case 'ollama-anthropic':
|
|
632
688
|
return 32000;
|
|
633
689
|
case 'together':
|
|
634
690
|
return 131072;
|
|
@@ -26,7 +26,9 @@ export declare function getTierMappings(provider: ProviderType, overrides?: Part
|
|
|
26
26
|
export declare function getTierDisplayName(tier: ModelTier): string;
|
|
27
27
|
/**
|
|
28
28
|
* Get short model name from full model ID (for display).
|
|
29
|
-
*
|
|
29
|
+
* Prefers the registry's exact display name (single source of truth);
|
|
30
|
+
* falls back to a version-less heuristic for ids not in the registry.
|
|
31
|
+
* e.g., "claude-opus-4-8" -> "Opus 4.8"; "claude-opus-9" -> "Opus".
|
|
30
32
|
*/
|
|
31
33
|
export declare function getShortModelName(modelId: string): string;
|
|
32
34
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* CLI wraps these with its settings layer.
|
|
7
7
|
*/
|
|
8
8
|
import { TIER_INFO } from './types.js';
|
|
9
|
-
import { getDefaultModelForTier as getDefaultFromRegistry } from './model-registry.js';
|
|
9
|
+
import { getDefaultModelForTier as getDefaultFromRegistry, getModelInfo, } from './model-registry.js';
|
|
10
10
|
/**
|
|
11
11
|
* Get the default model ID for a tier from the registry.
|
|
12
12
|
*/
|
|
@@ -50,41 +50,33 @@ export function getTierDisplayName(tier) {
|
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Get short model name from full model ID (for display).
|
|
53
|
-
*
|
|
53
|
+
* Prefers the registry's exact display name (single source of truth);
|
|
54
|
+
* falls back to a version-less heuristic for ids not in the registry.
|
|
55
|
+
* e.g., "claude-opus-4-8" -> "Opus 4.8"; "claude-opus-9" -> "Opus".
|
|
54
56
|
*/
|
|
55
57
|
export function getShortModelName(modelId) {
|
|
56
|
-
//
|
|
58
|
+
// Registry is authoritative for known models.
|
|
59
|
+
const info = getModelInfo(modelId);
|
|
60
|
+
if (info)
|
|
61
|
+
return info.displayName;
|
|
62
|
+
// Heuristic fallback for unregistered ids (version unknown → omit it).
|
|
57
63
|
if (modelId.includes('claude-haiku'))
|
|
58
|
-
return 'Haiku
|
|
64
|
+
return 'Haiku';
|
|
59
65
|
if (modelId.includes('claude-sonnet'))
|
|
60
|
-
return 'Sonnet
|
|
66
|
+
return 'Sonnet';
|
|
61
67
|
if (modelId.includes('claude-opus'))
|
|
62
|
-
return 'Opus
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return 'GPT-5 Mini';
|
|
68
|
-
if (modelId.includes('gpt-5.2'))
|
|
69
|
-
return 'GPT-5.2';
|
|
70
|
-
if (modelId.includes('gpt-4o-mini'))
|
|
71
|
-
return 'GPT-4o Mini';
|
|
68
|
+
return 'Opus';
|
|
69
|
+
if (modelId.includes('claude-fable'))
|
|
70
|
+
return 'Fable';
|
|
71
|
+
if (modelId.includes('gpt-5'))
|
|
72
|
+
return 'GPT-5';
|
|
72
73
|
if (modelId.includes('gpt-4o'))
|
|
73
74
|
return 'GPT-4o';
|
|
74
|
-
if (modelId.includes('
|
|
75
|
-
return '
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (modelId.includes('gemini-2.5-flash'))
|
|
80
|
-
return 'Flash 2.5';
|
|
81
|
-
if (modelId.includes('gemini-2.5-pro'))
|
|
82
|
-
return 'Pro 2.5';
|
|
83
|
-
if (modelId.includes('gemini-3-flash'))
|
|
84
|
-
return 'Flash 3';
|
|
85
|
-
if (modelId.includes('gemini-3-pro'))
|
|
86
|
-
return 'Pro 3';
|
|
87
|
-
// Ollama - just return the model ID
|
|
75
|
+
if (modelId.includes('gemini-3'))
|
|
76
|
+
return 'Gemini 3';
|
|
77
|
+
if (modelId.includes('gemini-2.5'))
|
|
78
|
+
return 'Gemini 2.5';
|
|
79
|
+
// Unknown — return the raw model ID.
|
|
88
80
|
return modelId;
|
|
89
81
|
}
|
|
90
82
|
/**
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama discovery — host-agnostic helpers to list locally-pulled models and
|
|
3
|
+
* detect the Ollama version. Shared by CLI + Desktop so both surface installed
|
|
4
|
+
* models (closing the Desktop parity gap) for BOTH ollama providers
|
|
5
|
+
* (`ollama` OpenAI-compat and `ollama-anthropic`). Uses Ollama's native
|
|
6
|
+
* `/api/tags` and `/api/version` (same on both providers — same port).
|
|
7
|
+
*
|
|
8
|
+
* The base URL is a parameter (hosts pass their configured value); this module
|
|
9
|
+
* has no settings dependency. Results are cached per base URL for 30s.
|
|
10
|
+
* See ollama-anthropic-provider-spec.md §6.
|
|
11
|
+
*/
|
|
12
|
+
/** Minimum Ollama version that supports the native Anthropic `/v1/messages` endpoint. */
|
|
13
|
+
export declare const OLLAMA_ANTHROPIC_MIN_VERSION = "0.14.0";
|
|
14
|
+
/** Information about an Ollama model as returned by `/api/tags`. */
|
|
15
|
+
export interface OllamaModelInfo {
|
|
16
|
+
/** Model name/tag (e.g., "llama3.3:70b", "ornith:latest") */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Model size in bytes */
|
|
19
|
+
size: number;
|
|
20
|
+
/** When the model was modified/pulled */
|
|
21
|
+
modifiedAt: string;
|
|
22
|
+
/** Model digest (hash) */
|
|
23
|
+
digest: string;
|
|
24
|
+
/** Model details (family, parameter size, quantization) */
|
|
25
|
+
details?: {
|
|
26
|
+
family?: string;
|
|
27
|
+
parameterSize?: string;
|
|
28
|
+
quantizationLevel?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Result of listing Ollama models. */
|
|
32
|
+
export interface OllamaModelsResult {
|
|
33
|
+
success: boolean;
|
|
34
|
+
models: OllamaModelInfo[];
|
|
35
|
+
error?: string;
|
|
36
|
+
/** Whether the Ollama server responded at all */
|
|
37
|
+
ollamaRunning: boolean;
|
|
38
|
+
fetchedAt: number;
|
|
39
|
+
}
|
|
40
|
+
/** Clear the models cache (testing / forced refresh). */
|
|
41
|
+
export declare function clearOllamaModelsCache(): void;
|
|
42
|
+
/**
|
|
43
|
+
* List locally-available Ollama models via `/api/tags`. Cached per base URL for
|
|
44
|
+
* 30s. Returns gracefully (success:false) when Ollama isn't running.
|
|
45
|
+
*/
|
|
46
|
+
export declare function listOllamaModels(baseUrl?: string, forceRefresh?: boolean): Promise<OllamaModelsResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Get the running Ollama server version via `/api/version`, or null if
|
|
49
|
+
* unreachable. Used to gate the `ollama-anthropic` provider.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getOllamaVersion(baseUrl?: string): Promise<string | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the Ollama server supports the native Anthropic `/v1/messages`
|
|
54
|
+
* endpoint (version >= 0.14.0). Returns false if unreachable/unknown — callers
|
|
55
|
+
* should treat that as "offer classic ollama, gate/warn on ollama-anthropic".
|
|
56
|
+
*/
|
|
57
|
+
export declare function isOllamaAnthropicCompatible(baseUrl?: string): Promise<boolean>;
|
|
58
|
+
/** Format a byte size for display (e.g. "4.1 GB"). */
|
|
59
|
+
export declare function formatOllamaModelSize(bytes: number): string;
|
|
60
|
+
/** Friendly display name for a model tag (e.g. "ornith:latest" → "Ornith (latest)"). */
|
|
61
|
+
export declare function getOllamaModelDisplayName(name: string): string;
|
|
62
|
+
/** Short description from model metadata (params · quant · size). */
|
|
63
|
+
export declare function getOllamaModelDescription(model: OllamaModelInfo): string;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama discovery — host-agnostic helpers to list locally-pulled models and
|
|
3
|
+
* detect the Ollama version. Shared by CLI + Desktop so both surface installed
|
|
4
|
+
* models (closing the Desktop parity gap) for BOTH ollama providers
|
|
5
|
+
* (`ollama` OpenAI-compat and `ollama-anthropic`). Uses Ollama's native
|
|
6
|
+
* `/api/tags` and `/api/version` (same on both providers — same port).
|
|
7
|
+
*
|
|
8
|
+
* The base URL is a parameter (hosts pass their configured value); this module
|
|
9
|
+
* has no settings dependency. Results are cached per base URL for 30s.
|
|
10
|
+
* See ollama-anthropic-provider-spec.md §6.
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_BASE_URL = 'http://localhost:11434';
|
|
13
|
+
/** Minimum Ollama version that supports the native Anthropic `/v1/messages` endpoint. */
|
|
14
|
+
export const OLLAMA_ANTHROPIC_MIN_VERSION = '0.14.0';
|
|
15
|
+
const CACHE_DURATION_MS = 30_000;
|
|
16
|
+
const modelsCache = new Map();
|
|
17
|
+
function resolveBaseUrl(baseUrl) {
|
|
18
|
+
return baseUrl ?? process.env.OLLAMA_BASE_URL ?? process.env.OLLAMA_HOST ?? DEFAULT_BASE_URL;
|
|
19
|
+
}
|
|
20
|
+
/** Clear the models cache (testing / forced refresh). */
|
|
21
|
+
export function clearOllamaModelsCache() {
|
|
22
|
+
modelsCache.clear();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* List locally-available Ollama models via `/api/tags`. Cached per base URL for
|
|
26
|
+
* 30s. Returns gracefully (success:false) when Ollama isn't running.
|
|
27
|
+
*/
|
|
28
|
+
export async function listOllamaModels(baseUrl, forceRefresh = false) {
|
|
29
|
+
const host = resolveBaseUrl(baseUrl);
|
|
30
|
+
const cached = modelsCache.get(host);
|
|
31
|
+
if (!forceRefresh && cached && Date.now() - cached.fetchedAt < CACHE_DURATION_MS) {
|
|
32
|
+
return cached;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const response = await fetch(`${host}/api/tags`, {
|
|
36
|
+
method: 'GET',
|
|
37
|
+
signal: AbortSignal.timeout(5000),
|
|
38
|
+
});
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const result = {
|
|
41
|
+
success: false,
|
|
42
|
+
models: [],
|
|
43
|
+
error: `Ollama returned status ${String(response.status)}`,
|
|
44
|
+
ollamaRunning: true,
|
|
45
|
+
fetchedAt: Date.now(),
|
|
46
|
+
};
|
|
47
|
+
modelsCache.set(host, result);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
const data = (await response.json());
|
|
51
|
+
const models = (data.models ?? [])
|
|
52
|
+
.map((m) => ({
|
|
53
|
+
name: m.name,
|
|
54
|
+
size: m.size,
|
|
55
|
+
modifiedAt: m.modified_at,
|
|
56
|
+
digest: m.digest,
|
|
57
|
+
details: m.details
|
|
58
|
+
? {
|
|
59
|
+
family: m.details.family,
|
|
60
|
+
parameterSize: m.details.parameter_size,
|
|
61
|
+
quantizationLevel: m.details.quantization_level,
|
|
62
|
+
}
|
|
63
|
+
: undefined,
|
|
64
|
+
}))
|
|
65
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
66
|
+
const result = {
|
|
67
|
+
success: true,
|
|
68
|
+
models,
|
|
69
|
+
ollamaRunning: true,
|
|
70
|
+
fetchedAt: Date.now(),
|
|
71
|
+
};
|
|
72
|
+
modelsCache.set(host, result);
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
let errorMsg = 'Unknown error';
|
|
77
|
+
const ollamaRunning = false;
|
|
78
|
+
if (error instanceof Error) {
|
|
79
|
+
if (error.name === 'AbortError' || error.message.includes('timeout')) {
|
|
80
|
+
errorMsg = 'Connection timed out';
|
|
81
|
+
}
|
|
82
|
+
else if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) {
|
|
83
|
+
errorMsg = 'Ollama is not running. Start it with: ollama serve';
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
errorMsg = error.message;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const result = {
|
|
90
|
+
success: false,
|
|
91
|
+
models: [],
|
|
92
|
+
error: errorMsg,
|
|
93
|
+
ollamaRunning,
|
|
94
|
+
fetchedAt: Date.now(),
|
|
95
|
+
};
|
|
96
|
+
modelsCache.set(host, result);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the running Ollama server version via `/api/version`, or null if
|
|
102
|
+
* unreachable. Used to gate the `ollama-anthropic` provider.
|
|
103
|
+
*/
|
|
104
|
+
export async function getOllamaVersion(baseUrl) {
|
|
105
|
+
const host = resolveBaseUrl(baseUrl);
|
|
106
|
+
try {
|
|
107
|
+
const response = await fetch(`${host}/api/version`, {
|
|
108
|
+
method: 'GET',
|
|
109
|
+
signal: AbortSignal.timeout(5000),
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok)
|
|
112
|
+
return null;
|
|
113
|
+
const data = (await response.json());
|
|
114
|
+
return data.version ?? null;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Compare dotted numeric versions: -1 / 0 / 1. Non-numeric segments treated as 0. */
|
|
121
|
+
function compareVersions(a, b) {
|
|
122
|
+
const pa = a.split('.').map((n) => parseInt(n, 10) || 0);
|
|
123
|
+
const pb = b.split('.').map((n) => parseInt(n, 10) || 0);
|
|
124
|
+
const len = Math.max(pa.length, pb.length);
|
|
125
|
+
for (let i = 0; i < len; i++) {
|
|
126
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
127
|
+
if (d !== 0)
|
|
128
|
+
return d < 0 ? -1 : 1;
|
|
129
|
+
}
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Whether the Ollama server supports the native Anthropic `/v1/messages`
|
|
134
|
+
* endpoint (version >= 0.14.0). Returns false if unreachable/unknown — callers
|
|
135
|
+
* should treat that as "offer classic ollama, gate/warn on ollama-anthropic".
|
|
136
|
+
*/
|
|
137
|
+
export async function isOllamaAnthropicCompatible(baseUrl) {
|
|
138
|
+
const version = await getOllamaVersion(baseUrl);
|
|
139
|
+
if (!version)
|
|
140
|
+
return false;
|
|
141
|
+
return compareVersions(version, OLLAMA_ANTHROPIC_MIN_VERSION) >= 0;
|
|
142
|
+
}
|
|
143
|
+
// ── Display helpers (shared so hosts format installed models consistently) ──
|
|
144
|
+
/** Format a byte size for display (e.g. "4.1 GB"). */
|
|
145
|
+
export function formatOllamaModelSize(bytes) {
|
|
146
|
+
if (bytes < 1024)
|
|
147
|
+
return `${String(bytes)} B`;
|
|
148
|
+
if (bytes < 1024 * 1024)
|
|
149
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
150
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
151
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
152
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
153
|
+
}
|
|
154
|
+
/** Friendly display name for a model tag (e.g. "ornith:latest" → "Ornith (latest)"). */
|
|
155
|
+
export function getOllamaModelDisplayName(name) {
|
|
156
|
+
const [baseName, tag] = name.split(':');
|
|
157
|
+
const formattedBase = baseName
|
|
158
|
+
.split(/[-_]/)
|
|
159
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
160
|
+
.join(' ');
|
|
161
|
+
return tag ? `${formattedBase} (${tag})` : formattedBase;
|
|
162
|
+
}
|
|
163
|
+
/** Short description from model metadata (params · quant · size). */
|
|
164
|
+
export function getOllamaModelDescription(model) {
|
|
165
|
+
const parts = [];
|
|
166
|
+
if (model.details?.parameterSize)
|
|
167
|
+
parts.push(model.details.parameterSize);
|
|
168
|
+
if (model.details?.quantizationLevel)
|
|
169
|
+
parts.push(model.details.quantizationLevel);
|
|
170
|
+
parts.push(formatOllamaModelSize(model.size));
|
|
171
|
+
return parts.join(' · ');
|
|
172
|
+
}
|
package/dist/models/providers.js
CHANGED
|
@@ -56,6 +56,16 @@ export const PROVIDER_METADATA = {
|
|
|
56
56
|
requiresKey: false,
|
|
57
57
|
category: 'local',
|
|
58
58
|
},
|
|
59
|
+
'ollama-anthropic': {
|
|
60
|
+
type: 'ollama-anthropic',
|
|
61
|
+
displayName: 'Ollama (Claude API)',
|
|
62
|
+
description: "Local models via Ollama's Anthropic endpoint (thinking; needs Ollama ≥ 0.14)",
|
|
63
|
+
endpoint: 'http://localhost:11434',
|
|
64
|
+
envVar: '',
|
|
65
|
+
keyUrl: 'https://ollama.ai',
|
|
66
|
+
requiresKey: false,
|
|
67
|
+
category: 'local',
|
|
68
|
+
},
|
|
59
69
|
// "Others" providers (OpenAI-compatible APIs)
|
|
60
70
|
together: {
|
|
61
71
|
type: 'together',
|
|
@@ -128,15 +138,15 @@ export const PROVIDER_METADATA = {
|
|
|
128
138
|
*/
|
|
129
139
|
export const TOGETHER_MODELS = [
|
|
130
140
|
{
|
|
131
|
-
id: 'meta-llama/Llama-3.
|
|
132
|
-
displayName: 'Llama 3.
|
|
141
|
+
id: 'meta-llama/Llama-3.1-8B-Instruct-Turbo',
|
|
142
|
+
displayName: 'Llama 3.1 8B Instruct',
|
|
133
143
|
description: 'Fast, low cost',
|
|
134
144
|
provider: 'together',
|
|
135
145
|
tier: 'fast',
|
|
136
146
|
},
|
|
137
147
|
{
|
|
138
|
-
id: 'meta-llama/Llama-3.
|
|
139
|
-
displayName: 'Llama 3.
|
|
148
|
+
id: 'meta-llama/Llama-3.3-70B-Instruct-Turbo',
|
|
149
|
+
displayName: 'Llama 3.3 70B Instruct',
|
|
140
150
|
description: 'Balanced',
|
|
141
151
|
provider: 'together',
|
|
142
152
|
tier: 'balanced',
|
|
@@ -154,15 +164,15 @@ export const TOGETHER_MODELS = [
|
|
|
154
164
|
*/
|
|
155
165
|
export const GROQ_MODELS = [
|
|
156
166
|
{
|
|
157
|
-
id: 'llama-3.
|
|
158
|
-
displayName: 'Llama 3.
|
|
167
|
+
id: 'llama-3.1-8b-instant',
|
|
168
|
+
displayName: 'Llama 3.1 8B',
|
|
159
169
|
description: 'Fast, low cost',
|
|
160
170
|
provider: 'groq',
|
|
161
171
|
tier: 'fast',
|
|
162
172
|
},
|
|
163
173
|
{
|
|
164
|
-
id: 'llama-3.
|
|
165
|
-
displayName: 'Llama 3.
|
|
174
|
+
id: 'llama-3.3-70b-versatile',
|
|
175
|
+
displayName: 'Llama 3.3 70B',
|
|
166
176
|
description: 'Balanced',
|
|
167
177
|
provider: 'groq',
|
|
168
178
|
tier: 'balanced',
|
|
@@ -180,15 +190,15 @@ export const GROQ_MODELS = [
|
|
|
180
190
|
*/
|
|
181
191
|
export const FIREWORKS_MODELS = [
|
|
182
192
|
{
|
|
183
|
-
id: 'accounts/fireworks/models/llama-
|
|
184
|
-
displayName: 'Llama 3.
|
|
193
|
+
id: 'accounts/fireworks/models/llama-v3p1-8b-instruct',
|
|
194
|
+
displayName: 'Llama 3.1 8B',
|
|
185
195
|
description: 'Fast, low cost',
|
|
186
196
|
provider: 'fireworks',
|
|
187
197
|
tier: 'fast',
|
|
188
198
|
},
|
|
189
199
|
{
|
|
190
|
-
id: 'accounts/fireworks/models/llama-
|
|
191
|
-
displayName: 'Llama 3.
|
|
200
|
+
id: 'accounts/fireworks/models/llama-v3p3-70b-instruct',
|
|
201
|
+
displayName: 'Llama 3.3 70B',
|
|
192
202
|
description: 'Balanced',
|
|
193
203
|
provider: 'fireworks',
|
|
194
204
|
tier: 'balanced',
|
|
@@ -206,22 +216,22 @@ export const FIREWORKS_MODELS = [
|
|
|
206
216
|
*/
|
|
207
217
|
export const PERPLEXITY_MODELS = [
|
|
208
218
|
{
|
|
209
|
-
id: '
|
|
210
|
-
displayName: 'Sonar
|
|
219
|
+
id: 'sonar',
|
|
220
|
+
displayName: 'Sonar',
|
|
211
221
|
description: 'Fast, low cost',
|
|
212
222
|
provider: 'perplexity',
|
|
213
223
|
tier: 'fast',
|
|
214
224
|
},
|
|
215
225
|
{
|
|
216
|
-
id: '
|
|
217
|
-
displayName: 'Sonar
|
|
226
|
+
id: 'sonar-pro',
|
|
227
|
+
displayName: 'Sonar Pro',
|
|
218
228
|
description: 'Balanced',
|
|
219
229
|
provider: 'perplexity',
|
|
220
230
|
tier: 'balanced',
|
|
221
231
|
},
|
|
222
232
|
{
|
|
223
|
-
id: '
|
|
224
|
-
displayName: 'Sonar
|
|
233
|
+
id: 'sonar-reasoning-pro',
|
|
234
|
+
displayName: 'Sonar Reasoning Pro',
|
|
225
235
|
description: 'Most capable',
|
|
226
236
|
provider: 'perplexity',
|
|
227
237
|
tier: 'powerful',
|
|
@@ -232,22 +242,22 @@ export const PERPLEXITY_MODELS = [
|
|
|
232
242
|
*/
|
|
233
243
|
export const OPENROUTER_MODELS = [
|
|
234
244
|
{
|
|
235
|
-
id: 'meta-llama/llama-3.
|
|
236
|
-
displayName: 'Llama 3.
|
|
245
|
+
id: 'meta-llama/llama-3.1-8b-instruct',
|
|
246
|
+
displayName: 'Llama 3.1 8B',
|
|
237
247
|
description: 'Fast, low cost',
|
|
238
248
|
provider: 'openrouter',
|
|
239
249
|
tier: 'fast',
|
|
240
250
|
},
|
|
241
251
|
{
|
|
242
|
-
id: 'anthropic/claude-
|
|
243
|
-
displayName: 'Claude
|
|
252
|
+
id: 'anthropic/claude-sonnet-5',
|
|
253
|
+
displayName: 'Claude Sonnet 5',
|
|
244
254
|
description: 'Balanced (via OpenRouter)',
|
|
245
255
|
provider: 'openrouter',
|
|
246
256
|
tier: 'balanced',
|
|
247
257
|
},
|
|
248
258
|
{
|
|
249
|
-
id: 'anthropic/claude-
|
|
250
|
-
displayName: 'Claude
|
|
259
|
+
id: 'anthropic/claude-opus-4-8',
|
|
260
|
+
displayName: 'Claude Opus 4.8',
|
|
251
261
|
description: 'Most capable (via OpenRouter)',
|
|
252
262
|
provider: 'openrouter',
|
|
253
263
|
tier: 'powerful',
|
package/dist/provider.js
CHANGED
|
@@ -48,6 +48,22 @@ export function createProviderFromType(type, options) {
|
|
|
48
48
|
return createGeminiNativeProvider({ model, apiKey, estimateTokens, maxTokens });
|
|
49
49
|
case 'ollama':
|
|
50
50
|
return createOllamaProvider({ model, baseUrl, estimateTokens, maxTokens });
|
|
51
|
+
case 'ollama-anthropic':
|
|
52
|
+
// Ollama's native Anthropic Messages endpoint (Ollama >= 0.14). Reuses the
|
|
53
|
+
// Claude provider pointed at the Ollama base URL — the Anthropic SDK POSTs
|
|
54
|
+
// to {baseURL}/v1/messages. Anthropic-only features Ollama doesn't support
|
|
55
|
+
// are disabled; the dummy key is accepted-not-validated. Surfaces thinking
|
|
56
|
+
// that the OpenAI-compat `ollama` path drops. See ollama-anthropic spec.
|
|
57
|
+
return createClaudeProvider({
|
|
58
|
+
model,
|
|
59
|
+
apiKey: apiKey || 'ollama',
|
|
60
|
+
baseURL: baseUrl ?? 'http://localhost:11434',
|
|
61
|
+
estimateTokens,
|
|
62
|
+
maxTokens,
|
|
63
|
+
enablePromptCaching: false,
|
|
64
|
+
enableTokenEfficientTools: false,
|
|
65
|
+
enableExtendedContext: false,
|
|
66
|
+
});
|
|
51
67
|
case 'together':
|
|
52
68
|
return createTogetherProvider({ model, apiKey, estimateTokens, maxTokens });
|
|
53
69
|
case 'groq':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@compilr-dev/sdk",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.10",
|
|
4
4
|
"description": "Universal agent runtime for building AI-powered applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"node": ">=20.0.0"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@compilr-dev/agents": "^0.6.
|
|
79
|
+
"@compilr-dev/agents": "^0.6.8",
|
|
80
80
|
"@compilr-dev/logger": "^0.1.0",
|
|
81
81
|
"ajv": "^6.14.0",
|
|
82
82
|
"yaml": "^2.8.4"
|