mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-03-28 03:29:25 +01:00
Merge 8af0caaa40 into 44ecf41ca6
This commit is contained in:
commit
cd323dd086
|
|
@ -199,7 +199,7 @@ export class OllamaService {
|
|||
query: null,
|
||||
limit: 15,
|
||||
}
|
||||
): Promise<{ models: NomadOllamaModel[], hasMore: boolean } | null> {
|
||||
): Promise<{ models: NomadOllamaModel[], hasMore: boolean, source: 'api' | 'fallback' } | null> {
|
||||
try {
|
||||
const models = await this.retrieveAndRefreshModels(sort, force)
|
||||
if (!models) {
|
||||
|
|
@ -209,7 +209,8 @@ export class OllamaService {
|
|||
)
|
||||
return {
|
||||
models: FALLBACK_RECOMMENDED_OLLAMA_MODELS,
|
||||
hasMore: false
|
||||
hasMore: false,
|
||||
source: 'fallback',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +218,8 @@ export class OllamaService {
|
|||
const filteredModels = query ? this.fuseSearchModels(models, query) : models
|
||||
return {
|
||||
models: filteredModels.slice(0, limit || 15),
|
||||
hasMore: filteredModels.length > (limit || 15)
|
||||
hasMore: filteredModels.length > (limit || 15),
|
||||
source: 'api',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,13 +239,15 @@ export class OllamaService {
|
|||
const filteredRecommendedModels = this.fuseSearchModels(recommendedModels, query)
|
||||
return {
|
||||
models: filteredRecommendedModels,
|
||||
hasMore: filteredRecommendedModels.length > (limit || 15)
|
||||
hasMore: filteredRecommendedModels.length > (limit || 15),
|
||||
source: 'api',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
models: recommendedModels,
|
||||
hasMore: recommendedModels.length > (limit || 15)
|
||||
hasMore: recommendedModels.length > (limit || 15),
|
||||
source: 'api',
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import env from '#start/env'
|
|||
import KVStore from '#models/kv_store'
|
||||
import { KV_STORE_SCHEMA, KVStoreKey } from '../../types/kv_store.js'
|
||||
import { isNewerVersion } from '../utils/version.js'
|
||||
import { NOMAD_API_DEFAULT_BASE_URL } from '../../constants/misc.js'
|
||||
|
||||
|
||||
@inject()
|
||||
|
|
@ -384,8 +385,9 @@ export class SystemService {
|
|||
|
||||
async subscribeToReleaseNotes(email: string): Promise<{ success: boolean; message: string }> {
|
||||
try {
|
||||
const baseUrl = env.get('NOMAD_API_URL') || NOMAD_API_DEFAULT_BASE_URL
|
||||
const response = await axios.post(
|
||||
'https://api.projectnomad.us/api/v1/lists/release-notes/subscribe',
|
||||
`${baseUrl}/api/v1/lists/release-notes/subscribe`,
|
||||
{ email },
|
||||
{ timeout: 5000 }
|
||||
)
|
||||
|
|
@ -399,13 +401,13 @@ export class SystemService {
|
|||
|
||||
return {
|
||||
success: false,
|
||||
message: `Failed to subscribe: ${response.statusText}`,
|
||||
message: 'Failed to subscribe to release notes. Please try again later.',
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error subscribing to release notes:', error)
|
||||
logger.error({ err: error }, '[SystemService] Error subscribing to release notes')
|
||||
return {
|
||||
success: false,
|
||||
message: `Failed to subscribe: ${error instanceof Error ? error.message : error}`,
|
||||
message: 'Failed to subscribe to release notes. The service may be temporarily unavailable.',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ export const FALLBACK_RECOMMENDED_OLLAMA_MODELS: NomadOllamaModel[] = [
|
|||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'deepseek-r1',
|
||||
description:
|
||||
'DeepSeek-R1 is a family of open reasoning models with performance approaching that of leading models, such as O3 and Gemini 2.5 Pro.',
|
||||
'DeepSeek-R1 is a family of open reasoning models with performance approaching that of leading models.',
|
||||
estimated_pulls: '77.2M',
|
||||
id: '0b566560-68a6-4964-b0d4-beb3ab1ad694',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
|
|
@ -38,7 +38,15 @@ export const FALLBACK_RECOMMENDED_OLLAMA_MODELS: NomadOllamaModel[] = [
|
|||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: true
|
||||
thinking: true,
|
||||
},
|
||||
{
|
||||
name: 'deepseek-r1:8b',
|
||||
size: '4.9 GB',
|
||||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -56,7 +64,267 @@ export const FALLBACK_RECOMMENDED_OLLAMA_MODELS: NomadOllamaModel[] = [
|
|||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false
|
||||
thinking: false,
|
||||
},
|
||||
{
|
||||
name: 'llama3.2:3b',
|
||||
size: '2.0 GB',
|
||||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'mistral',
|
||||
description:
|
||||
'Mistral 7B is a compact yet powerful language model by Mistral AI, great for general-purpose tasks.',
|
||||
estimated_pulls: '26.8M',
|
||||
id: 'a2b3c4d5-e6f7-4890-abcd-ef1234567890',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '6 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'mistral:7b',
|
||||
size: '4.1 GB',
|
||||
context: '32k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'gemma2',
|
||||
description:
|
||||
'Gemma 2 is a family of lightweight, state-of-the-art open models by Google.',
|
||||
estimated_pulls: '18.5M',
|
||||
id: 'b3c4d5e6-f7a8-4901-bcde-f12345678901',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '8 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'gemma2:2b',
|
||||
size: '1.6 GB',
|
||||
context: '8k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
{
|
||||
name: 'gemma2:9b',
|
||||
size: '5.4 GB',
|
||||
context: '8k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'phi3',
|
||||
description:
|
||||
'Phi-3 is a family of small language models developed by Microsoft with strong reasoning capabilities.',
|
||||
estimated_pulls: '12.4M',
|
||||
id: 'c4d5e6f7-a8b9-4012-cdef-123456789012',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '10 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'phi3:mini',
|
||||
size: '2.3 GB',
|
||||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'codellama',
|
||||
description:
|
||||
'Code Llama is a model for generating and discussing code, built on top of Llama 2.',
|
||||
estimated_pulls: '15.2M',
|
||||
id: 'd5e6f7a8-b9c0-4123-defa-234567890123',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '1 year ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'codellama:7b',
|
||||
size: '3.8 GB',
|
||||
context: '16k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'qwen2.5-coder',
|
||||
description:
|
||||
'Qwen2.5-Coder is a series of code-specific large language models by Alibaba Cloud.',
|
||||
estimated_pulls: '9.7M',
|
||||
id: 'e6f7a8b9-c0d1-4234-efab-345678901234',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '4 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'qwen2.5-coder:3b',
|
||||
size: '1.9 GB',
|
||||
context: '32k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
{
|
||||
name: 'qwen2.5-coder:7b',
|
||||
size: '4.7 GB',
|
||||
context: '32k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'tinyllama',
|
||||
description:
|
||||
'TinyLlama is a compact 1.1B language model ideal for resource-constrained environments.',
|
||||
estimated_pulls: '5.3M',
|
||||
id: 'f7a8b9c0-d1e2-4345-fabc-456789012345',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '1 year ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'tinyllama:1.1b',
|
||||
size: '638 MB',
|
||||
context: '2k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'nomic-embed-text',
|
||||
description:
|
||||
'A high-performing open embedding model with a large token context window.',
|
||||
estimated_pulls: '22.1M',
|
||||
id: 'a8b9c0d1-e2f3-4456-abcd-567890123456',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '9 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'nomic-embed-text:latest',
|
||||
size: '274 MB',
|
||||
context: '8k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'qwen2.5',
|
||||
description:
|
||||
'Qwen2.5 is a series of large language models by Alibaba Cloud with strong multilingual support.',
|
||||
estimated_pulls: '14.6M',
|
||||
id: 'b9c0d1e2-f3a4-4567-bcde-678901234567',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '5 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'qwen2.5:3b',
|
||||
size: '1.9 GB',
|
||||
context: '32k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
{
|
||||
name: 'qwen2.5:7b',
|
||||
size: '4.7 GB',
|
||||
context: '32k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'llava',
|
||||
description:
|
||||
'LLaVA is a multimodal model that combines a vision encoder with Vicuna for visual and language understanding.',
|
||||
estimated_pulls: '8.9M',
|
||||
id: 'c0d1e2f3-a4b5-4678-cdef-789012345678',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '1 year ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'llava:7b',
|
||||
size: '4.7 GB',
|
||||
context: '4k',
|
||||
input: 'Text, Images',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'starcoder2',
|
||||
description:
|
||||
'StarCoder2 is a family of code generation models trained on The Stack v2 dataset.',
|
||||
estimated_pulls: '3.8M',
|
||||
id: 'd1e2f3a4-b5c6-4789-defa-890123456789',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '1 year ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'starcoder2:3b',
|
||||
size: '1.7 GB',
|
||||
context: '16k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'dolphin-mistral',
|
||||
description:
|
||||
'Dolphin Mistral is an uncensored, fine-tuned Mistral model focused on helpfulness.',
|
||||
estimated_pulls: '4.2M',
|
||||
id: 'e2f3a4b5-c6d7-4890-efab-901234567890',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '1 year ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'dolphin-mistral:7b',
|
||||
size: '4.1 GB',
|
||||
context: '32k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'phi3.5',
|
||||
description:
|
||||
'Phi-3.5 is an updated small language model by Microsoft with improved multilingual and reasoning capabilities.',
|
||||
estimated_pulls: '6.1M',
|
||||
id: 'f3a4b5c6-d7e8-4901-fabc-012345678901',
|
||||
first_seen: '2026-01-28T23:37:31.000+00:00',
|
||||
model_last_updated: '8 months ago',
|
||||
tags: [
|
||||
{
|
||||
name: 'phi3.5:3.8b',
|
||||
size: '2.2 GB',
|
||||
context: '128k',
|
||||
input: 'Text',
|
||||
cloud: false,
|
||||
thinking: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ class API {
|
|||
const response = await this.client.get<{
|
||||
models: NomadOllamaModel[]
|
||||
hasMore: boolean
|
||||
source?: 'api' | 'fallback'
|
||||
}>('/ollama/models', {
|
||||
params: { sort: 'pulls', ...params },
|
||||
})
|
||||
|
|
|
|||
|
|
@ -131,12 +131,20 @@ export default function ModelsPage(props: {
|
|||
initialData: { models: props.models.availableModels, hasMore: false },
|
||||
})
|
||||
|
||||
const isUsingFallback = availableModelData?.source === 'fallback'
|
||||
|
||||
async function handleForceRefresh() {
|
||||
forceRefreshRef.current = true
|
||||
setIsForceRefreshing(true)
|
||||
await refetch()
|
||||
const result = await refetch()
|
||||
setIsForceRefreshing(false)
|
||||
addNotification({ message: 'Model list refreshed from remote.', type: 'success' })
|
||||
const refreshSource = result.data?.source
|
||||
addNotification({
|
||||
message: refreshSource === 'fallback'
|
||||
? 'Could not reach model service. Showing offline list.'
|
||||
: 'Model list refreshed from remote.',
|
||||
type: refreshSource === 'fallback' ? 'warning' : 'success',
|
||||
})
|
||||
}
|
||||
|
||||
async function handleInstallModel(modelName: string) {
|
||||
|
|
@ -312,6 +320,11 @@ export default function ModelsPage(props: {
|
|||
Refresh Models
|
||||
</StyledButton>
|
||||
</div>
|
||||
{isUsingFallback && (
|
||||
<Alert variant="info">
|
||||
Showing offline model list. Connect to the internet and refresh for the full catalog.
|
||||
</Alert>
|
||||
)}
|
||||
<StyledTable<NomadOllamaModel>
|
||||
className="font-semibold mt-4"
|
||||
rowLines={true}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user