From 9f686c88fef130a9a9fe8a28d490f91eee2de4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 21 Jun 2026 16:15:36 +0200 Subject: [PATCH 1/2] Updated symfony ai bundle to 0.10.0 --- composer.json | 6 +- composer.lock | 236 +++++++++++++++++++++---------------------- config/reference.php | 5 +- 3 files changed, 124 insertions(+), 123 deletions(-) diff --git a/composer.json b/composer.json index f08f824d..d624ea8e 100644 --- a/composer.json +++ b/composer.json @@ -57,9 +57,9 @@ "scheb/2fa-trusted-device": "^v7.11.0", "shivas/versioning-bundle": "^4.0", "spatie/db-dumper": "^3.3.1", - "symfony/ai-bundle": "^0.9.0", - "symfony/ai-lm-studio-platform": "^0.9.0", - "symfony/ai-open-router-platform": "^0.9.0", + "symfony/ai-bundle": "^0.10.0", + "symfony/ai-lm-studio-platform": "^v0.10.0", + "symfony/ai-open-router-platform": "^0.10.0", "symfony/apache-pack": "^1.0", "symfony/asset": "7.4.*", "symfony/console": "7.4.*", diff --git a/composer.lock b/composer.lock index 467bc8a1..5738fb88 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1307bf553d1543704e3c03398dec06c7", + "content-hash": "ec87cdf341410bbd499a9debb5c862ab", "packages": [ { "name": "amphp/amp", - "version": "v3.1.1", + "version": "v3.1.2", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f" + "reference": "2f3ebed5a4f663968a0590dbb7654a8b32cb63cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/fa0ab33a6f47a82929c38d03ca47ebb71086a93f", - "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f", + "url": "https://api.github.com/repos/amphp/amp/zipball/2f3ebed5a4f663968a0590dbb7654a8b32cb63cb", + "reference": "2f3ebed5a4f663968a0590dbb7654a8b32cb63cb", "shasum": "" }, "require": { @@ -27,7 +27,7 @@ "require-dev": { "amphp/php-cs-fixer-config": "^2", "phpunit/phpunit": "^9", - "psalm/phar": "5.23.1" + "psalm/phar": "6.16.1" }, "type": "library", "autoload": { @@ -77,7 +77,7 @@ ], "support": { "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v3.1.1" + "source": "https://github.com/amphp/amp/tree/v3.1.2" }, "funding": [ { @@ -85,7 +85,7 @@ "type": "github" } ], - "time": "2025-08-27T21:42:00+00:00" + "time": "2026-06-21T13:59:44+00:00" }, { "name": "amphp/byte-stream", @@ -10733,21 +10733,21 @@ }, { "name": "symfony/ai-bundle", - "version": "v0.9.0", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/symfony/ai-bundle.git", - "reference": "77fd1b513174770acf49abd68effa995fa518f7c" + "reference": "5f6d218ca26a4ac3c2b743e4bfae769c41c556c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ai-bundle/zipball/77fd1b513174770acf49abd68effa995fa518f7c", - "reference": "77fd1b513174770acf49abd68effa995fa518f7c", + "url": "https://api.github.com/repos/symfony/ai-bundle/zipball/5f6d218ca26a4ac3c2b743e4bfae769c41c556c0", + "reference": "5f6d218ca26a4ac3c2b743e4bfae769c41c556c0", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/ai-platform": "^0.9", + "symfony/ai-platform": "^0.10", "symfony/clock": "^7.3|^8.0", "symfony/config": "^7.3|^8.0", "symfony/console": "^7.3|^8.0", @@ -10762,74 +10762,74 @@ "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^11.5.53", - "symfony/ai-agent": "^0.9", - "symfony/ai-ai-ml-api-platform": "^0.9", - "symfony/ai-albert-platform": "^0.9", - "symfony/ai-amazee-ai-platform": "^0.9", - "symfony/ai-anthropic-platform": "^0.9", - "symfony/ai-azure-platform": "^0.9", - "symfony/ai-azure-search-store": "^0.9", - "symfony/ai-bedrock-platform": "^0.9", - "symfony/ai-cache-message-store": "^0.9", - "symfony/ai-cache-platform": "^0.9", - "symfony/ai-cache-store": "^0.9", - "symfony/ai-cartesia-platform": "^0.9", - "symfony/ai-cerebras-platform": "^0.9", - "symfony/ai-chat": "^0.9", - "symfony/ai-chroma-db-store": "^0.9", - "symfony/ai-click-house-store": "^0.9", - "symfony/ai-cloudflare-message-store": "^0.9", - "symfony/ai-cloudflare-store": "^0.9", - "symfony/ai-cohere-platform": "^0.9", - "symfony/ai-decart-platform": "^0.9", - "symfony/ai-deep-seek-platform": "^0.9", - "symfony/ai-docker-model-runner-platform": "^0.9", - "symfony/ai-doctrine-message-store": "^0.9", - "symfony/ai-elasticsearch-store": "^0.9", - "symfony/ai-eleven-labs-platform": "^0.9", - "symfony/ai-failover-platform": "^0.9", - "symfony/ai-gemini-platform": "^0.9", - "symfony/ai-generic-platform": "^0.9", - "symfony/ai-hugging-face-platform": "^0.9", - "symfony/ai-lm-studio-platform": "^0.9", - "symfony/ai-manticore-search-store": "^0.9", - "symfony/ai-maria-db-store": "^0.9", - "symfony/ai-meilisearch-message-store": "^0.9", - "symfony/ai-meilisearch-store": "^0.9", - "symfony/ai-meta-platform": "^0.9", - "symfony/ai-milvus-store": "^0.9", - "symfony/ai-mistral-platform": "^0.9", - "symfony/ai-mongo-db-message-store": "^0.9", - "symfony/ai-mongo-db-store": "^0.9", - "symfony/ai-neo4j-store": "^0.9", - "symfony/ai-ollama-platform": "^0.9", - "symfony/ai-open-ai-platform": "^0.9", - "symfony/ai-open-responses-platform": "^0.9", - "symfony/ai-open-router-platform": "^0.9", - "symfony/ai-open-search-store": "^0.9", - "symfony/ai-ovh-platform": "^0.9", - "symfony/ai-perplexity-platform": "^0.9", - "symfony/ai-pinecone-store": "^0.9", - "symfony/ai-pogocache-message-store": "^0.9", - "symfony/ai-postgres-store": "^0.9", - "symfony/ai-qdrant-store": "^0.9", - "symfony/ai-redis-message-store": "^0.9", - "symfony/ai-redis-store": "^0.9", - "symfony/ai-replicate-platform": "^0.9", - "symfony/ai-s3vectors-store": "^0.9", - "symfony/ai-scaleway-platform": "^0.9", - "symfony/ai-session-message-store": "^0.9", - "symfony/ai-sqlite-store": "^0.9", - "symfony/ai-store": "^0.9", - "symfony/ai-supabase-store": "^0.9", - "symfony/ai-surreal-db-message-store": "^0.9", - "symfony/ai-surreal-db-store": "^0.9", - "symfony/ai-transformers-php-platform": "^0.9", - "symfony/ai-typesense-store": "^0.9", - "symfony/ai-vektor-store": "^0.9", - "symfony/ai-vertex-ai-platform": "^0.9", - "symfony/ai-voyage-platform": "^0.9", - "symfony/ai-weaviate-store": "^0.9", + "symfony/ai-agent": "^0.10", + "symfony/ai-ai-ml-api-platform": "^0.10", + "symfony/ai-albert-platform": "^0.10", + "symfony/ai-amazee-ai-platform": "^0.10", + "symfony/ai-anthropic-platform": "^0.10", + "symfony/ai-azure-platform": "^0.10", + "symfony/ai-azure-search-store": "^0.10", + "symfony/ai-bedrock-platform": "^0.10", + "symfony/ai-cache-message-store": "^0.10", + "symfony/ai-cache-platform": "^0.10", + "symfony/ai-cache-store": "^0.10", + "symfony/ai-cartesia-platform": "^0.10", + "symfony/ai-cerebras-platform": "^0.10", + "symfony/ai-chat": "^0.10", + "symfony/ai-chroma-db-store": "^0.10", + "symfony/ai-click-house-store": "^0.10", + "symfony/ai-cloudflare-message-store": "^0.10", + "symfony/ai-cloudflare-store": "^0.10", + "symfony/ai-cohere-platform": "^0.10", + "symfony/ai-decart-platform": "^0.10", + "symfony/ai-deep-seek-platform": "^0.10", + "symfony/ai-docker-model-runner-platform": "^0.10", + "symfony/ai-doctrine-message-store": "^0.10", + "symfony/ai-elasticsearch-store": "^0.10", + "symfony/ai-eleven-labs-platform": "^0.10", + "symfony/ai-failover-platform": "^0.10", + "symfony/ai-gemini-platform": "^0.10", + "symfony/ai-generic-platform": "^0.10", + "symfony/ai-hugging-face-platform": "^0.10", + "symfony/ai-lm-studio-platform": "^0.10", + "symfony/ai-manticore-search-store": "^0.10", + "symfony/ai-maria-db-store": "^0.10", + "symfony/ai-meilisearch-message-store": "^0.10", + "symfony/ai-meilisearch-store": "^0.10", + "symfony/ai-meta-platform": "^0.10", + "symfony/ai-milvus-store": "^0.10", + "symfony/ai-mistral-platform": "^0.10", + "symfony/ai-mongo-db-message-store": "^0.10", + "symfony/ai-mongo-db-store": "^0.10", + "symfony/ai-neo4j-store": "^0.10", + "symfony/ai-ollama-platform": "^0.10", + "symfony/ai-open-ai-platform": "^0.10", + "symfony/ai-open-responses-platform": "^0.10", + "symfony/ai-open-router-platform": "^0.10", + "symfony/ai-open-search-store": "^0.10", + "symfony/ai-ovh-platform": "^0.10", + "symfony/ai-perplexity-platform": "^0.10", + "symfony/ai-pinecone-store": "^0.10", + "symfony/ai-pogocache-message-store": "^0.10", + "symfony/ai-postgres-store": "^0.10", + "symfony/ai-qdrant-store": "^0.10", + "symfony/ai-redis-message-store": "^0.10", + "symfony/ai-redis-store": "^0.10", + "symfony/ai-replicate-platform": "^0.10", + "symfony/ai-s3vectors-store": "^0.10", + "symfony/ai-scaleway-platform": "^0.10", + "symfony/ai-session-message-store": "^0.10", + "symfony/ai-sqlite-store": "^0.10", + "symfony/ai-store": "^0.10", + "symfony/ai-supabase-store": "^0.10", + "symfony/ai-surreal-db-message-store": "^0.10", + "symfony/ai-surreal-db-store": "^0.10", + "symfony/ai-transformers-php-platform": "^0.10", + "symfony/ai-typesense-store": "^0.10", + "symfony/ai-vektor-store": "^0.10", + "symfony/ai-vertex-ai-platform": "^0.10", + "symfony/ai-voyage-platform": "^0.10", + "symfony/ai-weaviate-store": "^0.10", "symfony/expression-language": "^7.3|^8.0", "symfony/security-core": "^7.3|^8.0", "symfony/translation": "^7.3|^8.0", @@ -10867,7 +10867,7 @@ ], "description": "Integration bundle for Symfony AI components", "support": { - "source": "https://github.com/symfony/ai-bundle/tree/v0.9.0" + "source": "https://github.com/symfony/ai-bundle/tree/v0.10.0" }, "funding": [ { @@ -10887,25 +10887,25 @@ "type": "tidelift" } ], - "time": "2026-05-16T08:40:45+00:00" + "time": "2026-06-16T07:10:08+00:00" }, { "name": "symfony/ai-generic-platform", - "version": "v0.9.0", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/symfony/ai-generic-platform.git", - "reference": "8887d12b8ea97d079c5c97de4aebb19f42c58dc5" + "reference": "a099d8a35ea9f7254a159b9c17bc7a4927f9ebb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ai-generic-platform/zipball/8887d12b8ea97d079c5c97de4aebb19f42c58dc5", - "reference": "8887d12b8ea97d079c5c97de4aebb19f42c58dc5", + "url": "https://api.github.com/repos/symfony/ai-generic-platform/zipball/a099d8a35ea9f7254a159b9c17bc7a4927f9ebb2", + "reference": "a099d8a35ea9f7254a159b9c17bc7a4927f9ebb2", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/ai-platform": "^0.9", + "symfony/ai-platform": "^0.10", "symfony/http-client": "^7.3|^8.0" }, "require-dev": { @@ -10952,7 +10952,7 @@ "platform" ], "support": { - "source": "https://github.com/symfony/ai-generic-platform/tree/v0.9.0" + "source": "https://github.com/symfony/ai-generic-platform/tree/v0.10.0" }, "funding": [ { @@ -10972,26 +10972,26 @@ "type": "tidelift" } ], - "time": "2026-05-16T01:01:33+00:00" + "time": "2026-06-16T07:10:08+00:00" }, { "name": "symfony/ai-lm-studio-platform", - "version": "v0.9.0", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/symfony/ai-lm-studio-platform.git", - "reference": "9e53e56c8c3a04dddb955088b40904e747ec3981" + "reference": "b6c4a3a5bedf2fd613953447602945c104e75a30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ai-lm-studio-platform/zipball/9e53e56c8c3a04dddb955088b40904e747ec3981", - "reference": "9e53e56c8c3a04dddb955088b40904e747ec3981", + "url": "https://api.github.com/repos/symfony/ai-lm-studio-platform/zipball/b6c4a3a5bedf2fd613953447602945c104e75a30", + "reference": "b6c4a3a5bedf2fd613953447602945c104e75a30", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/ai-generic-platform": "^0.9", - "symfony/ai-platform": "^0.9", + "symfony/ai-generic-platform": "^0.10", + "symfony/ai-platform": "^0.10", "symfony/http-client": "^7.3|^8.0" }, "require-dev": { @@ -11039,7 +11039,7 @@ "platform" ], "support": { - "source": "https://github.com/symfony/ai-lm-studio-platform/tree/v0.9.0" + "source": "https://github.com/symfony/ai-lm-studio-platform/tree/v0.10.0" }, "funding": [ { @@ -11059,26 +11059,26 @@ "type": "tidelift" } ], - "time": "2026-05-16T01:01:33+00:00" + "time": "2026-06-15T22:48:31+00:00" }, { "name": "symfony/ai-open-router-platform", - "version": "v0.9.0", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/symfony/ai-open-router-platform.git", - "reference": "7e2b560c86f618cd5d33f9f0c581d83bebc9802f" + "reference": "cfadb7858fca98b28b968b032b1bbeb5c9cc985b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ai-open-router-platform/zipball/7e2b560c86f618cd5d33f9f0c581d83bebc9802f", - "reference": "7e2b560c86f618cd5d33f9f0c581d83bebc9802f", + "url": "https://api.github.com/repos/symfony/ai-open-router-platform/zipball/cfadb7858fca98b28b968b032b1bbeb5c9cc985b", + "reference": "cfadb7858fca98b28b968b032b1bbeb5c9cc985b", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/ai-generic-platform": "^0.9", - "symfony/ai-platform": "^0.9", + "symfony/ai-generic-platform": "^0.10", + "symfony/ai-platform": "^0.10", "symfony/http-client": "^7.3|^8.0" }, "require-dev": { @@ -11126,7 +11126,7 @@ "platform" ], "support": { - "source": "https://github.com/symfony/ai-open-router-platform/tree/v0.9.0" + "source": "https://github.com/symfony/ai-open-router-platform/tree/v0.10.0" }, "funding": [ { @@ -11146,20 +11146,20 @@ "type": "tidelift" } ], - "time": "2026-05-16T01:01:33+00:00" + "time": "2026-06-16T08:09:36+00:00" }, { "name": "symfony/ai-platform", - "version": "v0.9.0", + "version": "v0.10.0", "source": { "type": "git", "url": "https://github.com/symfony/ai-platform.git", - "reference": "fb55ebdf20bbe30af6752a0ce6a25abc56b2b625" + "reference": "8100507aa9c46f3ad56d0272e8e46b558f451052" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ai-platform/zipball/fb55ebdf20bbe30af6752a0ce6a25abc56b2b625", - "reference": "fb55ebdf20bbe30af6752a0ce6a25abc56b2b625", + "url": "https://api.github.com/repos/symfony/ai-platform/zipball/8100507aa9c46f3ad56d0272e8e46b558f451052", + "reference": "8100507aa9c46f3ad56d0272e8e46b558f451052", "shasum": "" }, "require": { @@ -11258,7 +11258,7 @@ "voyage" ], "support": { - "source": "https://github.com/symfony/ai-platform/tree/v0.9.0" + "source": "https://github.com/symfony/ai-platform/tree/v0.10.0" }, "funding": [ { @@ -11278,7 +11278,7 @@ "type": "tidelift" } ], - "time": "2026-05-15T19:15:50+00:00" + "time": "2026-06-16T06:39:24+00:00" }, { "name": "symfony/apache-pack", @@ -20222,16 +20222,16 @@ }, { "name": "rector/rector", - "version": "2.5.0", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "7526beadb3da0b88cfa9e8290d74944799d1f3a4" + "reference": "34a9124ece04df818e6b4be4ecd0a4e23f4c0c64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/7526beadb3da0b88cfa9e8290d74944799d1f3a4", - "reference": "7526beadb3da0b88cfa9e8290d74944799d1f3a4", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/34a9124ece04df818e6b4be4ecd0a4e23f4c0c64", + "reference": "34a9124ece04df818e6b4be4ecd0a4e23f4c0c64", "shasum": "" }, "require": { @@ -20270,7 +20270,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.5.0" + "source": "https://github.com/rectorphp/rector/tree/2.5.1" }, "funding": [ { @@ -20278,7 +20278,7 @@ "type": "github" } ], - "time": "2026-06-20T17:02:36+00:00" + "time": "2026-06-21T10:28:27+00:00" }, { "name": "roave/security-advisories", diff --git a/config/reference.php b/config/reference.php index 71b08412..961d8ea5 100644 --- a/config/reference.php +++ b/config/reference.php @@ -2874,8 +2874,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * enable_translation?: bool|Param, // Enable translation for the system prompt // Default: false * translation_domain?: string|Param, // The translation domain for the system prompt // Default: null * }, - * tools?: bool|array{ - * enabled?: bool|Param, // Default: true + * tools?: bool|array{ // Tools are opt-in: set to true to inject all services tagged with "ai.tool", or configure an explicit list of tools. When the option is omitted (or set to null or false), no tools are registered. + * enabled?: bool|Param, // Default: false * services?: list Date: Sun, 21 Jun 2026 20:41:24 +0200 Subject: [PATCH 2/2] Added ollama as AI provider Unlike the LMStudio one it also features an API key and proper model auto suggestion --- composer.json | 1 + composer.lock | 88 +++++++++++++++++++++- config/packages/ai_ollama_platform.yaml | 5 ++ docs/usage/ai.md | 7 ++ src/Services/AI/AIPlatforms.php | 3 + src/Settings/AISettings/AISettings.php | 3 + src/Settings/AISettings/OllamaSettings.php | 58 ++++++++++++++ symfony.lock | 12 +++ translations/messages.en.xlf | 18 +++++ 9 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 config/packages/ai_ollama_platform.yaml create mode 100644 src/Settings/AISettings/OllamaSettings.php diff --git a/composer.json b/composer.json index d624ea8e..10c9b702 100644 --- a/composer.json +++ b/composer.json @@ -59,6 +59,7 @@ "spatie/db-dumper": "^3.3.1", "symfony/ai-bundle": "^0.10.0", "symfony/ai-lm-studio-platform": "^v0.10.0", + "symfony/ai-ollama-platform": "^0.10.0", "symfony/ai-open-router-platform": "^0.10.0", "symfony/apache-pack": "^1.0", "symfony/asset": "7.4.*", diff --git a/composer.lock b/composer.lock index 5738fb88..ca50c2c6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ec87cdf341410bbd499a9debb5c862ab", + "content-hash": "6a79fa73091c2e15bce035c85c2d61ed", "packages": [ { "name": "amphp/amp", @@ -11061,6 +11061,92 @@ ], "time": "2026-06-15T22:48:31+00:00" }, + { + "name": "symfony/ai-ollama-platform", + "version": "v0.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-ollama-platform.git", + "reference": "1542f19b78362cafc034c219f5bc9a5a239a0ffb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-ollama-platform/zipball/1542f19b78362cafc034c219f5bc9a5a239a0ffb", + "reference": "1542f19b78362cafc034c219f5bc9a5a239a0ffb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-platform": "^0.10", + "symfony/http-client": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53" + }, + "type": "symfony-ai-platform", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\Bridge\\Ollama\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Ollama platform bridge for Symfony AI", + "keywords": [ + "Bridge", + "ai", + "local", + "ollama", + "platform" + ], + "support": { + "source": "https://github.com/symfony/ai-ollama-platform/tree/v0.10.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-06-15T22:48:31+00:00" + }, { "name": "symfony/ai-open-router-platform", "version": "v0.10.0", diff --git a/config/packages/ai_ollama_platform.yaml b/config/packages/ai_ollama_platform.yaml new file mode 100644 index 00000000..df551d4a --- /dev/null +++ b/config/packages/ai_ollama_platform.yaml @@ -0,0 +1,5 @@ +ai: + platform: + ollama: + endpoint: '%env(string:settings:ai_ollama:endpoint)%' + api_key: '%env(string:settings:ai_ollama:apiKey)%' diff --git a/docs/usage/ai.md b/docs/usage/ai.md index 3a1fb419..30f6c628 100644 --- a/docs/usage/ai.md +++ b/docs/usage/ai.md @@ -25,3 +25,10 @@ You need to supply an API key for OpenRouter to use it as an AI platform in Part [LMStudio](https://lmstudio.ai/) is a local LLM hosting solution that allows you to run LLMs on your own hardware. You can use LMStudio to host your own LLM and connect it to Part-DB for AI features. Currently only LMStudio without any authentication is supported. Supply your LMStudio instance URL (including the port) to use it as an AI platform in Part-DB. +You have to set a model by hand, as suggestions currently do not work yet. Ensure the context length is suitable for your application. + +### Ollama + +[Ollama](https://ollama.com/) is another local LLM hosting solution that allows you to run LLMs on your own hardware. You can use Ollama to host your own LLM and connect it to Part-DB for AI features. +Supply your Ollama instance URL (including the port) and an optional API key for authentication to use it as an AI platform in Part-DB. The model selector should give you suggestions about available models. +Ensure the context length is suitable for your application. diff --git a/src/Services/AI/AIPlatforms.php b/src/Services/AI/AIPlatforms.php index 2f4d6317..318819a2 100644 --- a/src/Services/AI/AIPlatforms.php +++ b/src/Services/AI/AIPlatforms.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace App\Services\AI; use App\Settings\AISettings\LMStudioSettings; +use App\Settings\AISettings\OllamaSettings; use App\Settings\AISettings\OpenRouterSettings; use Symfony\Contracts\Translation\TranslatableInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -32,6 +33,7 @@ enum AIPlatforms: string implements TranslatableInterface { case OPENROUTER = 'openrouter'; case LMSTUDIO = 'lmstudio'; + case OLLAMA = 'ollama'; /** * Returns the name attribute of the service tag for this platform, which is used to register the platform in the AIPlatformRegistry @@ -52,6 +54,7 @@ enum AIPlatforms: string implements TranslatableInterface return match ($this) { self::LMSTUDIO => LMStudioSettings::class, self::OPENROUTER => OpenRouterSettings::class, + self::OLLAMA => OllamaSettings::class, }; } diff --git a/src/Settings/AISettings/AISettings.php b/src/Settings/AISettings/AISettings.php index 732eb597..9f145c7f 100644 --- a/src/Settings/AISettings/AISettings.php +++ b/src/Settings/AISettings/AISettings.php @@ -40,4 +40,7 @@ class AISettings #[EmbeddedSettings] public ?LMStudioSettings $lmstudio = null; + + #[EmbeddedSettings] + public ?OllamaSettings $ollama = null; } diff --git a/src/Settings/AISettings/OllamaSettings.php b/src/Settings/AISettings/OllamaSettings.php new file mode 100644 index 00000000..dd17d5e2 --- /dev/null +++ b/src/Settings/AISettings/OllamaSettings.php @@ -0,0 +1,58 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Settings\AISettings; + +use App\Form\Type\APIKeyType; +use App\Services\AI\AIPlatformSettingsInterface; +use App\Settings\SettingsIcon; +use Jbtronics\SettingsBundle\Metadata\EnvVarMode; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Form\Extension\Core\Type\UrlType; +use Symfony\Component\Translation\StaticMessage; +use Symfony\Component\Translation\TranslatableMessage as TM; + +#[Settings(name: 'ai_ollama', label: new TM("settings.ai.ollama"))] +#[SettingsIcon("fa-robot")] +class OllamaSettings implements AIPlatformSettingsInterface +{ + use SettingsTrait; + + #[SettingsParameter(label: new TM("settings.ai.ollama.endpoint"), + formType: UrlType::class, + formOptions: ["attr" => ["placeholder" => new StaticMessage("http://localhost:11434")]], + envVar: "AI_OLLAMA_ENDPOINT", envVarMode: EnvVarMode::OVERWRITE)] + public ?string $endpoint = null; + + #[SettingsParameter(label: new TM("settings.ai.ollama.apiKey"), + formType: APIKeyType::class, + envVar: "AI_OLLAMA_API_KEY", envVarMode: EnvVarMode::OVERWRITE)] + public ?string $apiKey = null; + + public function isAIPlatformEnabled(): bool + { + return $this->endpoint !== null && $this->endpoint !== ""; + } +} diff --git a/symfony.lock b/symfony.lock index f8f88675..94af6e6a 100644 --- a/symfony.lock +++ b/symfony.lock @@ -411,6 +411,18 @@ "config/packages/ai_lm_studio_platform.yaml" ] }, + "symfony/ai-ollama-platform": { + "version": "0.10", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "0.1", + "ref": "2f0ac0a8bc59c4e46b47a962a3ad7fe8104457d6" + }, + "files": [ + "config/packages/ai_ollama_platform.yaml" + ] + }, "symfony/ai-open-router-platform": { "version": "0.8", "recipe": { diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index fe219869..af33ee97 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13619,6 +13619,24 @@ Buerklin-API Authentication server: Host URL + + + settings.ai.ollama + Ollama + + + + + settings.ai.ollama.endpoint + Endpoint URL + + + + + settings.ai.ollama.apiKey + API Key + + browser_plugin.recent_pages.title