Skip to content

Commit 3404a74

Browse files
authored
Merge pull request #78 from codebar-ag/feauter-llms
Feature LLMS
2 parents 2cfd0fa + 86e6aec commit 3404a74

34 files changed

Lines changed: 1063 additions & 286 deletions

app/Actions/ViewDataAction.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace App\Actions;
44

55
use App\DTO\ContactDTO;
6+
use App\Enums\AiModelCategoryEnum;
67
use App\Enums\ContactSectionEnum;
8+
use App\Models\AiModel;
79
use App\Models\Configuration;
810
use App\Models\Contact;
911
use App\Models\News;
@@ -62,6 +64,35 @@ public function technologies(string $locale): Collection
6264
});
6365
}
6466

67+
public function aiModelGroups(): Collection
68+
{
69+
return Cache::rememberForever('ai_models_active', function () {
70+
return $this->groupAiModelsByCategory(
71+
AiModel::whereNull('archived_at')->orderBy('order')->get()
72+
);
73+
});
74+
}
75+
76+
public function aiModelArchive(): Collection
77+
{
78+
return Cache::rememberForever('ai_models_archived', function () {
79+
return $this->groupAiModelsByCategory(
80+
AiModel::whereNotNull('archived_at')->with('replacedBy')->orderBy('order')->get()
81+
);
82+
});
83+
}
84+
85+
private function groupAiModelsByCategory(Collection $models): Collection
86+
{
87+
return collect(AiModelCategoryEnum::cases())
88+
->map(fn (AiModelCategoryEnum $category) => [
89+
'category' => $category,
90+
'models' => $models->where('category', $category)->values(),
91+
])
92+
->filter(fn (array $group) => $group['models']->isNotEmpty())
93+
->values();
94+
}
95+
6596
public function openSource(string $locale): Collection
6697
{
6798
$key = Str::slug("open_source_published_{$locale}");

app/Enums/AiModelCategoryEnum.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Enums;
4+
5+
enum AiModelCategoryEnum: string
6+
{
7+
case REASONING_CODING = 'reasoning_coding';
8+
case VISION_DOCUMENTS = 'vision_documents';
9+
case RETRIEVAL_SEARCH = 'retrieval_search';
10+
11+
public function title(): string
12+
{
13+
return __('components.ai_llm.categories.'.$this->value.'.title');
14+
}
15+
16+
public function description(): string
17+
{
18+
return __('components.ai_llm.categories.'.$this->value.'.description');
19+
}
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Ai;
4+
5+
use App\Actions\PageAction;
6+
use App\Http\Controllers\Controller;
7+
use Illuminate\View\View;
8+
9+
class AiIndexController extends Controller
10+
{
11+
public function __invoke(): View
12+
{
13+
return view('app.ai.index')->with([
14+
'page' => (new PageAction(locale: null, routeName: 'ai.index'))->default(),
15+
]);
16+
}
17+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Ai;
4+
5+
use App\Actions\PageAction;
6+
use App\Actions\ViewDataAction;
7+
use App\Http\Controllers\Controller;
8+
use Illuminate\View\View;
9+
10+
class AiLlmIndexController extends Controller
11+
{
12+
public function __invoke(): View
13+
{
14+
$viewData = new ViewDataAction;
15+
16+
return view('app.ai.llm.index')->with([
17+
'page' => (new PageAction(locale: null, routeName: 'ai.llm.index'))->default(),
18+
'groups' => $viewData->aiModelGroups(),
19+
'archive' => $viewData->aiModelArchive(),
20+
]);
21+
}
22+
}

app/Http/Controllers/Sitemap/SitemapController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class SitemapController extends Controller
2828
'media.index',
2929
'legal.imprint.index',
3030
'legal.privacy.index',
31+
'ai.index',
32+
'ai.llm.index',
3133
];
3234

3335
protected const array DEFAULT_LOCALES = [

app/Models/AiModel.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use App\Enums\AiModelCategoryEnum;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
8+
9+
class AiModel extends Model
10+
{
11+
protected $casts = [
12+
'category' => AiModelCategoryEnum::class,
13+
'role' => 'json',
14+
'archived_at' => 'date',
15+
];
16+
17+
public function replacedBy(): BelongsTo
18+
{
19+
return $this->belongsTo(AiModel::class, 'replaced_by_id');
20+
}
21+
22+
public function localizedRole(): ?string
23+
{
24+
return $this->role[substr(app()->getLocale(), 0, 2)] ?? null;
25+
}
26+
27+
public function licenseLabel(): ?string
28+
{
29+
$key = $this->licenseKey();
30+
31+
return $key ? __('components.ai_llm.licenses.'.$key.'.label') : $this->license;
32+
}
33+
34+
public function licenseTooltip(): ?string
35+
{
36+
$key = $this->licenseKey();
37+
38+
return $key ? __('components.ai_llm.licenses.'.$key.'.tooltip') : null;
39+
}
40+
41+
private function licenseKey(): ?string
42+
{
43+
return match ($this->license) {
44+
'MIT' => 'mit',
45+
'Apache-2.0' => 'apache',
46+
'Gemma' => 'gemma',
47+
default => null,
48+
};
49+
}
50+
}

app/Security/Presets/MyCspPreset.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class MyCspPreset implements Preset
1212
{
1313
public function configure(Policy $policy): void
1414
{
15-
$cdnHost = parse_url((string) env('AWS_CDN_ENDPOINT', ''), PHP_URL_HOST);
15+
$cdnHost = parse_url((string) config('filesystems.disks.s3.cdn_endpoint', ''), PHP_URL_HOST);
1616

1717
$scriptSources = array_filter([
1818
Keyword::SELF,

app/Support/CloudinaryUrl.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
class CloudinaryUrl
66
{
7-
private const CLOUDINARY_HOST = 'res.cloudinary.com';
7+
private const string CLOUDINARY_HOST = 'res.cloudinary.com';
88

9-
private const UPLOAD_MARKER = '/image/upload/';
9+
private const string UPLOAD_MARKER = '/image/upload/';
1010

1111
public static function src(string $url, int $width): string
1212
{
@@ -46,8 +46,7 @@ private static function stripExistingTransforms(string $path): string
4646
$segments = explode('/', $path);
4747

4848
if (
49-
isset($segments[0])
50-
&& preg_match('/^[a-z0-9_,.-]+$/', $segments[0])
49+
preg_match('/^[a-z0-9_,.-]+$/', $segments[0])
5150
&& preg_match('/[whcfq]_/', $segments[0])
5251
) {
5352
array_shift($segments);

0 commit comments

Comments
 (0)