mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-04-02 14:59:26 +02:00
New defaults: OLLAMA_NO_CLOUD=1 - "Ollama can run in local only mode by disabling Ollama’s cloud features. By turning off Ollama’s cloud features, you will lose the ability to use Ollama’s cloud models and web search." https://ollama.com/blog/web-search https://docs.ollama.com/faq#how-do-i-disable-ollama%E2%80%99s-cloud-features example output: ``` ollama run minimax-m2.7:cloud Error: ollama cloud is disabled: remote model details are unavailable ``` This setting can be safely disabled as you have to click on a link to login to ollama cloud and theres no real way to do that in nomad outside of looking at the nomad_ollama logs. This one can be disabled in settings in case theres a model out there that doesn't play nice. but that doesnt seem necessary so far. OLLAMA_FLASH_ATTENTION=1 - "Flash Attention is a feature of most modern models that can significantly reduce memory usage as the context size grows. " Tested with llama3.2: ``` docker logs nomad_ollama --tail 1000 2>&1 |grep --color -i flash_attn llama_context: flash_attn = enabled ``` And with second_constantine/deepseek-coder-v2 with is based on https://huggingface.co/lmstudio-community/DeepSeek-Coder-V2-Lite-Instruct-GGUF which is a model that specifically calls out that you should disable flash attention, but during testing it seems ollama can do this for you automatically: ``` docker logs nomad_ollama --tail 1000 2>&1 |grep --color -i flash_attn llama_context: flash_attn = disabled ```
125 lines
4.1 KiB
TypeScript
125 lines
4.1 KiB
TypeScript
import KVStore from '#models/kv_store'
|
|
import { BenchmarkService } from '#services/benchmark_service'
|
|
import { MapService } from '#services/map_service'
|
|
import { OllamaService } from '#services/ollama_service'
|
|
import { SystemService } from '#services/system_service'
|
|
import { getSettingSchema, updateSettingSchema } from '#validators/settings'
|
|
import { inject } from '@adonisjs/core'
|
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
|
|
@inject()
|
|
export default class SettingsController {
|
|
constructor(
|
|
private systemService: SystemService,
|
|
private mapService: MapService,
|
|
private benchmarkService: BenchmarkService,
|
|
private ollamaService: OllamaService
|
|
) {}
|
|
|
|
async system({ inertia }: HttpContext) {
|
|
const systemInfo = await this.systemService.getSystemInfo()
|
|
return inertia.render('settings/system', {
|
|
system: {
|
|
info: systemInfo,
|
|
},
|
|
})
|
|
}
|
|
|
|
async apps({ inertia }: HttpContext) {
|
|
const services = await this.systemService.getServices({ installedOnly: false })
|
|
return inertia.render('settings/apps', {
|
|
system: {
|
|
services,
|
|
},
|
|
})
|
|
}
|
|
|
|
async legal({ inertia }: HttpContext) {
|
|
return inertia.render('settings/legal')
|
|
}
|
|
|
|
async support({ inertia }: HttpContext) {
|
|
return inertia.render('settings/support')
|
|
}
|
|
|
|
async maps({ inertia }: HttpContext) {
|
|
const baseAssetsCheck = await this.mapService.ensureBaseAssets()
|
|
const regionFiles = await this.mapService.listRegions()
|
|
return inertia.render('settings/maps', {
|
|
maps: {
|
|
baseAssetsExist: baseAssetsCheck,
|
|
regionFiles: regionFiles.files,
|
|
},
|
|
})
|
|
}
|
|
|
|
async models({ inertia }: HttpContext) {
|
|
const availableModels = await this.ollamaService.getAvailableModels({
|
|
sort: 'pulls',
|
|
recommendedOnly: false,
|
|
query: null,
|
|
limit: 15,
|
|
})
|
|
const installedModels = await this.ollamaService.getModels().catch(() => [])
|
|
const chatSuggestionsEnabled = await KVStore.getValue('chat.suggestionsEnabled')
|
|
const aiAssistantCustomName = await KVStore.getValue('ai.assistantCustomName')
|
|
const remoteOllamaUrl = await KVStore.getValue('ai.remoteOllamaUrl')
|
|
const ollamaFlashAttention = await KVStore.getValue('ai.ollamaFlashAttention')
|
|
return inertia.render('settings/models', {
|
|
models: {
|
|
availableModels: availableModels?.models || [],
|
|
installedModels: installedModels || [],
|
|
settings: {
|
|
chatSuggestionsEnabled: chatSuggestionsEnabled ?? false,
|
|
aiAssistantCustomName: aiAssistantCustomName ?? '',
|
|
remoteOllamaUrl: remoteOllamaUrl ?? '',
|
|
ollamaFlashAttention: ollamaFlashAttention ?? true,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
async update({ inertia }: HttpContext) {
|
|
const updateInfo = await this.systemService.checkLatestVersion()
|
|
return inertia.render('settings/update', {
|
|
system: {
|
|
updateAvailable: updateInfo.updateAvailable,
|
|
latestVersion: updateInfo.latestVersion,
|
|
currentVersion: updateInfo.currentVersion,
|
|
},
|
|
})
|
|
}
|
|
|
|
async zim({ inertia }: HttpContext) {
|
|
return inertia.render('settings/zim/index')
|
|
}
|
|
|
|
async zimRemote({ inertia }: HttpContext) {
|
|
return inertia.render('settings/zim/remote-explorer')
|
|
}
|
|
|
|
async benchmark({ inertia }: HttpContext) {
|
|
const latestResult = await this.benchmarkService.getLatestResult()
|
|
const status = this.benchmarkService.getStatus()
|
|
return inertia.render('settings/benchmark', {
|
|
benchmark: {
|
|
latestResult,
|
|
status: status.status,
|
|
currentBenchmarkId: status.benchmarkId,
|
|
},
|
|
})
|
|
}
|
|
|
|
async getSetting({ request, response }: HttpContext) {
|
|
const { key } = await getSettingSchema.validate({ key: request.qs().key });
|
|
const value = await KVStore.getValue(key);
|
|
return response.status(200).send({ key, value });
|
|
}
|
|
|
|
async updateSetting({ request, response }: HttpContext) {
|
|
const reqData = await request.validateUsing(updateSettingSchema)
|
|
await this.systemService.updateSetting(reqData.key, reqData.value)
|
|
return response.status(200).send({ success: true, message: 'Setting updated successfully' })
|
|
}
|
|
}
|