Refactor various services and models for improved type handling and configuration management
This commit is contained in:
@@ -15,21 +15,21 @@ class AppSettingsService
|
||||
'prompt.classifier' => 'You are a support assistant. Select best article and return JSON. Include tool_call only when the selected article explicitly allows that action and all required parameters are present.',
|
||||
'prompt.knowledge_gap' => 'Create a draft knowledge base article suggestion based on the customer question. Use the requested output language passed in the prompt. Return JSON only with keys: title, content.',
|
||||
'prompt.support_reply' => 'Give only direct advice in the requested output language. No greeting, no closing, no thank-you text. Start directly with the solution. Give 3-6 numbered action points and end with a verification step.',
|
||||
'llm.provider' => env('LLM_PROVIDER', 'ollama'),
|
||||
'llm.active_instance_id' => env('LLM_PROVIDER', 'ollama').'_default',
|
||||
'llm.provider' => (string) config('services.llm.provider', 'ollama'),
|
||||
'llm.active_instance_id' => (string) config('services.llm.provider', 'ollama').'_default',
|
||||
'llm.provider_instances' => json_encode($this->defaultProviderInstances()),
|
||||
'llm.timeout' => (string) env('LLM_TIMEOUT', env('OLLAMA_TIMEOUT', 30)),
|
||||
'llm.providers.ollama.base_url' => env('OLLAMA_BASE_URL', 'http://localhost:11434'),
|
||||
'llm.providers.ollama.chat_model' => env('OLLAMA_CHAT_MODEL', 'llama3'),
|
||||
'llm.providers.ollama.embedding_model' => env('OLLAMA_EMBED_MODEL', 'nomic-embed-text'),
|
||||
'llm.providers.lmstudio.base_url' => env('LLM_BASE_URL', 'http://localhost:1234'),
|
||||
'llm.providers.lmstudio.chat_model' => env('LLM_CHAT_MODEL', 'local-model'),
|
||||
'llm.providers.lmstudio.embedding_model' => env('LLM_EMBEDDING_MODEL', 'text-embedding-nomic-embed-text-v1.5@q6_k'),
|
||||
'llm.models.normalization' => env('LLM_CHAT_MODEL', env('OLLAMA_CHAT_MODEL', 'llama3')),
|
||||
'llm.models.classifier' => env('LLM_CHAT_MODEL', env('OLLAMA_CHAT_MODEL', 'llama3')),
|
||||
'llm.models.knowledge_gap' => env('LLM_CHAT_MODEL', env('OLLAMA_CHAT_MODEL', 'llama3')),
|
||||
'llm.models.support_reply' => env('LLM_CHAT_MODEL', env('OLLAMA_CHAT_MODEL', 'llama3')),
|
||||
'llm.models.embedding' => env('LLM_EMBEDDING_MODEL', env('OLLAMA_EMBED_MODEL', 'nomic-embed-text')),
|
||||
'llm.timeout' => (string) config('services.llm.timeout', 30),
|
||||
'llm.providers.ollama.base_url' => (string) config('services.llm.base_url', 'http://localhost:11434'),
|
||||
'llm.providers.ollama.chat_model' => (string) config('services.llm.chat_model', 'llama3'),
|
||||
'llm.providers.ollama.embedding_model' => (string) config('services.llm.embedding_model', 'nomic-embed-text'),
|
||||
'llm.providers.lmstudio.base_url' => (string) config('services.llm.base_url', 'http://localhost:1234'),
|
||||
'llm.providers.lmstudio.chat_model' => (string) config('services.llm.chat_model', 'local-model'),
|
||||
'llm.providers.lmstudio.embedding_model' => (string) config('services.llm.embedding_model', 'text-embedding-nomic-embed-text-v1.5@q6_k'),
|
||||
'llm.models.normalization' => (string) config('services.llm.chat_model', 'llama3'),
|
||||
'llm.models.classifier' => (string) config('services.llm.chat_model', 'llama3'),
|
||||
'llm.models.knowledge_gap' => (string) config('services.llm.chat_model', 'llama3'),
|
||||
'llm.models.support_reply' => (string) config('services.llm.chat_model', 'llama3'),
|
||||
'llm.models.embedding' => (string) config('services.llm.embedding_model', 'nomic-embed-text'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -62,17 +62,17 @@ class AppSettingsService
|
||||
'id' => 'lmstudio_default',
|
||||
'name' => 'LM Studio',
|
||||
'type' => 'lmstudio',
|
||||
'base_url' => env('LLM_BASE_URL', 'http://localhost:1234'),
|
||||
'chat_model' => env('LLM_CHAT_MODEL', 'local-model'),
|
||||
'embedding_model' => env('LLM_EMBEDDING_MODEL', 'text-embedding-nomic-embed-text-v1.5@q6_k'),
|
||||
'base_url' => (string) config('services.llm.base_url', 'http://localhost:1234'),
|
||||
'chat_model' => (string) config('services.llm.chat_model', 'local-model'),
|
||||
'embedding_model' => (string) config('services.llm.embedding_model', 'text-embedding-nomic-embed-text-v1.5@q6_k'),
|
||||
],
|
||||
[
|
||||
'id' => 'ollama_default',
|
||||
'name' => 'Ollama',
|
||||
'type' => 'ollama',
|
||||
'base_url' => env('OLLAMA_BASE_URL', 'http://localhost:11434'),
|
||||
'chat_model' => env('OLLAMA_CHAT_MODEL', 'llama3'),
|
||||
'embedding_model' => env('OLLAMA_EMBED_MODEL', 'nomic-embed-text'),
|
||||
'base_url' => (string) config('services.llm.base_url', 'http://localhost:11434'),
|
||||
'chat_model' => (string) config('services.llm.chat_model', 'llama3'),
|
||||
'embedding_model' => (string) config('services.llm.embedding_model', 'nomic-embed-text'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ class EmbeddingService
|
||||
}
|
||||
|
||||
$embedding = $this->llmClient->embed($text);
|
||||
if (! is_array($embedding) || $embedding === []) {
|
||||
throw new OllamaUnavailableException('LLM embedding response did not include a valid embedding');
|
||||
if ($embedding === []) {
|
||||
throw new OllamaUnavailableException('llm', 'embedding', 'LLM embedding response did not include a valid embedding');
|
||||
}
|
||||
|
||||
EmbeddingCache::query()->updateOrCreate(
|
||||
|
||||
@@ -125,7 +125,7 @@ class HelpdeskImportService
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $dryRun && $parentId !== null) {
|
||||
if (! $dryRun) {
|
||||
$childModel = Category::query()->updateOrCreate(
|
||||
['external_id' => (int) $child['id']],
|
||||
['name' => (string) $child['title'], 'slug' => (string) $child['slug'], 'parent_id' => $parentId]
|
||||
@@ -179,13 +179,15 @@ class HelpdeskImportService
|
||||
|
||||
foreach ($sources as $source) {
|
||||
try {
|
||||
$html = $source['html'] ?? $this->fetch($source['url']);
|
||||
$html = array_key_exists('html', $source)
|
||||
? (string) $source['html']
|
||||
: $this->fetch((string) $source['url']);
|
||||
} catch (\Throwable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
preg_match_all('/https:\/\/www\.internettoday\.nl\/helpdesk\/(\d+)-[a-z0-9\-]+/i', $html, $matches);
|
||||
foreach (($matches[0] ?? []) as $match) {
|
||||
foreach ($matches[0] as $match) {
|
||||
$url = strtolower($match);
|
||||
if (! isset($result[$url])) {
|
||||
$result[$url] = [
|
||||
|
||||
@@ -67,7 +67,7 @@ class LmStudioClient implements LlmClientInterface
|
||||
->throw()
|
||||
->json();
|
||||
} catch (RequestException $e) {
|
||||
$body = (string) ($e->response?->body() ?? '');
|
||||
$body = (string) $e->response->body();
|
||||
$isResponseFormatError = str_contains($body, 'response_format.type')
|
||||
|| str_contains($body, 'json_schema');
|
||||
|
||||
@@ -131,7 +131,7 @@ class LmStudioClient implements LlmClientInterface
|
||||
private function mapException(Throwable $e, string $operation): OllamaUnavailableException
|
||||
{
|
||||
if ($e instanceof RequestException) {
|
||||
$body = $e->response?->body();
|
||||
$body = $e->response->body();
|
||||
$snippet = $body ? mb_substr($body, 0, 280) : null;
|
||||
|
||||
return new OllamaUnavailableException('lmstudio', $operation, $e->getMessage(), $e, $snippet);
|
||||
|
||||
@@ -97,7 +97,7 @@ class OllamaClient implements LlmClientInterface
|
||||
private function mapException(Throwable $e, string $operation): OllamaUnavailableException
|
||||
{
|
||||
if ($e instanceof RequestException) {
|
||||
$body = $e->response?->body();
|
||||
$body = $e->response->body();
|
||||
$snippet = $body ? mb_substr($body, 0, 280) : null;
|
||||
|
||||
return new OllamaUnavailableException('ollama', $operation, $e->getMessage(), $e, $snippet);
|
||||
|
||||
@@ -17,9 +17,11 @@ class QuickReplyResolver
|
||||
$article->load('quickReplies');
|
||||
}
|
||||
|
||||
return $article->quickReplies
|
||||
$quickReply = $article->quickReplies
|
||||
->where('is_active', true)
|
||||
->sortBy('title')
|
||||
->first();
|
||||
|
||||
return $quickReply instanceof QuickReply ? $quickReply : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class SemanticSearchService
|
||||
return $scoreB <=> $scoreA;
|
||||
});
|
||||
|
||||
return array_values(array_slice($unique, 0, $limit));
|
||||
return array_slice($unique, 0, $limit);
|
||||
}
|
||||
|
||||
private function candidateScore(string $text, float $distance, bool $isHowTo): float
|
||||
|
||||
Reference in New Issue
Block a user