diff --git a/.docker/docker-compose/docker-compose.local.yml b/.docker/docker-compose/docker-compose.local.yml index 63eb8965e..581b318e7 100644 --- a/.docker/docker-compose/docker-compose.local.yml +++ b/.docker/docker-compose/docker-compose.local.yml @@ -46,13 +46,13 @@ services: networks: - network restart: always -# deploy: -# resources: -# reservations: -# devices: -# - driver: nvidia -# count: 1 # alternatively, use `count: all` for all GPUs -# capabilities: [gpu] + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 # alternatively, use `count: all` for all GPUs + capabilities: [gpu] webhook: image: tarampampam/webhook-tester:2 restart: always diff --git a/src/new/src/PSC/Component/AiBundle/Platform/Completions/ModelClient.php b/src/new/src/PSC/Component/AiBundle/Platform/Completions/ModelClient.php index 74a067861..6ba8626c5 100644 --- a/src/new/src/PSC/Component/AiBundle/Platform/Completions/ModelClient.php +++ b/src/new/src/PSC/Component/AiBundle/Platform/Completions/ModelClient.php @@ -18,7 +18,7 @@ use Symfony\Contracts\HttpClient\HttpClientInterface; */ final class ModelClient implements ModelClientInterface { - private readonly EventSourceHttpClient $httpClient; + private readonly HttpClientInterface $httpClient; public function __construct( HttpClientInterface $httpClient, @@ -44,13 +44,23 @@ final class ModelClient implements ModelClientInterface */ public function request(Model $model, array|string $payload, array $options = []): RawResultInterface { - $headers = ['Content-Type' => 'application/json']; + $headers = [ + 'Content-Type' => 'application/json', + // Lowercase 'accept' ist wichtig: EventSourceHttpClient prüft exakt $options['headers']['accept'] + // mit ??= — uppercase 'Accept' würde NICHT matchen und trotzdem text/event-stream setzen. + 'accept' => 'application/json', + ]; if ($this->apiKey) { $headers['Authorization'] = 'Bearer ' . $this->apiKey; } $body = array_merge($payload, ['model' => $model->getName()]); + // Ollama-spezifische Optionen (z.B. num_ctx) direkt in den Body mergen + if (!empty($options['ollama_options'])) { + $body['options'] = $options['ollama_options']; + } + // Tools in OpenAI-Format bringen: {type: "function", function: {name, description, parameters}} if (!empty($options['tools'])) { $body['tools'] = array_map( @@ -77,7 +87,7 @@ final class ModelClient implements ModelClientInterface $response = $this->httpClient->request('POST', rtrim($this->baseUrl, '/') . $this->path, [ 'headers' => $headers, 'json' => $body, - 'timeout' => 120, + 'timeout' => 180, ]); return new RawHttpResult($response); diff --git a/src/new/src/PSC/Component/ApiBundle/Api/Shop/Get.php b/src/new/src/PSC/Component/ApiBundle/Api/Shop/Get.php index 71a7494e1..d04feb993 100755 --- a/src/new/src/PSC/Component/ApiBundle/Api/Shop/Get.php +++ b/src/new/src/PSC/Component/ApiBundle/Api/Shop/Get.php @@ -4,33 +4,47 @@ namespace PSC\Component\ApiBundle\Api\Shop; use Doctrine\ORM\EntityManagerInterface; use Nelmio\ApiDocBundle\Attribute\Model; -use OpenApi\Attributes as OA; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\JsonContent; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; use PSC\Component\ApiBundle\Dto\Error\NotFound; use PSC\Component\ApiBundle\Dto\Shop\Shops; -use PSC\Component\ApiBundle\Model\Shop; -use PSC\Component\ApiBundle\Model\Shop\Domain; +use PSC\Shop\EntityBundle\Repository\ShopContactRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response as HttpResponse; -use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; -use Symfony\Component\Yaml\Yaml; class Get extends AbstractController { - private EntityManagerInterface $entityManager; - private \PSC\Component\ApiBundle\Hydrate\Shop $hydrateShop; - public function __construct( - EntityManagerInterface $entityManager, - \PSC\Component\ApiBundle\Hydrate\Shop $hydrateShop, - ) { - $this->entityManager = $entityManager; - $this->hydrateShop = $hydrateShop; + private EntityManagerInterface $entityManager, + private \PSC\Component\ApiBundle\Hydrate\Shop $hydrateShop, + private ShopContactRepository $shopContactRepository, + ) {} + + #[Response( + response: 200, + description: 'my shops', + content: new JsonContent(ref: new Model(type: PSC\Component\ApiBundle\Dto\Shop\Shops\Output::class)), + )] + #[Tag(name: 'Shops')] + #[Security(name: 'ApiKeyAuth')] + #[Security(name: 'Bearer')] + #[Route(path: '/my_shops', methods: ['GET'])] + #[IsGranted('ROLE_SHOP')] + public function myShops(): JsonResponse + { + $shops = $this->entityManager->getRepository(\PSC\Shop\EntityBundle\Entity\Shop::class)->findAll(); + + $data = []; + /** @var \PSC\Shop\EntityBundle\Entity\Shop $shop */ + foreach ($shops as $shop) { + $data[] = $this->hydrateShop->hydrateToModel($shop); + } + + return $this->json(new Shops\Output($data)); } #[Response( @@ -45,7 +59,7 @@ class Get extends AbstractController #[IsGranted('ROLE_SHOP')] public function allAction(): JsonResponse { - $shops = $this->entityManager->getRepository(\PSC\Shop\EntityBundle\Entity\Shop::class)->findAll(); + $shops = $this->shopContactRepository->myEditableShops($this->getUser()); $data = []; /** @var \PSC\Shop\EntityBundle\Entity\Shop $shop */ diff --git a/src/new/src/PSC/Shop/EntityBundle/Repository/ShopContactRepository.php b/src/new/src/PSC/Shop/EntityBundle/Repository/ShopContactRepository.php index 739eafc70..a7b0a86d9 100755 --- a/src/new/src/PSC/Shop/EntityBundle/Repository/ShopContactRepository.php +++ b/src/new/src/PSC/Shop/EntityBundle/Repository/ShopContactRepository.php @@ -13,9 +13,11 @@ namespace PSC\Shop\EntityBundle\Repository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\ORM\EntityRepository; +use Doctrine\Persistence\ManagerRegistry; use PSC\Shop\EntityBundle\Entity\Contact; +use PSC\Shop\EntityBundle\Entity\ShopContact; /** * ShopContactRepository @@ -26,8 +28,13 @@ use PSC\Shop\EntityBundle\Entity\Contact; * @package PSC\Shop\Entity * @subpackage Repositorys */ -class ShopContactRepository extends EntityRepository +class ShopContactRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ShopContact::class); + } + /** * Gibt einen Shop per Apikey zurück * @@ -42,12 +49,13 @@ class ShopContactRepository extends EntityRepository public function myEditableShops(Contact $contact) { - $query = $this->getEntityManager()->createQuery( - ' + $query = $this + ->getEntityManager() + ->createQuery(' SELECT sc FROM PSC\Shop\EntityBundle\Entity\ShopContact sc JOIN sc.shop s - WHERE sc.contact = :id AND sc.admin = 1 ORDER BY sc.admin ASC, s.title ASC', - )->setParameter('id', $contact->getId()); + WHERE sc.contact = :id AND sc.admin = 1 ORDER BY sc.admin ASC, s.title ASC') + ->setParameter('id', $contact->getId()); try { $result = $query->execute(); $tmpCollection = new ArrayCollection(); @@ -62,12 +70,15 @@ class ShopContactRepository extends EntityRepository public function myEditableShopsWithNoDeleted(Contact $contact) { - $query = $this->getEntityManager()->createQuery( - ' + $query = $this + ->getEntityManager() + ->createQuery( + ' SELECT sc FROM PSC\Shop\EntityBundle\Entity\ShopContact sc JOIN sc.shop s WHERE sc.contact = :id AND s.deleted = 0 AND sc.admin = 1 ORDER BY sc.admin ASC, s.title ASC', - )->setParameter('id', $contact->getId()); + ) + ->setParameter('id', $contact->getId()); try { $result = $query->execute(); $tmpCollection = new ArrayCollection(); @@ -82,14 +93,16 @@ class ShopContactRepository extends EntityRepository public function changeSelectedShop(Contact $contact, $shop_uuid) { - $this->getEntityManager() + $this + ->getEntityManager() ->createQuery(' UPDATE PSC\Shop\EntityBundle\Entity\ShopContact sc SET sc.selected = 0 WHERE sc.contact = :id AND sc.selected = 1') ->setParameter('id', $contact->getId()) ->execute(); - $this->getEntityManager() + $this + ->getEntityManager() ->createQuery(' UPDATE PSC\Shop\EntityBundle\Entity\ShopContact sc SET sc.selected = 1 @@ -101,7 +114,8 @@ class ShopContactRepository extends EntityRepository public function updateAdmin($contactId, $shopId, $admin = true) { - $this->createQueryBuilder('sc') + $this + ->createQueryBuilder('sc') ->update() ->set('sc.admin', '?1') ->setParameter(1, $admin) @@ -114,7 +128,8 @@ class ShopContactRepository extends EntityRepository public function resetAdmin($contactId, $admin = true) { - $this->createQueryBuilder('sc') + $this + ->createQueryBuilder('sc') ->update() ->set('sc.admin', '?1') ->setParameter(1, $admin) diff --git a/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig b/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig index 557832da6..f02b2b26a 100755 --- a/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig +++ b/src/new/src/PSC/System/SettingsBundle/Resources/views/backend/settings/index.html.twig @@ -452,7 +452,7 @@ - + @@ -486,12 +486,12 @@
AnbieterEmpfohlenes ModellAPI Key nötigBase URL
Ollamallama3.2 / mistralNeinhttp://localhost:11434
Ollamaqwen2.5-coder:3b / llama3.2 / mistralNeinhttp://localhost:11434
Anthropicclaude-sonnet-4-6Ja-
OpenAIgpt-4oJa-
Googlegemini-2.0-flashJa-