82 lines
3.6 KiB
Dart
82 lines
3.6 KiB
Dart
import 'dart:io';
|
|
|
|
class AiConstants {
|
|
AiConstants._();
|
|
|
|
// Server ports
|
|
static const int chatServerPort = 8080;
|
|
static const int embeddingServerPort = 8081;
|
|
|
|
// API endpoints
|
|
static String get chatApiUrl =>
|
|
'http://localhost:$chatServerPort/v1/chat/completions';
|
|
static String get embeddingApiUrl =>
|
|
'http://localhost:$embeddingServerPort/v1/embeddings';
|
|
static String chatHealthUrl = 'http://localhost:$chatServerPort/health';
|
|
static String embeddingHealthUrl =
|
|
'http://localhost:$embeddingServerPort/health';
|
|
|
|
// Model files
|
|
static const String qwenModelFile = 'qwen3-4b-instruct-2507-q4_k_m.gguf';
|
|
static const String nomicModelFile = 'nomic-embed-text-v1.5.Q4_K_M.gguf';
|
|
static const String nomicModelName = 'nomic-embed-text-v1.5.Q4_K_M';
|
|
|
|
// llama.cpp binary
|
|
static const String llamaBuild = 'b8130';
|
|
static String get serverBinaryName =>
|
|
Platform.isWindows ? 'llama-server.exe' : 'llama-server';
|
|
|
|
// Model download URLs
|
|
static const String nomicModelUrl =
|
|
'https://huggingface.co/nomic-ai/nomic-embed-text-v1.5-GGUF/resolve/main/nomic-embed-text-v1.5.Q4_K_M.gguf';
|
|
static const String qwenModelUrl =
|
|
'https://huggingface.co/bartowski/Qwen_Qwen3-4B-Instruct-2507-GGUF/resolve/main/Qwen_Qwen3-4B-Instruct-2507-Q4_K_M.gguf';
|
|
|
|
// Human-readable model labels (single source of truth for UI copy)
|
|
static const String chatModelLabel = 'Qwen3 4B Instruct Q4_K_M';
|
|
static const String embeddingModelLabel = 'Nomic Embed Text v1.5 Q4_K_M';
|
|
|
|
// Minimum plausible file sizes — a partially downloaded file is smaller.
|
|
static const int qwenModelMinBytes = 2_000_000_000; // full file ≈ 2.4 GB
|
|
static const int nomicModelMinBytes = 50_000_000; // full file ≈ 84 MB
|
|
static const int serverBinaryMinBytes = 1_000_000;
|
|
|
|
// Server configuration
|
|
static const int qwenContextSize = 8192;
|
|
static const int nomicContextSize = 2048;
|
|
static const int gpuLayerOffload = 99;
|
|
static const double chatTemperature = 0.7;
|
|
static const int chatMaxTokens = 1536;
|
|
|
|
/// How many most-recent messages are sent back to the model as history.
|
|
static const int chatHistoryLimit = 12;
|
|
|
|
/// Nomic v1.5 requires task prefixes for good retrieval quality.
|
|
static const String nomicDocumentPrefix = 'search_document: ';
|
|
static const String nomicQueryPrefix = 'search_query: ';
|
|
|
|
// Timeouts
|
|
static const Duration serverConnectTimeout = Duration(seconds: 30);
|
|
static const Duration serverReceiveTimeout = Duration(minutes: 5);
|
|
static const Duration embeddingConnectTimeout = Duration(seconds: 10);
|
|
static const Duration embeddingReceiveTimeout = Duration(seconds: 60);
|
|
|
|
/// Cold-loading a multi-GB model can take minutes: on the first Vulkan
|
|
/// run llama.cpp additionally compiles GPU pipelines for the device.
|
|
static const Duration serverStartupTimeout = Duration(minutes: 5);
|
|
|
|
/// CPU fallback loads via mmap and needs no pipeline compilation.
|
|
static const Duration serverStartupTimeoutCpu = Duration(minutes: 3);
|
|
static const Duration healthPollInterval = Duration(milliseconds: 750);
|
|
|
|
// System prompt
|
|
static const String baseSystemPrompt =
|
|
'You are the AI coach inside TrainHub, a training hub for ITF Taekwon-Do. '
|
|
'You help with: designing drills and training plans (patterns/tul, '
|
|
'sparring/matsogi, kicks, conditioning), analysing technique, belt '
|
|
'grading preparation, and sports science questions. '
|
|
'Use correct ITF terminology (e.g. dollyo chagi, yop chagi, tul names). '
|
|
'Always answer in the same language the user writes in. '
|
|
'Be concise and practical — coaches read this between rounds.';
|
|
}
|