Files
TicketAssistent/app/Repositories/ArticleRepository.php
your name 9244899f9b feat: Enhance Support Reply Service with tone instructions and article details
- Added tone instruction retrieval to SupportReplyService.
- Improved user feedback when no relevant article is found.
- Included article URL and tone instruction in LLM prompt.
- Updated response format to include source information.
- Enhanced article management UI with search functionality and editing capabilities.
- Introduced a new API endpoint for nearest articles based on vector search.
- Added confidence badge component to display article confidence levels.
- Implemented tests for article searching, editing, and nearest article API.
- Removed obsolete .htaccess file.
2026-05-13 22:25:45 +02:00

54 lines
2.1 KiB
PHP

<?php
namespace App\Repositories;
use App\DTOs\ArticleCandidateDTO;
use App\Models\Article;
use App\Models\ArticleChunk;
use App\Repositories\Contracts\ArticleRepositoryInterface;
class ArticleRepository implements ArticleRepositoryInterface
{
public function findSimilarByEmbedding(array $embedding, int $limit = 5, array $embeddingContext = [], array $filters = []): array
{
$vector = '['.implode(',', array_map(static fn ($value) => (float) $value, $embedding)).']';
$chunkDistances = ArticleChunk::query()
->selectRaw('article_id, MIN(embedding <=> ?::vector) as distance', [$vector])
->whereNotNull('embedding')
->when((bool) ($filters['published_only'] ?? false), function ($query) {
$query->whereHas('article', function ($articleQuery) {
$articleQuery
->where('status', 'published')
->where('is_ai_draft', false);
});
})
->when($embeddingContext !== [], function ($query) use ($embeddingContext) {
$query
->where('embedding_provider_instance_id', $embeddingContext['provider_instance_id'] ?? null)
->where('embedding_model', $embeddingContext['embedding_model'] ?? null);
})
->groupBy('article_id')
->orderByRaw('MIN(embedding <=> ?::vector)', [$vector])
->limit($limit)
->get();
if ($chunkDistances->isEmpty()) {
return [];
}
$distanceByArticleId = $chunkDistances->pluck('distance', 'article_id');
$articleIds = $chunkDistances->pluck('article_id')->all();
$articles = Article::query()
->whereIn('id', $articleIds)
->get()
->sortBy(fn (Article $a) => (float) ($distanceByArticleId[$a->id] ?? 1))
->values();
return $articles
->map(fn (Article $article) => ArticleCandidateDTO::fromArticle($article, (float) ($distanceByArticleId[$article->id] ?? 1)))
->all();
}
}