@compilr-dev/sdk 0.18.9 → 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 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, 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, } 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
@@ -85,7 +85,7 @@ export { DEFAULT_MODELS, getContextWindow, DEFAULT_CONTEXT_WINDOW } from './mode
85
85
  // =============================================================================
86
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
  // =============================================================================
@@ -5,3 +5,4 @@ export { type ModelTier, type TierInfo, type ProviderModelMap, MODEL_TIERS, TIER
5
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';
@@ -9,3 +9,5 @@ export { MODEL_REGISTRY, getModelsForProvider, getModelsSortedForDisplay, getMod
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';
@@ -684,6 +684,7 @@ function getProviderContextLimitFallback(provider) {
684
684
  case 'openai':
685
685
  return 128000;
686
686
  case 'ollama':
687
+ case 'ollama-anthropic':
687
688
  return 32000;
688
689
  case 'together':
689
690
  return 131072;
@@ -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
+ }
@@ -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',
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.9",
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",