diff --git a/demo/src/Audio/Chat.php b/demo/src/Audio/Chat.php index 178dd32fa..2987e4659 100644 --- a/demo/src/Audio/Chat.php +++ b/demo/src/Audio/Chat.php @@ -39,7 +39,7 @@ public function say(string $base64audio): void $path = tempnam(sys_get_temp_dir(), 'audio-').'.wav'; file_put_contents($path, base64_decode($base64audio)); - $result = $this->platform->invoke(new Whisper(), Audio::fromFile($path)); + $result = $this->platform->invoke(Whisper::create(), Audio::fromFile($path)); $this->submitMessage($result->asText()); } diff --git a/demo/src/Video/TwigComponent.php b/demo/src/Video/TwigComponent.php index 448e70005..115ca38f6 100644 --- a/demo/src/Video/TwigComponent.php +++ b/demo/src/Video/TwigComponent.php @@ -47,7 +47,7 @@ public function submit(#[LiveArg] string $instruction, #[LiveArg] string $image) Message::ofUser($instruction, Image::fromDataUrl($image)) ); - $result = $this->platform->invoke(new Gpt(Gpt::GPT_4O_MINI), $messageBag, [ + $result = $this->platform->invoke(Gpt::create(Gpt::GPT_4O_MINI), $messageBag, [ 'max_tokens' => 100, ]); diff --git a/examples/albert/chat.php b/examples/albert/chat.php index 3fea6d474..88d04719b 100644 --- a/examples/albert/chat.php +++ b/examples/albert/chat.php @@ -19,7 +19,7 @@ $platform = PlatformFactory::create(env('ALBERT_API_KEY'), env('ALBERT_API_URL'), http_client()); -$model = new Gpt('gpt-4o'); +$model = Gpt::create('gpt-4o'); $agent = new Agent($platform, $model, logger: logger()); $documentContext = <<<'CONTEXT' diff --git a/examples/anthropic/chat.php b/examples/anthropic/chat.php index d2c0ed868..c07d8061e 100644 --- a/examples/anthropic/chat.php +++ b/examples/anthropic/chat.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(Claude::SONNET_37); +$model = Claude::create(Claude::SONNET_37); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/anthropic/image-input-binary.php b/examples/anthropic/image-input-binary.php index d2e8fe9bd..2dd44cd60 100644 --- a/examples/anthropic/image-input-binary.php +++ b/examples/anthropic/image-input-binary.php @@ -19,7 +19,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(Claude::SONNET_37); +$model = Claude::create(Claude::SONNET_37); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/anthropic/image-input-url.php b/examples/anthropic/image-input-url.php index 089eb927c..f4ab74cdb 100644 --- a/examples/anthropic/image-input-url.php +++ b/examples/anthropic/image-input-url.php @@ -19,7 +19,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(Claude::SONNET_37); +$model = Claude::create(Claude::SONNET_37); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/anthropic/pdf-input-binary.php b/examples/anthropic/pdf-input-binary.php index 79cc9f64b..f0437f5f4 100644 --- a/examples/anthropic/pdf-input-binary.php +++ b/examples/anthropic/pdf-input-binary.php @@ -19,7 +19,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(Claude::SONNET_37); +$model = Claude::create(Claude::SONNET_37); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/anthropic/pdf-input-url.php b/examples/anthropic/pdf-input-url.php index 4f3d4f881..08749dc8d 100644 --- a/examples/anthropic/pdf-input-url.php +++ b/examples/anthropic/pdf-input-url.php @@ -19,7 +19,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(Claude::SONNET_37); +$model = Claude::create(Claude::SONNET_37); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/anthropic/stream.php b/examples/anthropic/stream.php index 69373d53d..f55eea34c 100644 --- a/examples/anthropic/stream.php +++ b/examples/anthropic/stream.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(); +$model = Claude::create(); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/anthropic/toolcall.php b/examples/anthropic/toolcall.php index 926c05767..c7b0a673c 100644 --- a/examples/anthropic/toolcall.php +++ b/examples/anthropic/toolcall.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), httpClient: http_client()); -$model = new Claude(); +$model = Claude::create(); $wikipedia = new Wikipedia(http_client()); $toolbox = new Toolbox([$wikipedia], logger: logger()); diff --git a/examples/azure/audio-transcript.php b/examples/azure/audio-transcript.php index e4ffea49e..30b566201 100644 --- a/examples/azure/audio-transcript.php +++ b/examples/azure/audio-transcript.php @@ -22,7 +22,7 @@ env('AZURE_OPENAI_KEY'), http_client(), ); -$model = new Whisper(); +$model = Whisper::create(); $file = Audio::fromFile(dirname(__DIR__, 2).'/fixtures/audio.mp3'); $result = $platform->invoke($model, $file); diff --git a/examples/azure/chat-gpt.php b/examples/azure/chat-gpt.php index 114c54922..74ce8398d 100644 --- a/examples/azure/chat-gpt.php +++ b/examples/azure/chat-gpt.php @@ -24,7 +24,7 @@ env('AZURE_OPENAI_KEY'), http_client(), ); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/azure/chat-llama.php b/examples/azure/chat-llama.php index 011abdbcb..f37bdb2bc 100644 --- a/examples/azure/chat-llama.php +++ b/examples/azure/chat-llama.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('AZURE_LLAMA_BASEURL'), env('AZURE_LLAMA_KEY'), http_client()); -$model = new Llama(Llama::V3_3_70B_INSTRUCT); +$model = Llama::create(Llama::V3_3_70B_INSTRUCT); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag(Message::ofUser('I am going to Paris, what should I see?')); diff --git a/examples/azure/embeddings.php b/examples/azure/embeddings.php index f87aaaf99..734642a46 100644 --- a/examples/azure/embeddings.php +++ b/examples/azure/embeddings.php @@ -21,7 +21,7 @@ env('AZURE_OPENAI_KEY'), http_client(), ); -$embeddings = new Embeddings(); +$embeddings = Embeddings::create(); $result = $platform->invoke($embeddings, <<invoke($embeddings, << ['url_context' => true], 'temperature' => 1.0]); +$llm = Gemini::create('gemini-2.5-pro-preview-03-25', options: ['server_tools' => ['url_context' => true], 'temperature' => 1.0]); $toolbox = new Toolbox([new Clock()], logger: logger()); $processor = new AgentProcessor($toolbox); diff --git a/examples/gemini/stream.php b/examples/gemini/stream.php index 5e29174da..90eb09e6f 100644 --- a/examples/gemini/stream.php +++ b/examples/gemini/stream.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('GEMINI_API_KEY'), http_client()); -$model = new Gemini(Gemini::GEMINI_2_FLASH); +$model = Gemini::create(Gemini::GEMINI_2_FLASH); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/gemini/structured-output-clock.php b/examples/gemini/structured-output-clock.php index cc6b1e717..5bfad559f 100644 --- a/examples/gemini/structured-output-clock.php +++ b/examples/gemini/structured-output-clock.php @@ -23,7 +23,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('GEMINI_API_KEY'), http_client()); -$model = new Gemini(Gemini::GEMINI_1_5_FLASH); +$model = Gemini::create(Gemini::GEMINI_1_5_FLASH); $clock = new Clock(new SymfonyClock()); $toolbox = new Toolbox([$clock]); diff --git a/examples/gemini/structured-output-math.php b/examples/gemini/structured-output-math.php index 549b4ce24..adc5eb91d 100644 --- a/examples/gemini/structured-output-math.php +++ b/examples/gemini/structured-output-math.php @@ -20,7 +20,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('GEMINI_API_KEY'), http_client()); -$model = new Gemini(Gemini::GEMINI_1_5_FLASH); +$model = Gemini::create(Gemini::GEMINI_1_5_FLASH); $processor = new AgentProcessor(); $agent = new Agent($platform, $model, [$processor], [$processor], logger()); diff --git a/examples/gemini/toolcall.php b/examples/gemini/toolcall.php index e9355312d..5d6033a8e 100644 --- a/examples/gemini/toolcall.php +++ b/examples/gemini/toolcall.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('GEMINI_API_KEY'), http_client()); -$llm = new Gemini(Gemini::GEMINI_2_FLASH); +$llm = Gemini::create(Gemini::GEMINI_2_FLASH); $toolbox = new Toolbox([new Clock()], logger: logger()); $processor = new AgentProcessor($toolbox); diff --git a/examples/lmstudio/chat.php b/examples/lmstudio/chat.php index 76532da06..9e8218d50 100644 --- a/examples/lmstudio/chat.php +++ b/examples/lmstudio/chat.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('LMSTUDIO_HOST_URL'), http_client()); -$model = new Completions('gemma-3-4b-it-qat'); +$model = Completions::create('gemma-3-4b-it-qat'); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/lmstudio/image-input-binary.php b/examples/lmstudio/image-input-binary.php index fa52bf885..2b1dd610d 100644 --- a/examples/lmstudio/image-input-binary.php +++ b/examples/lmstudio/image-input-binary.php @@ -20,7 +20,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('LMSTUDIO_HOST_URL'), http_client()); -$model = new Completions( +$model = Completions::create( name: 'gemma-3-4b-it-qat', capabilities: [...Completions::DEFAULT_CAPABILITIES, Capability::INPUT_IMAGE] ); diff --git a/examples/memory/mariadb.php b/examples/memory/mariadb.php index b49ddb277..920b493fa 100644 --- a/examples/memory/mariadb.php +++ b/examples/memory/mariadb.php @@ -58,7 +58,7 @@ // create embeddings for documents as preparation of the chain memory $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); @@ -66,7 +66,7 @@ $embeddingsMemory = new EmbeddingProvider($platform, $embeddings, $store); $memoryProcessor = new MemoryInputProcessor($embeddingsMemory); -$agent = new Agent($platform, new Gpt(Gpt::GPT_4O_MINI), [$memoryProcessor], logger: logger()); +$agent = new Agent($platform, Gpt::create(Gpt::GPT_4O_MINI), [$memoryProcessor], logger: logger()); $messages = new MessageBag(Message::ofUser('Have we discussed about my friend John in the past? If yes, what did we talk about?')); $result = $agent->call($messages); diff --git a/examples/memory/static.php b/examples/memory/static.php index 8d717080d..50fe8f808 100644 --- a/examples/memory/static.php +++ b/examples/memory/static.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create($_ENV['OPENAI_API_KEY'], http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $systemPromptProcessor = new SystemPromptInputProcessor('You are a professional trainer with short, personalized advice and a motivating claim.'); diff --git a/examples/misc/chat-system-prompt.php b/examples/misc/chat-system-prompt.php index 832637ec4..1e35283e0 100644 --- a/examples/misc/chat-system-prompt.php +++ b/examples/misc/chat-system-prompt.php @@ -19,7 +19,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $processor = new SystemPromptInputProcessor('You are Yoda and write like he speaks. But short.'); diff --git a/examples/misc/parallel-chat-gpt.php b/examples/misc/parallel-chat-gpt.php index 0c4b40aca..441fbd09a 100644 --- a/examples/misc/parallel-chat-gpt.php +++ b/examples/misc/parallel-chat-gpt.php @@ -17,7 +17,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI, [ +$model = Gpt::create(Gpt::GPT_4O_MINI, [ 'temperature' => 0.5, // default options for the model ]); diff --git a/examples/misc/parallel-embeddings.php b/examples/misc/parallel-embeddings.php index 7c14ca28e..a6ed141e4 100644 --- a/examples/misc/parallel-embeddings.php +++ b/examples/misc/parallel-embeddings.php @@ -15,9 +15,9 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$ada = new Embeddings(Embeddings::TEXT_ADA_002); -$small = new Embeddings(Embeddings::TEXT_3_SMALL); -$large = new Embeddings(Embeddings::TEXT_3_LARGE); +$ada = Embeddings::create(Embeddings::TEXT_ADA_002); +$small = Embeddings::create(Embeddings::TEXT_3_SMALL); +$large = Embeddings::create(Embeddings::TEXT_3_LARGE); echo 'Initiating parallel embeddings calls to platform ...'.\PHP_EOL; $results = []; diff --git a/examples/misc/persistent-chat.php b/examples/misc/persistent-chat.php index 8b9df26fa..1a416370b 100644 --- a/examples/misc/persistent-chat.php +++ b/examples/misc/persistent-chat.php @@ -20,7 +20,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$llm = new Gpt(Gpt::GPT_4O_MINI); +$llm = Gpt::create(Gpt::GPT_4O_MINI); $agent = new Agent($platform, $llm, logger: logger()); $chat = new Chat($agent, new InMemoryStore()); diff --git a/examples/mistral/chat-multiple.php b/examples/mistral/chat-multiple.php index 8e9281bdf..971dbe39e 100644 --- a/examples/mistral/chat-multiple.php +++ b/examples/mistral/chat-multiple.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('MISTRAL_API_KEY'), http_client()); -$agent = new Agent($platform, new Mistral(), logger: logger()); +$agent = new Agent($platform, Mistral::create(), logger: logger()); $messages = new MessageBag( Message::forSystem('Just give short answers.'), diff --git a/examples/mistral/chat.php b/examples/mistral/chat.php index cf11f10da..27417dedb 100644 --- a/examples/mistral/chat.php +++ b/examples/mistral/chat.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('MISTRAL_API_KEY'), http_client()); -$model = new Mistral(); +$model = Mistral::create(); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag(Message::ofUser('What is the best French cheese?')); diff --git a/examples/mistral/embeddings.php b/examples/mistral/embeddings.php index 2e8207436..1168c89c3 100644 --- a/examples/mistral/embeddings.php +++ b/examples/mistral/embeddings.php @@ -15,7 +15,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('MISTRAL_API_KEY'), http_client()); -$model = new Embeddings(); +$model = Embeddings::create(); $result = $platform->invoke($model, <<invoke(new Ollama(Ollama::NOMIC_EMBED_TEXT), <<invoke(Ollama::create(Ollama::NOMIC_EMBED_TEXT), <<invoke($model, $file); diff --git a/examples/openai/chat-o1.php b/examples/openai/chat-o1.php index be420b402..b47e2d52c 100644 --- a/examples/openai/chat-o1.php +++ b/examples/openai/chat-o1.php @@ -23,7 +23,7 @@ } $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::O1_PREVIEW); +$model = Gpt::create(Gpt::O1_PREVIEW); $prompt = << 0.5, // default options for the model ]); diff --git a/examples/openai/embeddings.php b/examples/openai/embeddings.php index 5911933fb..6d0d64c7b 100644 --- a/examples/openai/embeddings.php +++ b/examples/openai/embeddings.php @@ -15,7 +15,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$embeddings = new Embeddings(); +$embeddings = Embeddings::create(); $result = $platform->invoke($embeddings, <<invoke( - model: new DallE(), // Utilize Dall-E 2 version in default + model: DallE::create(), // Utilize Dall-E 2 version in default input: 'A cartoon-style elephant with a long trunk and large ears.', options: [ 'response_format' => 'url', // Generate response as URL diff --git a/examples/openai/image-output-dall-e-3.php b/examples/openai/image-output-dall-e-3.php index 0898dc83e..2af890335 100644 --- a/examples/openai/image-output-dall-e-3.php +++ b/examples/openai/image-output-dall-e-3.php @@ -18,7 +18,7 @@ $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); $result = $platform->invoke( - model: new DallE(name: DallE::DALL_E_3), + model: DallE::create(name: DallE::DALL_E_3), input: 'A cartoon-style elephant with a long trunk and large ears.', options: [ 'response_format' => 'url', // Generate response as URL diff --git a/examples/openai/stream.php b/examples/openai/stream.php index 62752e29a..bc8fc9e03 100644 --- a/examples/openai/stream.php +++ b/examples/openai/stream.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/openai/structured-output-clock.php b/examples/openai/structured-output-clock.php index 7fe092deb..2cf652c76 100644 --- a/examples/openai/structured-output-clock.php +++ b/examples/openai/structured-output-clock.php @@ -23,7 +23,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $clock = new Clock(new SymfonyClock()); $toolbox = new Toolbox([$clock], logger: logger()); diff --git a/examples/openai/structured-output-math.php b/examples/openai/structured-output-math.php index a05cce0ce..69d58b0cc 100644 --- a/examples/openai/structured-output-math.php +++ b/examples/openai/structured-output-math.php @@ -20,7 +20,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $processor = new AgentProcessor(); $agent = new Agent($platform, $model, [$processor], [$processor], logger()); diff --git a/examples/openai/token-metadata.php b/examples/openai/token-metadata.php index d3e32c00e..c95c70f9e 100644 --- a/examples/openai/token-metadata.php +++ b/examples/openai/token-metadata.php @@ -19,7 +19,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI, [ +$model = Gpt::create(Gpt::GPT_4O_MINI, [ 'temperature' => 0.5, // default options for the model ]); diff --git a/examples/openai/toolcall-stream.php b/examples/openai/toolcall-stream.php index d5e8d0f41..34ffe313f 100644 --- a/examples/openai/toolcall-stream.php +++ b/examples/openai/toolcall-stream.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $wikipedia = new Wikipedia(http_client()); $toolbox = new Toolbox([$wikipedia], logger: logger()); diff --git a/examples/openai/toolcall.php b/examples/openai/toolcall.php index 3d31fc5d2..512d9128a 100644 --- a/examples/openai/toolcall.php +++ b/examples/openai/toolcall.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $transcriber = new YouTubeTranscriber(http_client()); $toolbox = new Toolbox([$transcriber], logger: logger()); diff --git a/examples/rag/cache.php b/examples/rag/cache.php index 46d3d704c..62077ea5c 100644 --- a/examples/rag/cache.php +++ b/examples/rag/cache.php @@ -43,11 +43,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/in-memory.php b/examples/rag/in-memory.php index 536aa1b5c..0f4a06b1b 100644 --- a/examples/rag/in-memory.php +++ b/examples/rag/in-memory.php @@ -42,11 +42,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/mariadb-gemini.php b/examples/rag/mariadb-gemini.php index 6d72fec62..754e22938 100644 --- a/examples/rag/mariadb-gemini.php +++ b/examples/rag/mariadb-gemini.php @@ -52,12 +52,12 @@ // create embeddings for documents $platform = PlatformFactory::create(env('GEMINI_API_KEY'), http_client()); -$embeddings = new Embeddings(options: ['dimensions' => 768, 'task_type' => TaskType::SemanticSimilarity]); +$embeddings = Embeddings::create(options: ['dimensions' => 768, 'task_type' => TaskType::SemanticSimilarity]); $vectorizer = new Vectorizer($platform, $embeddings); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gemini(Gemini::GEMINI_2_FLASH_LITE); +$model = Gemini::create(Gemini::GEMINI_2_FLASH_LITE); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/mariadb-openai.php b/examples/rag/mariadb-openai.php index 110a76d2d..221eb8d7a 100644 --- a/examples/rag/mariadb-openai.php +++ b/examples/rag/mariadb-openai.php @@ -51,11 +51,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/meilisearch.php b/examples/rag/meilisearch.php index 588beb993..a7615d663 100644 --- a/examples/rag/meilisearch.php +++ b/examples/rag/meilisearch.php @@ -52,11 +52,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/mongodb.php b/examples/rag/mongodb.php index 7df292134..9464e0449 100644 --- a/examples/rag/mongodb.php +++ b/examples/rag/mongodb.php @@ -49,14 +49,14 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY')); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); // initialize the index $store->initialize(); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/neo4j.php b/examples/rag/neo4j.php index de115447c..ed025f60a 100644 --- a/examples/rag/neo4j.php +++ b/examples/rag/neo4j.php @@ -55,11 +55,11 @@ // create embeddings for documents $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/pinecone.php b/examples/rag/pinecone.php index 43cb308f7..76f60b8f1 100644 --- a/examples/rag/pinecone.php +++ b/examples/rag/pinecone.php @@ -43,11 +43,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/postgres.php b/examples/rag/postgres.php index e64d11641..4cdcb847c 100644 --- a/examples/rag/postgres.php +++ b/examples/rag/postgres.php @@ -51,11 +51,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/qdrant.php b/examples/rag/qdrant.php index 213805021..544757ff5 100644 --- a/examples/rag/qdrant.php +++ b/examples/rag/qdrant.php @@ -51,11 +51,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/surrealdb.php b/examples/rag/surrealdb.php index 6c50873ae..2e9779ae1 100644 --- a/examples/rag/surrealdb.php +++ b/examples/rag/surrealdb.php @@ -55,11 +55,11 @@ // create embeddings for documents $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/rag/typesense.php b/examples/rag/typesense.php index f19dae60e..93a1e3193 100644 --- a/examples/rag/typesense.php +++ b/examples/rag/typesense.php @@ -51,11 +51,11 @@ // create embeddings for documents $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$vectorizer = new Vectorizer($platform, $embeddings = Embeddings::create()); $indexer = new Indexer($vectorizer, $store, logger()); $indexer->index($documents); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = new Toolbox([$similaritySearch], logger: logger()); diff --git a/examples/replicate/chat-llama.php b/examples/replicate/chat-llama.php index e1a3aaac0..3be7084d9 100644 --- a/examples/replicate/chat-llama.php +++ b/examples/replicate/chat-llama.php @@ -18,7 +18,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('REPLICATE_API_KEY'), http_client()); -$model = new Llama(); +$model = Llama::create(); $agent = new Agent($platform, $model, logger: logger()); $messages = new MessageBag( diff --git a/examples/toolbox/brave.php b/examples/toolbox/brave.php index 21672778f..0e6f60795 100644 --- a/examples/toolbox/brave.php +++ b/examples/toolbox/brave.php @@ -22,7 +22,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $brave = new Brave(http_client(), env('BRAVE_API_KEY')); $crawler = new Crawler(http_client()); diff --git a/examples/toolbox/clock.php b/examples/toolbox/clock.php index 4b12af2c7..b5eb6e022 100644 --- a/examples/toolbox/clock.php +++ b/examples/toolbox/clock.php @@ -22,7 +22,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $metadataFactory = (new MemoryToolFactory()) ->addTool(Clock::class, 'clock', 'Get the current date and time', 'now'); diff --git a/examples/toolbox/firecrawl-crawl.php b/examples/toolbox/firecrawl-crawl.php index 75a220f48..3884e0979 100644 --- a/examples/toolbox/firecrawl-crawl.php +++ b/examples/toolbox/firecrawl-crawl.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__) . '/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $firecrawl = new Firecrawl( http_client(), diff --git a/examples/toolbox/firecrawl-map.php b/examples/toolbox/firecrawl-map.php index a791e708b..120d0559f 100644 --- a/examples/toolbox/firecrawl-map.php +++ b/examples/toolbox/firecrawl-map.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__) . '/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $firecrawl = new Firecrawl( http_client(), diff --git a/examples/toolbox/firecrawl-scrape.php b/examples/toolbox/firecrawl-scrape.php index 1c2fa872c..734d20979 100644 --- a/examples/toolbox/firecrawl-scrape.php +++ b/examples/toolbox/firecrawl-scrape.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__) . '/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $firecrawl = new Firecrawl( http_client(), diff --git a/examples/toolbox/serpapi.php b/examples/toolbox/serpapi.php index d9aa65244..0e7456009 100644 --- a/examples/toolbox/serpapi.php +++ b/examples/toolbox/serpapi.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $serpApi = new SerpApi(http_client(), env('SERP_API_KEY')); $toolbox = new Toolbox([$serpApi], logger: logger()); diff --git a/examples/toolbox/tavily.php b/examples/toolbox/tavily.php index 42c2f2885..62530da4a 100644 --- a/examples/toolbox/tavily.php +++ b/examples/toolbox/tavily.php @@ -21,7 +21,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $tavily = new Tavily(http_client(), env('TAVILY_API_KEY')); $toolbox = new Toolbox([$tavily], logger: logger()); diff --git a/examples/toolbox/weather-event.php b/examples/toolbox/weather-event.php index e7efa7a14..5ab79ae25 100644 --- a/examples/toolbox/weather-event.php +++ b/examples/toolbox/weather-event.php @@ -24,7 +24,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client()); -$model = new Gpt(Gpt::GPT_4O_MINI); +$model = Gpt::create(Gpt::GPT_4O_MINI); $openMeteo = new OpenMeteo(http_client()); $toolbox = new Toolbox([$openMeteo], logger: logger()); diff --git a/examples/voyage/embeddings.php b/examples/voyage/embeddings.php index d5720bf92..8b1ab80f7 100644 --- a/examples/voyage/embeddings.php +++ b/examples/voyage/embeddings.php @@ -15,7 +15,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; $platform = PlatformFactory::create(env('VOYAGE_API_KEY'), http_client()); -$embeddings = new Voyage(); +$embeddings = Voyage::create(); $result = $platform->invoke($embeddings, << $claude]); $processor = new ModelOverrideInputProcessor(); @@ -46,7 +46,7 @@ public function testProcessInputWithValidModelOption() public function testProcessInputWithoutModelOption() { - $gpt = new Gpt(); + $gpt = Gpt::create(); $input = new Input($gpt, new MessageBag(), []); $processor = new ModelOverrideInputProcessor(); @@ -60,7 +60,7 @@ public function testProcessInputWithInvalidModelOption() $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Option "model" must be an instance of "Symfony\AI\Platform\Model".'); - $gpt = new Gpt(); + $gpt = Gpt::create(); $model = new MessageBag(); $input = new Input($gpt, new MessageBag(), ['model' => $model]); diff --git a/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php b/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php index 23059442e..069aebf91 100644 --- a/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php +++ b/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php @@ -47,7 +47,7 @@ public function testProcessInputAddsSystemMessageWhenNoneExists() { $processor = new SystemPromptInputProcessor('This is a system prompt'); - $input = new Input(new Gpt(), new MessageBag(Message::ofUser('This is a user message')), []); + $input = new Input(Gpt::create(), new MessageBag(Message::ofUser('This is a user message')), []); $processor->processInput($input); $messages = $input->messages->getMessages(); @@ -65,7 +65,7 @@ public function testProcessInputDoesNotAddSystemMessageWhenOneExists() Message::forSystem('This is already a system prompt'), Message::ofUser('This is a user message'), ); - $input = new Input(new Gpt(), $messages, []); + $input = new Input(Gpt::create(), $messages, []); $processor->processInput($input); $messages = $input->messages->getMessages(); @@ -92,7 +92,7 @@ public function execute(ToolCall $toolCall): mixed } ); - $input = new Input(new Gpt(), new MessageBag(Message::ofUser('This is a user message')), []); + $input = new Input(Gpt::create(), new MessageBag(Message::ofUser('This is a user message')), []); $processor->processInput($input); $messages = $input->messages->getMessages(); @@ -130,7 +130,7 @@ public function execute(ToolCall $toolCall): mixed } ); - $input = new Input(new Gpt(), new MessageBag(Message::ofUser('This is a user message')), []); + $input = new Input(Gpt::create(), new MessageBag(Message::ofUser('This is a user message')), []); $processor->processInput($input); $messages = $input->messages->getMessages(); @@ -170,7 +170,7 @@ public function execute(ToolCall $toolCall): mixed } ); - $input = new Input(new Gpt(), new MessageBag(Message::ofUser('This is a user message')), []); + $input = new Input(Gpt::create(), new MessageBag(Message::ofUser('This is a user message')), []); $processor->processInput($input); $messages = $input->messages->getMessages(); diff --git a/src/ai-bundle/tests/DependencyInjection/AiBundleTest.php b/src/ai-bundle/tests/DependencyInjection/AiBundleTest.php index ba0b1993f..4a4beb859 100644 --- a/src/ai-bundle/tests/DependencyInjection/AiBundleTest.php +++ b/src/ai-bundle/tests/DependencyInjection/AiBundleTest.php @@ -301,7 +301,7 @@ private function getFullConfig(): array 'store' => 'my_azure_search_store_service_id', 'platform' => 'mistral_platform_service_id', 'model' => [ - 'class' => 'Symfony\AI\Platform\Bridge\Mistral\Embeddings', + 'class' => 'Symfony\AI\Platform\Model', 'name' => 'mistral-embed', 'options' => ['dimension' => 768], ], diff --git a/src/platform/doc/gemini-server-tools.rst b/src/platform/doc/gemini-server-tools.rst index 8a606395e..8e43ca743 100644 --- a/src/platform/doc/gemini-server-tools.rst +++ b/src/platform/doc/gemini-server-tools.rst @@ -25,7 +25,7 @@ The URL Context tool allows Gemini to fetch and analyze content from web pages. :: - $model = new Gemini('gemini-2.5-pro-preview-03-25', [ + $model = Gemini::create('gemini-2.5-pro-preview-03-25', [ 'server_tools' => [ 'url_context' => true ] @@ -42,7 +42,7 @@ The URL Context tool allows Gemini to fetch and analyze content from web pages. The Google Search tool enables the model to search the web and incorporate search results into its results:: - $model = new Gemini('gemini-2.5-pro-preview-03-25', [ + $model = Gemini::create('gemini-2.5-pro-preview-03-25', [ 'server_tools' => [ 'google_search' => true ] @@ -58,7 +58,7 @@ The Google Search tool enables the model to search the web and incorporate searc The Code Execution tool provides a sandboxed environment for running code:: - $model = new Gemini('gemini-2.5-pro-preview-03-25', [ + $model = Gemini::create('gemini-2.5-pro-preview-03-25', [ 'server_tools' => [ 'code_execution' => true ] @@ -75,7 +75,7 @@ The Code Execution tool provides a sandboxed environment for running code:: You can enable multiple server tools simultaneously:: - $model = new Gemini('gemini-2.5-pro-preview-03-25', [ + $model = Gemini::create('gemini-2.5-pro-preview-03-25', [ 'server_tools' => [ 'url_context' => true, 'google_search' => true, diff --git a/src/platform/doc/index.rst b/src/platform/doc/index.rst index 98dc0fb34..c115d8f0d 100644 --- a/src/platform/doc/index.rst +++ b/src/platform/doc/index.rst @@ -36,10 +36,10 @@ For example, to use the OpenAI provider, you would typically do something like t $platform = PlatformFactory::create(env('OPENAI_API_KEY')); // Embeddings Model - $embeddings = new Embeddings(); + $embeddings = Embeddings::create(); // Language Model in version gpt-4o-mini - $model = new Gpt(Gpt::GPT_4O_MINI); + $model = Gpt::create(Gpt::GPT_4O_MINI); And with a ``Symfony\AI\Platform\PlatformInterface`` instance, and a ``Symfony\AI\Platform\Model`` instance, you can now use the platform to interact with the AI model:: @@ -246,7 +246,7 @@ The standalone usage results in an ``Vector`` instance:: // Initialize Platform - $embeddings = new Embeddings($platform, Embeddings::TEXT_3_SMALL); + $embeddings = Embeddings::create(Embeddings::TEXT_3_SMALL); $vectors = $platform->invoke($embeddings, $textInput)->asVectors(); diff --git a/src/platform/src/Bridge/Anthropic/Claude.php b/src/platform/src/Bridge/Anthropic/Claude.php index 56d0cc18c..7828bddb0 100644 --- a/src/platform/src/Bridge/Anthropic/Claude.php +++ b/src/platform/src/Bridge/Anthropic/Claude.php @@ -17,7 +17,7 @@ /** * @author Christopher Hertel */ -class Claude extends Model +final class Claude { public const HAIKU_3 = 'claude-3-haiku-20240307'; public const HAIKU_35 = 'claude-3-5-haiku-latest'; @@ -34,10 +34,10 @@ class Claude extends Model /** * @param array $options The default options for the model usage */ - public function __construct( + public static function create( string $name = self::SONNET_37, array $options = ['temperature' => 1.0, 'max_tokens' => 1000], - ) { + ): Model { $capabilities = [ Capability::INPUT_MESSAGES, Capability::INPUT_IMAGE, @@ -46,6 +46,6 @@ public function __construct( Capability::TOOL_CALLING, ]; - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/Bedrock/Nova/Nova.php b/src/platform/src/Bridge/Bedrock/Nova/Nova.php index 826ae533e..f31b8302c 100644 --- a/src/platform/src/Bridge/Bedrock/Nova/Nova.php +++ b/src/platform/src/Bridge/Bedrock/Nova/Nova.php @@ -17,7 +17,7 @@ /** * @author Björn Altmann */ -final class Nova extends Model +final class Nova { public const MICRO = 'nova-micro'; public const LITE = 'nova-lite'; @@ -27,10 +27,10 @@ final class Nova extends Model /** * @param array $options The default options for the model usage */ - public function __construct( + public static function create( string $name = self::PRO, array $options = ['temperature' => 1.0, 'max_tokens' => 1000], - ) { + ): Model { $capabilities = [ Capability::INPUT_MESSAGES, Capability::OUTPUT_TEXT, @@ -41,6 +41,6 @@ public function __construct( $capabilities[] = Capability::INPUT_IMAGE; } - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/Cerebras/Model.php b/src/platform/src/Bridge/Cerebras/Model.php index 3df43a82f..b2fcfb910 100644 --- a/src/platform/src/Bridge/Cerebras/Model.php +++ b/src/platform/src/Bridge/Cerebras/Model.php @@ -8,7 +8,7 @@ /** * @author Junaid Farooq */ -final class Model extends BaseModel +final class Model { public const LLAMA_4_SCOUT_17B_16E_INSTRUCT = 'llama-4-scout-17b-16e-instruct'; public const LLAMA3_1_8B = 'llama3.1-8b'; @@ -29,11 +29,11 @@ final class Model extends BaseModel /** * @see https://inference-docs.cerebras.ai/api-reference/chat-completions for details like options */ - public function __construct( + public static function create( string $name = self::LLAMA3_1_8B, array $capabilities = self::CAPABILITIES, array $options = [], - ) { - parent::__construct($name, $capabilities, $options); + ): BaseModel { + return new BaseModel($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/Gemini/Embeddings.php b/src/platform/src/Bridge/Gemini/Embeddings.php index 17fcafd00..856cc3fd6 100644 --- a/src/platform/src/Bridge/Gemini/Embeddings.php +++ b/src/platform/src/Bridge/Gemini/Embeddings.php @@ -18,7 +18,7 @@ /** * @author Valtteri R */ -class Embeddings extends Model +final class Embeddings { /** Supported dimensions: 3072, 1536, or 768 */ public const GEMINI_EMBEDDING_EXP_03_07 = 'gemini-embedding-exp-03-07'; @@ -30,8 +30,8 @@ class Embeddings extends Model /** * @param array{dimensions?: int, task_type?: TaskType|string} $options */ - public function __construct(string $name = self::GEMINI_EMBEDDING_EXP_03_07, array $options = []) + public static function create(string $name = self::GEMINI_EMBEDDING_EXP_03_07, array $options = []): Model { - parent::__construct($name, [Capability::INPUT_MULTIPLE], $options); + return new Model($name, [Capability::INPUT_MULTIPLE], $options); } } diff --git a/src/platform/src/Bridge/Gemini/Gemini.php b/src/platform/src/Bridge/Gemini/Gemini.php index b2c4b00b2..f4a0bfe8b 100644 --- a/src/platform/src/Bridge/Gemini/Gemini.php +++ b/src/platform/src/Bridge/Gemini/Gemini.php @@ -17,7 +17,7 @@ /** * @author Roy Garrido */ -class Gemini extends Model +final class Gemini { public const GEMINI_2_FLASH = 'gemini-2.0-flash'; public const GEMINI_2_PRO = 'gemini-2.0-pro-exp-02-05'; @@ -28,7 +28,7 @@ class Gemini extends Model /** * @param array $options The default options for the model usage */ - public function __construct(string $name = self::GEMINI_2_PRO, array $options = ['temperature' => 1.0]) + public static function create(string $name = self::GEMINI_2_PRO, array $options = ['temperature' => 1.0]): Model { $capabilities = [ Capability::INPUT_MESSAGES, @@ -40,6 +40,6 @@ public function __construct(string $name = self::GEMINI_2_PRO, array $options = Capability::TOOL_CALLING, ]; - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/LmStudio/Completions.php b/src/platform/src/Bridge/LmStudio/Completions.php index 361ca412d..61fb8744b 100644 --- a/src/platform/src/Bridge/LmStudio/Completions.php +++ b/src/platform/src/Bridge/LmStudio/Completions.php @@ -17,7 +17,7 @@ /** * @author André Lubian */ -class Completions extends Model +final class Completions { public const DEFAULT_CAPABILITIES = [ Capability::INPUT_MESSAGES, @@ -25,11 +25,11 @@ class Completions extends Model Capability::OUTPUT_STREAMING, ]; - public function __construct( + public static function create( string $name, array $options = ['temperature' => 0.7], array $capabilities = self::DEFAULT_CAPABILITIES, - ) { - parent::__construct($name, $capabilities, $options); + ): Model { + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/LmStudio/Embeddings.php b/src/platform/src/Bridge/LmStudio/Embeddings.php index 7d899c215..af570202a 100644 --- a/src/platform/src/Bridge/LmStudio/Embeddings.php +++ b/src/platform/src/Bridge/LmStudio/Embeddings.php @@ -16,6 +16,10 @@ /** * @author André Lubian */ -class Embeddings extends Model +final class Embeddings { + public static function create(string $name, array $capabilities = [], array $options = []): Model + { + return new Model($name, $capabilities, $options); + } } diff --git a/src/platform/src/Bridge/Meta/Llama.php b/src/platform/src/Bridge/Meta/Llama.php index d6d50e9e0..745cfe8af 100644 --- a/src/platform/src/Bridge/Meta/Llama.php +++ b/src/platform/src/Bridge/Meta/Llama.php @@ -17,7 +17,7 @@ /** * @author Christopher Hertel */ -class Llama extends Model +final class Llama { public const V3_3_70B_INSTRUCT = 'llama-3.3-70B-Instruct'; public const V3_2_90B_VISION_INSTRUCT = 'llama-3.2-90b-vision-instruct'; @@ -38,13 +38,13 @@ class Llama extends Model /** * @param array $options */ - public function __construct(string $name = self::V3_1_405B_INSTRUCT, array $options = []) + public static function create(string $name = self::V3_1_405B_INSTRUCT, array $options = []): Model { $capabilities = [ Capability::INPUT_MESSAGES, Capability::OUTPUT_TEXT, ]; - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/Mistral/Embeddings.php b/src/platform/src/Bridge/Mistral/Embeddings.php index 6f96f5f48..ad70e08fc 100644 --- a/src/platform/src/Bridge/Mistral/Embeddings.php +++ b/src/platform/src/Bridge/Mistral/Embeddings.php @@ -17,17 +17,17 @@ /** * @author Christopher Hertel */ -final class Embeddings extends Model +final class Embeddings { public const MISTRAL_EMBED = 'mistral-embed'; /** * @param array $options */ - public function __construct( + public static function create( string $name = self::MISTRAL_EMBED, array $options = [], - ) { - parent::__construct($name, [Capability::INPUT_MULTIPLE], $options); + ): Model { + return new Model($name, [Capability::INPUT_MULTIPLE], $options); } } diff --git a/src/platform/src/Bridge/Mistral/Mistral.php b/src/platform/src/Bridge/Mistral/Mistral.php index 62fec67e4..1365c332c 100644 --- a/src/platform/src/Bridge/Mistral/Mistral.php +++ b/src/platform/src/Bridge/Mistral/Mistral.php @@ -17,7 +17,7 @@ /** * @author Christopher Hertel */ -final class Mistral extends Model +final class Mistral { public const CODESTRAL = 'codestral-latest'; public const CODESTRAL_MAMBA = 'open-codestral-mamba'; @@ -33,10 +33,10 @@ final class Mistral extends Model /** * @param array $options */ - public function __construct( + public static function create( string $name = self::MISTRAL_LARGE, array $options = [], - ) { + ): Model { $capabilities = [ Capability::INPUT_MESSAGES, Capability::OUTPUT_TEXT, @@ -61,6 +61,6 @@ public function __construct( $capabilities[] = Capability::TOOL_CALLING; } - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/Ollama/Ollama.php b/src/platform/src/Bridge/Ollama/Ollama.php index cca4c464e..a4f7ebafb 100644 --- a/src/platform/src/Bridge/Ollama/Ollama.php +++ b/src/platform/src/Bridge/Ollama/Ollama.php @@ -17,7 +17,7 @@ /** * @author Joshua Behrens */ -class Ollama extends Model +final class Ollama { public const DEEPSEEK_R_1 = 'deepseek-r1'; public const GEMMA_3_N = 'gemma3n'; @@ -63,7 +63,7 @@ class Ollama extends Model /** * @param array $options */ - public function __construct(string $name = self::LLAMA_3_2, array $options = []) + public static function create(string $name = self::LLAMA_3_2, array $options = []): Model { $capabilities = []; @@ -75,6 +75,6 @@ public function __construct(string $name = self::LLAMA_3_2, array $options = []) } } - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/OpenAi/DallE.php b/src/platform/src/Bridge/OpenAi/DallE.php index 40b071cf4..30ee1cfa4 100644 --- a/src/platform/src/Bridge/OpenAi/DallE.php +++ b/src/platform/src/Bridge/OpenAi/DallE.php @@ -17,19 +17,21 @@ /** * @author Denis Zunke */ -class DallE extends Model +final class DallE { public const DALL_E_2 = 'dall-e-2'; public const DALL_E_3 = 'dall-e-3'; - /** @param array $options The default options for the model usage */ - public function __construct(string $name = self::DALL_E_2, array $options = []) + /** + * @param array $options The default options for the model usage + */ + public static function create(string $name = self::DALL_E_2, array $options = []): Model { $capabilities = [ Capability::INPUT_TEXT, Capability::OUTPUT_IMAGE, ]; - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/OpenAi/Embeddings.php b/src/platform/src/Bridge/OpenAi/Embeddings.php index 80472e8e2..4cc45cf0b 100644 --- a/src/platform/src/Bridge/OpenAi/Embeddings.php +++ b/src/platform/src/Bridge/OpenAi/Embeddings.php @@ -16,7 +16,7 @@ /** * @author Christopher Hertel */ -class Embeddings extends Model +final class Embeddings { public const TEXT_ADA_002 = 'text-embedding-ada-002'; public const TEXT_3_LARGE = 'text-embedding-3-large'; @@ -25,8 +25,8 @@ class Embeddings extends Model /** * @param array $options */ - public function __construct(string $name = self::TEXT_3_SMALL, array $options = []) + public static function create(string $name = self::TEXT_3_SMALL, array $options = []): Model { - parent::__construct($name, [], $options); + return new Model($name, [], $options); } } diff --git a/src/platform/src/Bridge/OpenAi/Gpt.php b/src/platform/src/Bridge/OpenAi/Gpt.php index 4251ccbce..e0a1b6e0c 100644 --- a/src/platform/src/Bridge/OpenAi/Gpt.php +++ b/src/platform/src/Bridge/OpenAi/Gpt.php @@ -18,7 +18,7 @@ * @author Christopher Hertel * @author Oskar Stark */ -class Gpt extends Model +final class Gpt { public const GPT_35_TURBO = 'gpt-3.5-turbo'; public const GPT_35_TURBO_INSTRUCT = 'gpt-3.5-turbo-instruct'; @@ -62,10 +62,10 @@ class Gpt extends Model /** * @param array $options The default options for the model usage */ - public function __construct( + public static function create( string $name = self::GPT_4O, array $options = ['temperature' => 1.0], - ) { + ): Model { $capabilities = [ Capability::INPUT_MESSAGES, Capability::OUTPUT_TEXT, @@ -85,6 +85,6 @@ public function __construct( $capabilities[] = Capability::OUTPUT_STRUCTURED; } - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/OpenAi/Whisper.php b/src/platform/src/Bridge/OpenAi/Whisper.php index 24e8ffe10..3ec65d7be 100644 --- a/src/platform/src/Bridge/OpenAi/Whisper.php +++ b/src/platform/src/Bridge/OpenAi/Whisper.php @@ -17,20 +17,20 @@ /** * @author Christopher Hertel */ -class Whisper extends Model +final class Whisper { public const WHISPER_1 = 'whisper-1'; /** * @param array $options */ - public function __construct(string $name = self::WHISPER_1, array $options = []) + public static function create(string $name = self::WHISPER_1, array $options = []): Model { $capabilities = [ Capability::INPUT_AUDIO, Capability::OUTPUT_TEXT, ]; - parent::__construct($name, $capabilities, $options); + return new Model($name, $capabilities, $options); } } diff --git a/src/platform/src/Bridge/Voyage/Voyage.php b/src/platform/src/Bridge/Voyage/Voyage.php index 955748499..2a21ef85e 100644 --- a/src/platform/src/Bridge/Voyage/Voyage.php +++ b/src/platform/src/Bridge/Voyage/Voyage.php @@ -17,7 +17,7 @@ /** * @author Christopher Hertel */ -class Voyage extends Model +final class Voyage { public const V3 = 'voyage-3'; public const V3_LITE = 'voyage-3-lite'; @@ -29,8 +29,8 @@ class Voyage extends Model /** * @param array $options */ - public function __construct(string $name = self::V3, array $options = []) + public static function create(string $name = self::V3, array $options = []): Model { - parent::__construct($name, [Capability::INPUT_MULTIPLE], $options); + return new Model($name, [Capability::INPUT_MULTIPLE], $options); } } diff --git a/src/platform/src/Model.php b/src/platform/src/Model.php index 6594b972b..5d335dccb 100644 --- a/src/platform/src/Model.php +++ b/src/platform/src/Model.php @@ -14,7 +14,7 @@ /** * @author Christopher Hertel */ -class Model +final class Model { /** * @param Capability[] $capabilities diff --git a/src/platform/tests/Bridge/Albert/EmbeddingsModelClientTest.php b/src/platform/tests/Bridge/Albert/EmbeddingsModelClientTest.php index a915a7c8a..ac21d52c4 100644 --- a/src/platform/tests/Bridge/Albert/EmbeddingsModelClientTest.php +++ b/src/platform/tests/Bridge/Albert/EmbeddingsModelClientTest.php @@ -58,7 +58,7 @@ public function testSupportsEmbeddingsModel() 'https://albert.example.com/' ); - $embeddingsModel = new Embeddings('text-embedding-ada-002'); + $embeddingsModel = Embeddings::create('text-embedding-ada-002'); $this->assertTrue($client->supports($embeddingsModel)); } @@ -70,7 +70,7 @@ public function testDoesNotSupportNonEmbeddingsModel() 'https://albert.example.com/' ); - $gptModel = new Gpt('gpt-3.5-turbo'); + $gptModel = Gpt::create('gpt-3.5-turbo'); $this->assertFalse($client->supports($gptModel)); } @@ -90,7 +90,7 @@ public function testRequestSendsCorrectHttpRequest(array|string $payload, array 'https://albert.example.com/v1' ); - $model = new Embeddings('text-embedding-ada-002'); + $model = Embeddings::create('text-embedding-ada-002'); $result = $client->request($model, $payload, $options); $this->assertNotNull($capturedRequest); @@ -151,7 +151,7 @@ public function testRequestHandlesBaseUrlWithoutTrailingSlash() 'https://albert.example.com/v1' ); - $model = new Embeddings('text-embedding-ada-002'); + $model = Embeddings::create('text-embedding-ada-002'); $client->request($model, ['input' => 'test']); $this->assertSame('https://albert.example.com/v1/embeddings', $capturedUrl); @@ -172,7 +172,7 @@ public function testRequestHandlesBaseUrlWithTrailingSlash() 'https://albert.example.com/v1' ); - $model = new Embeddings('text-embedding-ada-002'); + $model = Embeddings::create('text-embedding-ada-002'); $client->request($model, ['input' => 'test']); $this->assertSame('https://albert.example.com/v1/embeddings', $capturedUrl); diff --git a/src/platform/tests/Bridge/Albert/GptModelClientTest.php b/src/platform/tests/Bridge/Albert/GptModelClientTest.php index 06c18a341..84d0ef4a9 100644 --- a/src/platform/tests/Bridge/Albert/GptModelClientTest.php +++ b/src/platform/tests/Bridge/Albert/GptModelClientTest.php @@ -68,7 +68,7 @@ public function testConstructorWrapsHttpClientInEventSourceHttpClient() $mockResponse = new JsonMockResponse(['choices' => []]); $mockHttpClient->setResponseFactory([$mockResponse]); - $model = new Gpt('gpt-3.5-turbo'); + $model = Gpt::create('gpt-3.5-turbo'); $client->request($model, ['messages' => []]); } @@ -89,7 +89,7 @@ public function testConstructorAcceptsEventSourceHttpClient() $mockResponse = new JsonMockResponse(['choices' => []]); $mockHttpClient->setResponseFactory([$mockResponse]); - $model = new Gpt('gpt-3.5-turbo'); + $model = Gpt::create('gpt-3.5-turbo'); $client->request($model, ['messages' => []]); } @@ -101,7 +101,7 @@ public function testSupportsGptModel() 'https://albert.example.com/' ); - $gptModel = new Gpt('gpt-3.5-turbo'); + $gptModel = Gpt::create('gpt-3.5-turbo'); $this->assertTrue($client->supports($gptModel)); } @@ -113,7 +113,7 @@ public function testDoesNotSupportNonGptModel() 'https://albert.example.com/' ); - $embeddingsModel = new Embeddings('text-embedding-ada-002'); + $embeddingsModel = Embeddings::create('text-embedding-ada-002'); $this->assertFalse($client->supports($embeddingsModel)); } @@ -133,7 +133,7 @@ public function testRequestSendsCorrectHttpRequest(array|string $payload, array 'https://albert.example.com/v1' ); - $model = new Gpt('gpt-3.5-turbo'); + $model = Gpt::create('gpt-3.5-turbo'); $result = $client->request($model, $payload, $options); $this->assertNotNull($capturedRequest); @@ -200,7 +200,7 @@ public function testRequestHandlesBaseUrlWithoutTrailingSlash() 'https://albert.example.com/v1' ); - $model = new Gpt('gpt-3.5-turbo'); + $model = Gpt::create('gpt-3.5-turbo'); $client->request($model, ['messages' => []]); $this->assertSame('https://albert.example.com/v1/chat/completions', $capturedUrl); @@ -221,7 +221,7 @@ public function testRequestHandlesBaseUrlWithTrailingSlash() 'https://albert.example.com/v1' ); - $model = new Gpt('gpt-3.5-turbo'); + $model = Gpt::create('gpt-3.5-turbo'); $client->request($model, ['messages' => []]); $this->assertSame('https://albert.example.com/v1/chat/completions', $capturedUrl); diff --git a/src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php b/src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php index f3cbc4f4c..6c18e08ad 100644 --- a/src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php +++ b/src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php @@ -77,7 +77,7 @@ public function testItIsSupportingTheCorrectModel() { $client = new EmbeddingsModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '2023-12-01', 'api-key'); - $this->assertTrue($client->supports(new Embeddings())); + $this->assertTrue($client->supports(Embeddings::create())); } public function testItIsExecutingTheCorrectRequest() @@ -93,6 +93,6 @@ public function testItIsExecutingTheCorrectRequest() $httpClient = new MockHttpClient([$resultCallback]); $client = new EmbeddingsModelClient($httpClient, 'test.azure.com', 'embeddings-deployment', '2023-12-01', 'test-api-key'); - $client->request(new Embeddings(), 'Hello, world!'); + $client->request(Embeddings::create(), 'Hello, world!'); } } diff --git a/src/platform/tests/Bridge/Azure/OpenAi/GptModelClientTest.php b/src/platform/tests/Bridge/Azure/OpenAi/GptModelClientTest.php index a51abffd8..f0d19ea88 100644 --- a/src/platform/tests/Bridge/Azure/OpenAi/GptModelClientTest.php +++ b/src/platform/tests/Bridge/Azure/OpenAi/GptModelClientTest.php @@ -77,7 +77,7 @@ public function testItIsSupportingTheCorrectModel() { $client = new GptModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '2023-12-01', 'api-key'); - $this->assertTrue($client->supports(new Gpt())); + $this->assertTrue($client->supports(Gpt::create())); } public function testItIsExecutingTheCorrectRequest() @@ -93,6 +93,6 @@ public function testItIsExecutingTheCorrectRequest() $httpClient = new MockHttpClient([$resultCallback]); $client = new GptModelClient($httpClient, 'test.azure.com', 'gpt-deployment', '2023-12-01', 'test-api-key'); - $client->request(new Gpt(), ['messages' => [['role' => 'user', 'content' => 'Hello']]]); + $client->request(Gpt::create(), ['messages' => [['role' => 'user', 'content' => 'Hello']]]); } } diff --git a/src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php b/src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php index 450d694f6..35e7cbb2c 100644 --- a/src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php +++ b/src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php @@ -78,7 +78,7 @@ public function testItSupportsWhisperModel() '2023-12-01-preview', 'test-key' ); - $model = new Whisper(); + $model = Whisper::create(); $this->assertTrue($client->supports($model)); } @@ -95,7 +95,7 @@ function ($method, $url): MockResponse { ]); $client = new WhisperModelClient($httpClient, 'test.azure.com', 'whspr', '2023-12', 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $payload = ['file' => 'audio-data']; $client->request($model, $payload); @@ -115,7 +115,7 @@ function ($method, $url): MockResponse { ]); $client = new WhisperModelClient($httpClient, 'test.azure.com', 'whspr', '2023-12', 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $payload = ['file' => 'audio-data']; $options = ['task' => Task::TRANSCRIPTION]; @@ -136,7 +136,7 @@ function ($method, $url): MockResponse { ]); $client = new WhisperModelClient($httpClient, 'test.azure.com', 'whspr', '2023-12', 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $payload = ['file' => 'audio-data']; $options = ['task' => Task::TRANSLATION]; diff --git a/src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php b/src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php index b04583e6d..1ce310d89 100644 --- a/src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php +++ b/src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php @@ -55,7 +55,7 @@ public function testConvert(MessageBag $bag, array $expected) new UserMessageNormalizer(), ); - $this->assertEquals($expected, $contract->createRequestPayload(new Nova(), $bag)); + $this->assertEquals($expected, $contract->createRequestPayload(Nova::create(), $bag)); } /** diff --git a/src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php b/src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php index 6a4940339..b3f803a05 100644 --- a/src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php +++ b/src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php @@ -36,7 +36,7 @@ public function testSupportsNormalization() $normalizer = new AssistantMessageNormalizer(); $this->assertTrue($normalizer->supportsNormalization(new AssistantMessage('Hello'), context: [ - Contract::CONTEXT_MODEL => new Gemini(), + Contract::CONTEXT_MODEL => Gemini::create(), ])); $this->assertFalse($normalizer->supportsNormalization('not an assistant message')); } diff --git a/src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php b/src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php index 25723bde7..7f83f2425 100644 --- a/src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php +++ b/src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php @@ -46,7 +46,7 @@ public function testSupportsNormalization() $normalizer = new MessageBagNormalizer(); $this->assertTrue($normalizer->supportsNormalization(new MessageBag(), context: [ - Contract::CONTEXT_MODEL => new Gemini(), + Contract::CONTEXT_MODEL => Gemini::create(), ])); $this->assertFalse($normalizer->supportsNormalization('not a message bag')); } diff --git a/src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php b/src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php index 0395da8df..2c87da469 100644 --- a/src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php +++ b/src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php @@ -36,7 +36,7 @@ public function testSupportsNormalization() $normalizer = new ToolCallMessageNormalizer(); $this->assertTrue($normalizer->supportsNormalization(new ToolCallMessage(new ToolCall('', '', []), ''), context: [ - Contract::CONTEXT_MODEL => new Gemini(), + Contract::CONTEXT_MODEL => Gemini::create(), ])); $this->assertFalse($normalizer->supportsNormalization('not a tool call')); } diff --git a/src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php b/src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php index 7cf2b0eff..7df7afee9 100644 --- a/src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php +++ b/src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php @@ -37,7 +37,7 @@ public function testSupportsNormalization() $normalizer = new ToolNormalizer(); $this->assertTrue($normalizer->supportsNormalization(new Tool(new ExecutionReference(ToolNoParams::class), 'test', 'test'), context: [ - Contract::CONTEXT_MODEL => new Gemini(), + Contract::CONTEXT_MODEL => Gemini::create(), ])); $this->assertFalse($normalizer->supportsNormalization('not a tool')); } diff --git a/src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php b/src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php index 5ccf9970d..b3a90fb70 100644 --- a/src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php +++ b/src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php @@ -42,7 +42,7 @@ public function testSupportsNormalization() $normalizer = new UserMessageNormalizer(); $this->assertTrue($normalizer->supportsNormalization(new UserMessage(new Text('Hello')), context: [ - Contract::CONTEXT_MODEL => new Gemini(), + Contract::CONTEXT_MODEL => Gemini::create(), ])); $this->assertFalse($normalizer->supportsNormalization('not a user message')); } diff --git a/src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php b/src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php index 5eda6889c..6b6db0199 100644 --- a/src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php +++ b/src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php @@ -64,7 +64,7 @@ public function testItMakesARequestWithCorrectPayload() ) ->willReturn($result); - $model = new Embeddings(Embeddings::GEMINI_EMBEDDING_EXP_03_07, ['dimensions' => 1536, 'task_type' => 'CLASSIFICATION']); + $model = Embeddings::create(Embeddings::GEMINI_EMBEDDING_EXP_03_07, ['dimensions' => 1536, 'task_type' => 'CLASSIFICATION']); $result = (new ModelClient($httpClient, 'test'))->request($model, ['payload1', 'payload2']); $this->assertSame(json_decode($this->getEmbeddingStub(), true), $result->getData()); diff --git a/src/platform/tests/Bridge/LmStudio/Completions/ModelClientTest.php b/src/platform/tests/Bridge/LmStudio/Completions/ModelClientTest.php index b543f29ac..205c6b0d0 100644 --- a/src/platform/tests/Bridge/LmStudio/Completions/ModelClientTest.php +++ b/src/platform/tests/Bridge/LmStudio/Completions/ModelClientTest.php @@ -31,7 +31,7 @@ public function testItIsSupportingTheCorrectModel() { $client = new ModelClient(new MockHttpClient(), 'http://localhost:1234'); - $this->assertTrue($client->supports(new Completions('test-model'))); + $this->assertTrue($client->supports(Completions::create('test-model'))); } public function testItIsExecutingTheCorrectRequest() @@ -57,7 +57,7 @@ public function testItIsExecutingTheCorrectRequest() ], ]; - $client->request(new Completions('test-model'), $payload); + $client->request(Completions::create('test-model'), $payload); } public function testItMergesOptionsWithPayload() @@ -83,7 +83,7 @@ public function testItMergesOptionsWithPayload() ], ]; - $client->request(new Completions('test-model'), $payload, ['temperature' => 0.7]); + $client->request(Completions::create('test-model'), $payload, ['temperature' => 0.7]); } public function testItUsesEventSourceHttpClient() diff --git a/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php b/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php index 4e7c1c4b8..20c550d79 100644 --- a/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php +++ b/src/platform/tests/Bridge/LmStudio/Completions/ResultConverterTest.php @@ -29,6 +29,6 @@ public function testItSupportsCompletionsModel() { $converter = new ResultConverter(); - $this->assertTrue($converter->supports(new Completions('test-model'))); + $this->assertTrue($converter->supports(Completions::create('test-model'))); } } diff --git a/src/platform/tests/Bridge/LmStudio/Embeddings/ModelClientTest.php b/src/platform/tests/Bridge/LmStudio/Embeddings/ModelClientTest.php index 1ab245d18..eb23c1913 100644 --- a/src/platform/tests/Bridge/LmStudio/Embeddings/ModelClientTest.php +++ b/src/platform/tests/Bridge/LmStudio/Embeddings/ModelClientTest.php @@ -29,7 +29,7 @@ public function testItIsSupportingTheCorrectModel() { $client = new ModelClient(new MockHttpClient(), 'http://localhost:1234'); - $this->assertTrue($client->supports(new Embeddings('test-model'))); + $this->assertTrue($client->supports(Embeddings::create('test-model'))); } public function testItIsExecutingTheCorrectRequest() @@ -45,7 +45,7 @@ public function testItIsExecutingTheCorrectRequest() $httpClient = new MockHttpClient([$resultCallback]); $client = new ModelClient($httpClient, 'http://localhost:1234'); - $model = new Embeddings('test-model'); + $model = Embeddings::create('test-model'); $client->request($model, 'Hello, world!'); } @@ -66,7 +66,7 @@ public function testItMergesOptionsWithPayload() $httpClient = new MockHttpClient([$resultCallback]); $client = new ModelClient($httpClient, 'http://localhost:1234'); - $model = new Embeddings('test-model'); + $model = Embeddings::create('test-model'); $client->request($model, 'Hello, world!', ['custom_option' => 'value']); } @@ -84,7 +84,7 @@ public function testItHandlesArrayInput() $httpClient = new MockHttpClient([$resultCallback]); $client = new ModelClient($httpClient, 'http://localhost:1234'); - $model = new Embeddings('test-model'); + $model = Embeddings::create('test-model'); $client->request($model, ['Hello', 'world']); } diff --git a/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php b/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php index 16b6b25d8..4e91a23c5 100644 --- a/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php +++ b/src/platform/tests/Bridge/LmStudio/Embeddings/ResultConverterTest.php @@ -84,6 +84,6 @@ public function testItSupportsEmbeddingsModel() { $converter = new ResultConverter(); - $this->assertTrue($converter->supports(new Embeddings('test-model'))); + $this->assertTrue($converter->supports(Embeddings::create('test-model'))); } } diff --git a/src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php b/src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php index 465b117c0..5dd1f4add 100644 --- a/src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php +++ b/src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php @@ -42,7 +42,7 @@ protected function setUp(): void public function testSupportsNormalization() { $this->assertTrue($this->normalizer->supportsNormalization(new AssistantMessage('Hello'), context: [ - Contract::CONTEXT_MODEL => new Ollama(), + Contract::CONTEXT_MODEL => Ollama::create(), ])); $this->assertFalse($this->normalizer->supportsNormalization(new AssistantMessage('Hello'), context: [ Contract::CONTEXT_MODEL => new Model('any-model'), diff --git a/src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php b/src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php index 791206200..567aad123 100644 --- a/src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php +++ b/src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php @@ -42,7 +42,7 @@ public function testSupportsLlamaModel() { $converter = new OllamaResultConverter(); - $this->assertTrue($converter->supports(new Ollama())); + $this->assertTrue($converter->supports(Ollama::create())); $this->assertFalse($converter->supports(new Model('any-model'))); } diff --git a/src/platform/tests/Bridge/Ollama/OllamaTest.php b/src/platform/tests/Bridge/Ollama/OllamaTest.php index e98d1efd3..8d9e51040 100644 --- a/src/platform/tests/Bridge/Ollama/OllamaTest.php +++ b/src/platform/tests/Bridge/Ollama/OllamaTest.php @@ -25,7 +25,7 @@ final class OllamaTest extends TestCase #[DataProvider('provideModelsWithToolCallingCapability')] public function testModelsWithToolCallingCapability(string $modelName) { - $model = new Ollama($modelName); + $model = Ollama::create($modelName); $this->assertTrue( $model->supports(Capability::TOOL_CALLING), @@ -36,7 +36,7 @@ public function testModelsWithToolCallingCapability(string $modelName) #[DataProvider('provideModelsWithoutToolCallingCapability')] public function testModelsWithoutToolCallingCapability(string $modelName) { - $model = new Ollama($modelName); + $model = Ollama::create($modelName); $this->assertFalse( $model->supports(Capability::TOOL_CALLING), @@ -47,7 +47,7 @@ public function testModelsWithoutToolCallingCapability(string $modelName) #[DataProvider('provideModelsWithMultipleInputCapabilities')] public function testModelsWithMultipleInputCapabilities(string $modelName) { - $model = new Ollama($modelName); + $model = Ollama::create($modelName); $this->assertTrue( $model->supports(Capability::INPUT_MULTIPLE), diff --git a/src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php b/src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php index d866c299b..ca4999cf2 100644 --- a/src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php +++ b/src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php @@ -61,7 +61,7 @@ public function testItIsSupportingTheCorrectModel() { $modelClient = new ModelClient(new MockHttpClient(), 'sk-api-key'); - $this->assertTrue($modelClient->supports(new DallE())); + $this->assertTrue($modelClient->supports(DallE::create())); } public function testItIsExecutingTheCorrectRequest() @@ -76,6 +76,6 @@ public function testItIsExecutingTheCorrectRequest() }; $httpClient = new MockHttpClient([$resultCallback]); $modelClient = new ModelClient($httpClient, 'sk-api-key'); - $modelClient->request(new DallE(), 'foo', ['n' => 1, 'response_format' => 'url']); + $modelClient->request(DallE::create(), 'foo', ['n' => 1, 'response_format' => 'url']); } } diff --git a/src/platform/tests/Bridge/OpenAi/DallETest.php b/src/platform/tests/Bridge/OpenAi/DallETest.php index 7448f0c4a..7b90625e3 100644 --- a/src/platform/tests/Bridge/OpenAi/DallETest.php +++ b/src/platform/tests/Bridge/OpenAi/DallETest.php @@ -22,7 +22,7 @@ final class DallETest extends TestCase { public function testItCreatesDallEWithDefaultSettings() { - $dallE = new DallE(); + $dallE = DallE::create(); $this->assertSame(DallE::DALL_E_2, $dallE->getName()); $this->assertSame([], $dallE->getOptions()); @@ -30,7 +30,7 @@ public function testItCreatesDallEWithDefaultSettings() public function testItCreatesDallEWithCustomSettings() { - $dallE = new DallE(DallE::DALL_E_3, ['response_format' => 'base64', 'n' => 2]); + $dallE = DallE::create(DallE::DALL_E_3, ['response_format' => 'base64', 'n' => 2]); $this->assertSame(DallE::DALL_E_3, $dallE->getName()); $this->assertSame(['response_format' => 'base64', 'n' => 2], $dallE->getOptions()); diff --git a/src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php b/src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php index d34e73ec6..2f37ae1c0 100644 --- a/src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php +++ b/src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php @@ -27,7 +27,7 @@ final class ModelClientTest extends TestCase public function testItSupportsWhisperModel() { $client = new ModelClient(new MockHttpClient(), 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $this->assertTrue($client->supports($model)); } @@ -44,7 +44,7 @@ function ($method, $url): MockResponse { ]); $client = new ModelClient($httpClient, 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $payload = ['file' => 'audio-data']; $client->request($model, $payload); @@ -64,7 +64,7 @@ function ($method, $url): MockResponse { ]); $client = new ModelClient($httpClient, 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $payload = ['file' => 'audio-data']; $options = ['task' => Task::TRANSCRIPTION]; @@ -85,7 +85,7 @@ function ($method, $url): MockResponse { ]); $client = new ModelClient($httpClient, 'test-key'); - $model = new Whisper(); + $model = Whisper::create(); $payload = ['file' => 'audio-data']; $options = ['task' => Task::TRANSLATION]; diff --git a/src/platform/tests/Contract/Normalizer/Message/MessageBagNormalizerTest.php b/src/platform/tests/Contract/Normalizer/Message/MessageBagNormalizerTest.php index d9e8164aa..a5ee7096f 100644 --- a/src/platform/tests/Contract/Normalizer/Message/MessageBagNormalizerTest.php +++ b/src/platform/tests/Contract/Normalizer/Message/MessageBagNormalizerTest.php @@ -96,7 +96,7 @@ public function testNormalizeWithModel() $innerNormalizer = $this->createMock(NormalizerInterface::class); $innerNormalizer->expects($this->once()) ->method('normalize') - ->with($messages, null, [Contract::CONTEXT_MODEL => new Gpt()]) + ->with($messages, null, [Contract::CONTEXT_MODEL => Gpt::create()]) ->willReturn([ ['role' => 'system', 'content' => 'You are a helpful assistant'], ['role' => 'user', 'content' => 'Hello'], @@ -113,7 +113,7 @@ public function testNormalizeWithModel() ]; $this->assertSame($expected, $this->normalizer->normalize($messageBag, context: [ - Contract::CONTEXT_MODEL => new Gpt(), + Contract::CONTEXT_MODEL => Gpt::create(), ])); } } diff --git a/src/platform/tests/ContractTest.php b/src/platform/tests/ContractTest.php index 111ee40c3..4a18d2908 100644 --- a/src/platform/tests/ContractTest.php +++ b/src/platform/tests/ContractTest.php @@ -83,7 +83,7 @@ public function testCreateRequestPayload(Model $model, array|string|object $inpu public static function providePayloadTestCases(): iterable { yield 'MessageBag with Gpt' => [ - 'model' => new Gpt(), + 'model' => Gpt::create(), 'input' => new MessageBag( Message::forSystem('System message'), Message::ofUser('User message'), @@ -101,7 +101,7 @@ public static function providePayloadTestCases(): iterable $audio = Audio::fromFile(\dirname(__DIR__, 3).'/fixtures/audio.mp3'); yield 'Audio within MessageBag with Gpt' => [ - 'model' => new Gpt(), + 'model' => Gpt::create(), 'input' => new MessageBag(Message::ofUser('What is this recording about?', $audio)), 'expected' => [ 'messages' => [ @@ -125,7 +125,7 @@ public static function providePayloadTestCases(): iterable $image = Image::fromFile(\dirname(__DIR__, 3).'/fixtures/image.jpg'); yield 'Image within MessageBag with Gpt' => [ - 'model' => new Gpt(), + 'model' => Gpt::create(), 'input' => new MessageBag( Message::forSystem('You are an image analyzer bot that helps identify the content of images.'), Message::ofUser('Describe the image as a comedian would do it.', $image), @@ -149,7 +149,7 @@ public static function providePayloadTestCases(): iterable ]; yield 'ImageUrl within MessageBag with Gpt' => [ - 'model' => new Gpt(), + 'model' => Gpt::create(), 'input' => new MessageBag( Message::forSystem('You are an image analyzer bot that helps identify the content of images.'), Message::ofUser('Describe the image as a comedian would do it.', new ImageUrl('https://example.com/image.jpg')), @@ -173,13 +173,13 @@ public static function providePayloadTestCases(): iterable ]; yield 'Text Input with Embeddings' => [ - 'model' => new Embeddings(), + 'model' => Embeddings::create(), 'input' => 'This is a test input.', 'expected' => 'This is a test input.', ]; yield 'Longer Conversation with Gpt' => [ - 'model' => new Gpt(), + 'model' => Gpt::create(), 'input' => new MessageBag( Message::forSystem('My amazing system prompt.'), Message::ofAssistant('It is time to sleep.'), @@ -223,7 +223,7 @@ public function jsonSerialize(): array }; yield 'MessageBag with custom message from Gpt' => [ - 'model' => new Gpt(), + 'model' => Gpt::create(), 'input' => new MessageBag($customSerializableMessage), 'expected' => [ 'messages' => [ @@ -240,7 +240,7 @@ public function testExtendedContractHandlesWhisper() $audio = Audio::fromFile(\dirname(__DIR__, 3).'/fixtures/audio.mp3'); - $actual = $contract->createRequestPayload(new Whisper(), $audio); + $actual = $contract->createRequestPayload(Whisper::create(), $audio); $this->assertArrayHasKey('model', $actual); $this->assertSame('whisper-1', $actual['model']); diff --git a/src/store/tests/IndexerTest.php b/src/store/tests/IndexerTest.php index e7865f9de..d9499102e 100644 --- a/src/store/tests/IndexerTest.php +++ b/src/store/tests/IndexerTest.php @@ -49,7 +49,7 @@ public function testIndexSingleDocument() { $document = new TextDocument($id = Uuid::v4(), 'Test content'); $vector = new Vector([0.1, 0.2, 0.3]); - $vectorizer = new Vectorizer(PlatformTestHandler::createPlatform(new VectorResult($vector)), new Embeddings()); + $vectorizer = new Vectorizer(PlatformTestHandler::createPlatform(new VectorResult($vector)), Embeddings::create()); $indexer = new Indexer($vectorizer, $store = new TestStore()); $indexer->index($document); @@ -64,7 +64,7 @@ public function testIndexEmptyDocumentList() { $logger = self::createMock(LoggerInterface::class); $logger->expects($this->once())->method('debug')->with('No documents to index'); - $vectorizer = new Vectorizer(PlatformTestHandler::createPlatform(), new Embeddings()); + $vectorizer = new Vectorizer(PlatformTestHandler::createPlatform(), Embeddings::create()); $indexer = new Indexer($vectorizer, $store = new TestStore(), $logger); $indexer->index([]); @@ -77,7 +77,7 @@ public function testIndexDocumentWithMetadata() $metadata = new Metadata(['key' => 'value']); $document = new TextDocument($id = Uuid::v4(), 'Test content', $metadata); $vector = new Vector([0.1, 0.2, 0.3]); - $vectorizer = new Vectorizer(PlatformTestHandler::createPlatform(new VectorResult($vector)), new Embeddings()); + $vectorizer = new Vectorizer(PlatformTestHandler::createPlatform(new VectorResult($vector)), Embeddings::create()); $indexer = new Indexer($vectorizer, $store = new TestStore()); $indexer->index($document);