diff --git a/README.md b/README.md index f1244d7d8..e23bd2618 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Symfony AI consists of several lower and higher level **components** and the res * **Components** * **[Platform](src/platform/README.md)**: A unified interface to various AI platforms like OpenAI, Anthropic, Azure, Gemini, VertexAI, and more. * **[Agent](src/agent/README.md)**: Framework for building AI agents that can interact with users and perform tasks. + * **[Chat](src/chat/README.md)**: An unified interface to send messages to agents and store long-term context. * **[Store](src/store/README.md)**: Data storage abstraction with indexing and retrieval for AI applications. * **Bundles** * **[AI Bundle](src/ai-bundle/README.md)**: Symfony integration for AI Platform, Store and Agent components. diff --git a/examples/misc/persistent-chat.php b/examples/chat/persistent-chat.php similarity index 92% rename from examples/misc/persistent-chat.php rename to examples/chat/persistent-chat.php index 1a3ecc712..a4a351dd4 100644 --- a/examples/misc/persistent-chat.php +++ b/examples/chat/persistent-chat.php @@ -10,8 +10,8 @@ */ use Symfony\AI\Agent\Agent; -use Symfony\AI\Agent\Chat; -use Symfony\AI\Agent\Chat\MessageStore\InMemoryStore; +use Symfony\AI\Chat\Bridge\Local\InMemoryStore; +use Symfony\AI\Chat\Chat; use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; diff --git a/examples/composer.json b/examples/composer.json index 70c946e26..1d214c1c0 100644 --- a/examples/composer.json +++ b/examples/composer.json @@ -17,6 +17,7 @@ "probots-io/pinecone-php": "^1.0", "psr/http-factory-implementation": "*", "symfony/ai-agent": "@dev", + "symfony/ai-chat": "@dev", "symfony/ai-platform": "@dev", "symfony/ai-store": "@dev", "symfony/cache": "^7.3|^8.0", diff --git a/src/agent/AGENTS.md b/src/agent/AGENTS.md index 8b8130c7d..869a0173d 100644 --- a/src/agent/AGENTS.md +++ b/src/agent/AGENTS.md @@ -11,7 +11,6 @@ Framework for building AI agents with user interaction and task execution. Built ### Core Classes - **Agent** (`src/Agent.php`): Main orchestration class - **AgentInterface**: Contract for implementations -- **Chat** (`src/Chat.php`): High-level conversation interface - **Input/Output** (`src/Input.php`, `src/Output.php`): Pipeline data containers ### Processing Pipeline @@ -79,4 +78,4 @@ cd ../../.. && vendor/bin/php-cs-fixer fix src/agent/ - Component is experimental (BC breaks possible) - Add `@author` tags to new classes - Use component-specific exceptions from `src/Exception/` -- Follow `@Symfony` PHP CS Fixer rules \ No newline at end of file +- Follow `@Symfony` PHP CS Fixer rules diff --git a/src/chat/.gitattributes b/src/chat/.gitattributes new file mode 100644 index 000000000..9cf0aaea6 --- /dev/null +++ b/src/chat/.gitattributes @@ -0,0 +1,8 @@ +/.github export-ignore +/tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +phpstan.dist.neon export-ignore +phpunit.xml.dist export-ignore +CLAUDE.md export-ignore +AGENTS.md export-ignore diff --git a/src/chat/.github/PULL_REQUEST_TEMPLATE.md b/src/chat/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..fcb87228a --- /dev/null +++ b/src/chat/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +Please do not submit any Pull Requests here. They will be closed. +--- + +Please submit your PR here instead: +https://github.com/symfony/ai + +This repository is what we call a "subtree split": a read-only subset of that main repository. +We're looking forward to your PR there! diff --git a/src/chat/.github/workflows/close-pull-request.yml b/src/chat/.github/workflows/close-pull-request.yml new file mode 100644 index 000000000..207153fd5 --- /dev/null +++ b/src/chat/.github/workflows/close-pull-request.yml @@ -0,0 +1,20 @@ +name: Close Pull Request + +on: + pull_request_target: + types: [opened] + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Thanks for your Pull Request! We love contributions. + + However, you should instead open your PR on the main repository: + https://github.com/symfony/ai + + This repository is what we call a "subtree split": a read-only subset of that main repository. + We're looking forward to your PR there! diff --git a/src/chat/.gitignore b/src/chat/.gitignore new file mode 100644 index 000000000..f43db636b --- /dev/null +++ b/src/chat/.gitignore @@ -0,0 +1,3 @@ +composer.lock +vendor +.phpunit.cache diff --git a/src/chat/AGENTS.md b/src/chat/AGENTS.md new file mode 100644 index 000000000..845fee746 --- /dev/null +++ b/src/chat/AGENTS.md @@ -0,0 +1,58 @@ +# AGENTS.md + +AI agent guidance for the Chat component. + +## Component Overview + +Library for building chats with agents using messages. Built on Platform and Agent components. + +## Architecture + +### Core Classes +- **Chat** (`src/Chat.php`): Main orchestration class +- **ChatInterface**: Contract for implementations +- **MessageStoreInterface** High-level conversation storage interface + +### Key Features +- **Bridge** (`src/Bridge/`): Storage capacity for messages and conversations + +## Essential Commands + +### Testing +```bash +vendor/bin/phpunit +vendor/bin/phpunit tests/ChatTest.php +vendor/bin/phpunit --coverage-html coverage/ +``` + +### Code Quality +```bash +vendor/bin/phpstan analyse +cd ../../.. && vendor/bin/php-cs-fixer fix src/chat/ +``` + +## Processing Architecture + +### Built-in bridges +- **CacheStore**: PSR-16 compliant storage +- **InMemoryStore**: In-memory storage +- **SessionStore**: Symfony HttpFoundation session storage + +## Dependencies + +- **Platform component**: Required for AI communication +- **Agent component**: Required for agent interaction +- **Symfony**: HttpFoundation + +## Testing Patterns + +- Use `MockHttpClient` over response mocking +- Test bridges independently +- Prefer `self::assert*` in tests + +## Development Notes + +- Component is experimental (BC breaks possible) +- Add `@author` tags to new classes +- Use component-specific exceptions from `src/Exception/` +- Follow `@Symfony` PHP CS Fixer rules diff --git a/src/chat/CHANGELOG.md b/src/chat/CHANGELOG.md new file mode 100644 index 000000000..dfd4e85a5 --- /dev/null +++ b/src/chat/CHANGELOG.md @@ -0,0 +1,7 @@ +CHANGELOG +========= + +0.1 +--- + + * Introduce the component diff --git a/src/chat/CLAUDE.md b/src/chat/CLAUDE.md new file mode 100644 index 000000000..7eff813da --- /dev/null +++ b/src/chat/CLAUDE.md @@ -0,0 +1,58 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in the Agent component. + +## Component Overview + +Library for building chats with agents using messages. Built on Platform and Agent components. + +## Architecture + +### Core Classes +- **Chat** (`src/Chat.php`): Main orchestration class +- **ChatInterface**: Contract for implementations +- **MessageStoreInterface** High-level conversation storage interface + +### Key Features +- **Bridge** (`src/Bridge/`): Storage capacity for messages and conversations + +## Essential Commands + +### Testing +```bash +vendor/bin/phpunit +vendor/bin/phpunit tests/ChatTests.php +vendor/bin/phpunit --coverage-html coverage/ +``` + +### Code Quality +```bash +vendor/bin/phpstan analyse +cd ../../.. && vendor/bin/php-cs-fixer fix src/chat/ +``` + +## Processing Architecture + +### Built-in bridges +- **CacheStore**: PSR-16 compliant storage +- **InMemoryStore**: In-memory storage +- **SessionStore**: Symfony HttpFoundation session storage + +## Dependencies + +- **Platform component**: Required for AI communication +- **Agent component**: Required for agent interaction +- **Symfony**: HttpFoundation + +## Testing Patterns + +- Use `MockHttpClient` over response mocking +- Test bridges independently +- Prefer `self::assert*` in tests + +## Development Notes + +- All new classes should have `@author` tags +- Use component-specific exceptions from `src/Exception/` +- Follow Symfony coding standards with `@Symfony` PHP CS Fixer rules +- The component is marked as experimental and subject to BC breaks diff --git a/src/chat/LICENSE b/src/chat/LICENSE new file mode 100644 index 000000000..bc38d714e --- /dev/null +++ b/src/chat/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2025-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/chat/README.md b/src/chat/README.md new file mode 100644 index 000000000..615a098b3 --- /dev/null +++ b/src/chat/README.md @@ -0,0 +1,25 @@ +# Symfony AI - Chat Component + +The Chat component provides a bridge for building chats with agents, sits on top of the Agent component, +allowing you to create chats and submit messages to agents. + +**This Component is experimental**. +[Experimental features](https://symfony.com/doc/current/contributing/code/experimental.html) +are not covered by Symfony's +[Backward Compatibility Promise](https://symfony.com/doc/current/contributing/code/bc.html). + +## Installation + +```bash +composer require symfony/ai-chat +``` + +**This repository is a READ-ONLY sub-tree split**. See +https://github.com/symfony/ai to create issues or submit pull requests. + +## Resources + +- [Documentation](doc/index.rst) +- [Report issues](https://github.com/symfony/ai/issues) and + [send Pull Requests](https://github.com/symfony/ai/pulls) + in the [main Symfony AI repository](https://github.com/symfony/ai) diff --git a/src/chat/composer.json b/src/chat/composer.json new file mode 100644 index 000000000..2a9df48fa --- /dev/null +++ b/src/chat/composer.json @@ -0,0 +1,54 @@ +{ + "name": "symfony/ai-chat", + "description": "PHP library for building chats with agents.", + "license": "MIT", + "type": "library", + "keywords": [ + "ai", + "llm", + "agent", + "chat" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + } + ], + "require": { + "php": ">=8.2", + "symfony/ai-agent": "@dev" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.13", + "symfony/http-foundation": "^7.3|^8.0", + "psr/cache": "^3.0" + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Chat\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Symfony\\AI\\Chat\\Tests\\": "tests/", + "Symfony\\AI\\PHPStan\\": "../../.phpstan/" + } + }, + "config": { + "sort-packages": true + }, + "extra": { + "thanks": { + "name": "symfony/ai", + "url": "https://github.com/symfony/ai" + } + }, + "minimum-stability": "dev" +} diff --git a/src/chat/doc/index.rst b/src/chat/doc/index.rst new file mode 100644 index 000000000..d196249a3 --- /dev/null +++ b/src/chat/doc/index.rst @@ -0,0 +1,36 @@ +Symfony AI - Chat Component +=========================== + +The Chat component provides an API to interact with agents, it allows to store messages and retrieve them later +for future chat and context-retrieving purposes. + +Installation +------------ + +Install the component using Composer: + +.. code-block:: terminal + + $ composer require symfony/ai-chat + +Basic Usage +----------- + +To initiate a chat, you need to instantiate the ``Symfony\AI\Chat\Chat`` along +with a ``Symfony\AI\Agent\AgentInterface`` and a ``Symfony\AI\Chat\MessageStoreInterface``:: + + use Symfony\AI\Agent\Agent; + use Symfony\AI\Chat\Bridge\Local\InMemoryStore; + use Symfony\AI\Chat\Chat; + use Symfony\AI\Platform\Bridge\OpenAi\Gpt; + use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory; + use Symfony\AI\Platform\Message\Message; + + $platform = PlatformFactory::create($apiKey); + $model = new Gpt(Gpt::GPT_4O_MINI); + + $agent = new Agent($platform, $model); + $chat = new Chat($agent, new InMemoryStore()); + + $chat->submit(Message::ofUser('Hello')); + diff --git a/src/chat/phpstan.dist.neon b/src/chat/phpstan.dist.neon new file mode 100644 index 000000000..0ea90278a --- /dev/null +++ b/src/chat/phpstan.dist.neon @@ -0,0 +1,11 @@ +includes: + - ../../.phpstan/extension.neon + +parameters: + level: 6 + paths: + - src/ + - tests/ + ignoreErrors: + - + message: "#^Method .*::test.*\\(\\) has no return type specified\\.$#" diff --git a/src/chat/phpunit.xml.dist b/src/chat/phpunit.xml.dist new file mode 100644 index 000000000..0ed27cf54 --- /dev/null +++ b/src/chat/phpunit.xml.dist @@ -0,0 +1,22 @@ + + + + + tests + + + + + + src + + + diff --git a/src/agent/src/Chat/MessageStore/SessionStore.php b/src/chat/src/Bridge/HttpFoundation/SessionStore.php similarity index 93% rename from src/agent/src/Chat/MessageStore/SessionStore.php rename to src/chat/src/Bridge/HttpFoundation/SessionStore.php index b5a0cea63..32c11f4dd 100644 --- a/src/agent/src/Chat/MessageStore/SessionStore.php +++ b/src/chat/src/Bridge/HttpFoundation/SessionStore.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent\Chat\MessageStore; +namespace Symfony\AI\Chat\Bridge\HttpFoundation; -use Symfony\AI\Agent\Chat\MessageStoreInterface; use Symfony\AI\Agent\Exception\RuntimeException; +use Symfony\AI\Chat\MessageStoreInterface; use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\SessionInterface; diff --git a/src/agent/src/Chat/MessageStore/CacheStore.php b/src/chat/src/Bridge/Local/CacheStore.php similarity index 93% rename from src/agent/src/Chat/MessageStore/CacheStore.php rename to src/chat/src/Bridge/Local/CacheStore.php index e3875baba..3d8ae4805 100644 --- a/src/agent/src/Chat/MessageStore/CacheStore.php +++ b/src/chat/src/Bridge/Local/CacheStore.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent\Chat\MessageStore; +namespace Symfony\AI\Chat\Bridge\Local; use Psr\Cache\CacheItemPoolInterface; -use Symfony\AI\Agent\Chat\MessageStoreInterface; use Symfony\AI\Agent\Exception\RuntimeException; +use Symfony\AI\Chat\MessageStoreInterface; use Symfony\AI\Platform\Message\MessageBag; /** diff --git a/src/agent/src/Chat/MessageStore/InMemoryStore.php b/src/chat/src/Bridge/Local/InMemoryStore.php similarity index 88% rename from src/agent/src/Chat/MessageStore/InMemoryStore.php rename to src/chat/src/Bridge/Local/InMemoryStore.php index 41e01ed1e..e23777efa 100644 --- a/src/agent/src/Chat/MessageStore/InMemoryStore.php +++ b/src/chat/src/Bridge/Local/InMemoryStore.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent\Chat\MessageStore; +namespace Symfony\AI\Chat\Bridge\Local; -use Symfony\AI\Agent\Chat\MessageStoreInterface; +use Symfony\AI\Chat\MessageStoreInterface; use Symfony\AI\Platform\Message\MessageBag; /** diff --git a/src/agent/src/Chat.php b/src/chat/src/Chat.php similarity index 94% rename from src/agent/src/Chat.php rename to src/chat/src/Chat.php index 1c594c8b2..a4e7f54af 100644 --- a/src/agent/src/Chat.php +++ b/src/chat/src/Chat.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent; +namespace Symfony\AI\Chat; -use Symfony\AI\Agent\Chat\MessageStoreInterface; +use Symfony\AI\Agent\AgentInterface; use Symfony\AI\Platform\Message\AssistantMessage; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; diff --git a/src/agent/src/ChatInterface.php b/src/chat/src/ChatInterface.php similarity index 96% rename from src/agent/src/ChatInterface.php rename to src/chat/src/ChatInterface.php index ba17f92cc..727146131 100644 --- a/src/agent/src/ChatInterface.php +++ b/src/chat/src/ChatInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent; +namespace Symfony\AI\Chat; use Symfony\AI\Agent\Exception\ExceptionInterface; use Symfony\AI\Platform\Message\AssistantMessage; diff --git a/src/agent/src/Chat/MessageStoreInterface.php b/src/chat/src/MessageStoreInterface.php similarity index 94% rename from src/agent/src/Chat/MessageStoreInterface.php rename to src/chat/src/MessageStoreInterface.php index 06651ad97..ec0833e7c 100644 --- a/src/agent/src/Chat/MessageStoreInterface.php +++ b/src/chat/src/MessageStoreInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent\Chat; +namespace Symfony\AI\Chat; use Symfony\AI\Platform\Message\MessageBag; diff --git a/src/agent/tests/ChatTest.php b/src/chat/tests/ChatTest.php similarity index 97% rename from src/agent/tests/ChatTest.php rename to src/chat/tests/ChatTest.php index 902cfae44..9522fdbd8 100644 --- a/src/agent/tests/ChatTest.php +++ b/src/chat/tests/ChatTest.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Symfony\AI\Agent\Tests; +namespace Symfony\AI\Chat\Tests; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\AI\Agent\AgentInterface; -use Symfony\AI\Agent\Chat; -use Symfony\AI\Agent\Chat\MessageStoreInterface; +use Symfony\AI\Chat\Chat; +use Symfony\AI\Chat\MessageStoreInterface; use Symfony\AI\Platform\Message\AssistantMessage; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag;