Skip to content

Commit 8e6a7d0

Browse files
authored
chore: split example folder structure into multiple subdirectories (#295)
1 parent 519c06c commit 8e6a7d0

35 files changed

+116
-114
lines changed

README.md

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
PHP library for building LLM-based and AI-based features and applications.
44

5-
This library is not a stable yet, but still rather experimental. Feel free to try it out, give feedback, ask questions,
6-
contribute or share your use cases. Abstractions, concepts and interfaces are not final and potentially subject of change.
5+
This library is not stable yet, but still rather experimental. Feel free to try it out, give feedback, ask questions,
6+
contribute, or share your use cases. Abstractions, concepts, and interfaces are not final and potentially subject of change.
77

88
## Requirements
99

@@ -21,7 +21,7 @@ When using Symfony Framework, check out the integration bundle [php-llm/llm-chai
2121

2222
## Examples
2323

24-
See [examples](examples) folder to run example implementations using this library.
24+
See [the examples folder](examples) to run example implementations using this library.
2525
Depending on the example you need to export different environment variables
2626
for API keys or deployment configurations or create a `.env.local` based on `.env` file.
2727

@@ -34,10 +34,10 @@ For a more sophisticated demo, see the [Symfony Demo Application](https://github
3434
### Models & Platforms
3535

3636
LLM Chain categorizes two main types of models: **Language Models** and **Embeddings Models**. On top of that, there are
37-
other models, like text-to-speech, image generation or classification models that are also supported.
37+
other models, like text-to-speech, image generation, or classification models that are also supported.
3838

39-
Language Models, like GPT, Claude and Llama, as essential centerpiece of LLM applications
40-
and Embeddings Models as supporting models to provide vector representations of text.
39+
Language Models, like GPT, Claude, and Llama, as essential centerpiece of LLM applications
40+
and Embeddings Models as supporting models to provide vector representations of a text.
4141

4242
Those models are provided by different **platforms**, like OpenAI, Azure, Google, Replicate, and others.
4343

@@ -112,8 +112,8 @@ The second parameter of the `call` method is an array of options, which can be u
112112
chain, like `stream`, `output_structure`, or `response_format`. This behavior is a combination of features provided by
113113
the underlying model and platform, or additional features provided by processors registered to the chain.
114114

115-
Options design for additional features provided by LLM Chain can be found in this documentation. For model and platform
116-
specific options, please refer to the respective documentation.
115+
Options designed for additional features provided by LLM Chain can be found in this documentation. For model- and
116+
platform-specific options, please refer to the respective documentation.
117117

118118
```php
119119
// Chain and MessageBag instantiation
@@ -126,13 +126,15 @@ $response = $chain->call($messages, [
126126

127127
#### Code Examples
128128

129-
1. **Anthropic's Claude**: [chat-claude-anthropic.php](examples/chat-claude-anthropic.php)
130-
1. **OpenAI's GPT with Azure**: [chat-gpt-azure.php](examples/chat-gpt-azure.php)
131-
1. **OpenAI's GPT**: [chat-gpt-openai.php](examples/chat-gpt-openai.php)
132-
1. **OpenAI's o1**: [chat-o1-openai.php](examples/chat-o1-openai.php)
133-
1. **Meta's Llama with Ollama**: [chat-llama-ollama.php](examples/chat-llama-ollama.php)
134-
1. **Meta's Llama with Replicate**: [chat-llama-replicate.php](examples/chat-llama-replicate.php)
135-
1. **Google's Gemini with OpenRouter**: [chat-gemini-openrouter.php](examples/chat-gemini-openrouter.php)
129+
1. [Anthropic's Claude](examples/anthropic/chat.php)
130+
1. [OpenAI's GPT with Azure](examples/azure/chat-gpt.php)
131+
1. [OpenAI's GPT](examples/openai/chat.php)
132+
1. [OpenAI's o1](examples/openai/chat-o1.php)
133+
1. [Meta's Llama with Azure](examples/azure/chat-llama.php)
134+
1. [Meta's Llama with Ollama](examples/ollama/chat-llama.php)
135+
1. [Meta's Llama with Replicate](examples/replicate/chat-llama.php)
136+
1. [Google's Gemini with Google](examples/google/chat.php)
137+
1. [Google's Gemini with OpenRouter](examples/openrouter/chat-gemini.php)
136138

137139
### Tools
138140

@@ -340,14 +342,14 @@ $eventDispatcher->addListener(ToolCallsExecuted::class, function (ToolCallsExecu
340342

341343
#### Code Examples (with built-in tools)
342344

343-
1. **Brave Tool**: [toolbox-brave.php](examples/toolbox-brave.php)
344-
1. **Clock Tool**: [toolbox-clock.php](examples/toolbox-clock.php)
345-
1. **Crawler Tool**: [toolbox-brave.php](examples/toolbox-brave.php)
346-
1. **SerpAPI Tool**: [toolbox-serpapi.php](examples/toolbox-serpapi.php)
347-
1. **Tavily Tool**: [toolbox-tavily.php](examples/toolbox-tavily.php)
348-
1. **Weather Tool with Event Listener**: [toolbox-weather-event.php](examples/toolbox-weather-event.php)
349-
1. **Wikipedia Tool**: [toolbox-wikipedia.php](examples/toolbox-wikipedia.php)
350-
1. **YouTube Transcriber Tool**: [toolbox-youtube.php](examples/toolbox-youtube.php) (with streaming)
345+
1. [Brave Tool](examples/toolbox/brave.php)
346+
1. [Clock Tool](examples/toolbox/clock.php)
347+
1. [Crawler Tool](examples/toolbox/brave.php)
348+
1. [SerpAPI Tool](examples/toolbox/serpapi.php)
349+
1. [Tavily Tool](examples/toolbox/tavily.php)
350+
1. [Weather Tool with Event Listener](examples/toolbox/weather-event.php)
351+
1. [Wikipedia Tool](examples/anthropic/toolbox.php)
352+
1. [YouTube Transcriber Tool](examples/openai/toolbox.php) (with streaming)
351353

352354
### Document Embedding, Vector Stores & Similarity Search (RAG)
353355

@@ -383,7 +385,7 @@ foreach ($entities as $entity) {
383385
$documents[] = new TextDocument(
384386
id: $entity->getId(), // UUID instance
385387
content: $entity->toString(), // Text representation of relevant data for embedding
386-
metadata: new Metadata($entity->toArray()), // Array representation of entity to be stored additionally
388+
metadata: new Metadata($entity->toArray()), // Array representation of an entity to be stored additionally
387389
);
388390
}
389391
```
@@ -421,8 +423,8 @@ $response = $chain->call($messages);
421423
422424
#### Code Examples
423425
424-
1. **MongoDB Store**: [store-mongodb-similarity-search.php](examples/store-mongodb-similarity-search.php)
425-
1. **Pinecone Store**: [store-pinecone-similarity-search.php](examples/store-pinecone-similarity-search.php)
426+
1. [MongoDB Store](examples/store-mongodb-similarity-search.php)
427+
1. [Pinecone Store](examples/store-pinecone-similarity-search.php)
426428
427429
#### Supported Stores
428430
@@ -442,7 +444,7 @@ by features like **Structured Output** or providing a **Response Format**.
442444
443445
#### PHP Classes as Output
444446
445-
LLM Chain support that use-case by abstracting the hustle of defining and providing schemas to the LLM and converting
447+
LLM Chain supports that use-case by abstracting the hustle of defining and providing schemas to the LLM and converting
446448
the response back to PHP objects.
447449
448450
To achieve this, a specific chain processor needs to be registered:
@@ -505,8 +507,8 @@ dump($response->getContent()); // returns an array
505507
506508
#### Code Examples
507509
508-
1. **Structured Output** (PHP class): [structured-output-math.php](examples/structured-output-math.php)
509-
1. **Structured Output** (array): [structured-output-clock.php](examples/structured-output-clock.php)
510+
1. [Structured Output with PHP class)](examples/openai/structured-output-math.php)
511+
1. [Structured Output with array](examples/openai/structured-output-clock.php)
510512
511513
### Response Streaming
512514
@@ -539,8 +541,8 @@ needs to be used.
539541
540542
#### Code Examples
541543
542-
1. **Streaming Claude**: [stream-claude-anthropic.php](examples/stream-claude-anthropic.php)
543-
1. **Streaming GPT**: [stream-gpt-openai.php](examples/stream-gpt-openai.php)
544+
1. [Streaming Claude](examples/anthropic/stream.php)
545+
1. [Streaming GPT](examples/openai/stream.php)
544546
545547
### Image Processing
546548
@@ -567,8 +569,8 @@ $response = $chain->call($messages);
567569
568570
#### Code Examples
569571
570-
1. **Image Description**: [image-describer-binary.php](examples/image-describer-binary.php) (with binary file)
571-
1. **Image Description**: [image-describer-url.php](examples/image-describer-url.php) (with URL)
572+
1. [Binary Image Input with GPT](examples/openai/image-input-binary.php)
573+
1. [Image URL Input with GPT](examples/openai/image-input-url.php)
572574
573575
### Audio Processing
574576
@@ -592,11 +594,11 @@ $response = $chain->call($messages);
592594
593595
#### Code Examples
594596
595-
1. **Audio Description**: [audio-describer.php](examples/audio-describer.php)
597+
1. [Audio Input with GPT](examples/openai/audio-input.php)
596598
597599
### Embeddings
598600
599-
Creating embeddings of word, sentences or paragraphs is a typical use case around the interaction with LLMs and
601+
Creating embeddings of word, sentences, or paragraphs is a typical use case around the interaction with LLMs, and
600602
therefore LLM Chain implements a `EmbeddingsModel` interface with various models, see above.
601603
602604
The standalone usage results in an `Vector` instance:
@@ -615,8 +617,8 @@ dump($vectors[0]->getData()); // Array of float values
615617
616618
#### Code Examples
617619
618-
1. **OpenAI's Emebddings**: [embeddings-openai.php](examples/embeddings-openai.php)
619-
1. **Voyage's Embeddings**: [embeddings-voyage.php](examples/embeddings-voyage.php)
620+
1. [OpenAI's Emebddings](examples/openai/embeddings.php)
621+
1. [Voyage's Embeddings](examples/voyage/embeddings.php)
620622
621623
### Parallel Platform Calls
622624
@@ -639,11 +641,11 @@ foreach ($responses as $response) {
639641
640642
#### Code Examples
641643
642-
1. **Parallel GPT Calls**: [parallel-chat-gpt.php](examples/parallel-chat-gpt.php)
643-
1. **Parallel Embeddings Calls**: [parallel-embeddings.php](examples/parallel-embeddings.php)
644+
1. [Parallel GPT Calls](examples/parallel-chat-gpt.php)
645+
1. [Parallel Embeddings Calls](examples/parallel-embeddings.php)
644646
645647
> [!NOTE]
646-
> Please be aware that some embeddings models also support batch processing out of the box.
648+
> Please be aware that some embedding models also support batch processing out of the box.
647649
648650
### Input & Output Processing
649651
@@ -733,7 +735,7 @@ final class MyProcessor implements OutputProcessor, ChainAwareProcessor
733735
## HuggingFace
734736
735737
LLM Chain comes out of the box with an integration for [HuggingFace](https://huggingface.co/) which is a platform for
736-
hosting and sharing all kind of models, including LLMs, embeddings, image generation and classification models.
738+
hosting and sharing all kinds of models, including LLMs, embeddings, image generation, and classification models.
737739
738740
You can just instantiate the Platform with the corresponding HuggingFace bridge and use it with the `task` option:
739741
```php
@@ -800,7 +802,7 @@ echo $response->getContent().PHP_EOL;
800802

801803
#### Code Examples
802804

803-
1. [Text Generation with TransformersPHP](examples/transformers-text-generation.php)
805+
1. [Text Generation with TransformersPHP](examples/transformers/text-generation.php)
804806

805807
## Contributions
806808

example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ $app = (new SingleCommandApplication('LLM Chain Example Runner'))
5656
: (1 === $run['process']->getExitCode() || $emptyOutput ? '<error>Failed</error>' : '<comment>Skipped</comment>');
5757
}
5858

59-
$table->addRow([$example->getFilename(), $state, $output]);
59+
$table->addRow([$example->getRelativePathname(), $state, $output]);
6060
}
6161
$table->render();
6262
};
@@ -87,7 +87,7 @@ $app = (new SingleCommandApplication('LLM Chain Example Runner'))
8787

8888
foreach ($exampleRuns as $run) {
8989
if (!$run['process']->isSuccessful()) {
90-
$io->section('Error in ' . $run['example']->getFilename());
90+
$io->section('Error in ' . $run['example']->getRelativePathname());
9191
$io->text($run['process']->getOutput());
9292
$io->text($run['process']->getErrorOutput());
9393
}

examples/chat-claude-anthropic.php renamed to examples/anthropic/chat.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
1414
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;

examples/stream-claude-anthropic.php renamed to examples/anthropic/stream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
1414
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;

examples/toolbox-wikipedia.php renamed to examples/anthropic/toolbox.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
use Symfony\Component\Dotenv\Dotenv;
1212
use Symfony\Component\HttpClient\HttpClient;
1313

14-
require_once dirname(__DIR__).'/vendor/autoload.php';
15-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
14+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
15+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1616

1717
if (empty($_ENV['ANTHROPIC_API_KEY'])) {
1818
echo 'Please set the ANTHROPIC_API_KEY environment variable.'.PHP_EOL;

examples/chat-gpt-azure.php renamed to examples/azure/chat-gpt.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['AZURE_OPENAI_BASEURL']) || empty($_ENV['AZURE_OPENAI_DEPLOYMENT']) || empty($_ENV['AZURE_OPENAI_VERSION']) || empty($_ENV['AZURE_OPENAI_KEY'])
1414
) {

examples/chat-llama-azure.php renamed to examples/azure/chat-llama.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['AZURE_LLAMA_BASEURL']) || empty($_ENV['AZURE_LLAMA_KEY'])) {
1414
echo 'Please set the AZURE_LLAMA_BASEURL and AZURE_LLAMA_KEY environment variable.'.PHP_EOL;

examples/chat-gemini-google.php renamed to examples/google/chat.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['GOOGLE_API_KEY'])) {
1414
echo 'Please set the GOOGLE_API_KEY environment variable.'.PHP_EOL;

examples/image-describer-binary-gemini.php renamed to examples/google/image-input.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
use PhpLlm\LlmChain\Model\Message\MessageBag;
99
use Symfony\Component\Dotenv\Dotenv;
1010

11-
require_once dirname(__DIR__).'/vendor/autoload.php';
12-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
11+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
12+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1313

1414
if (empty($_ENV['GOOGLE_API_KEY'])) {
1515
echo 'Please set the GOOGLE_API_KEY environment variable.'.PHP_EOL;
@@ -24,7 +24,7 @@
2424
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
2525
Message::ofUser(
2626
'Describe the image as a comedian would do it.',
27-
Image::fromFile(dirname(__DIR__).'/tests/Fixture/image.jpg'),
27+
Image::fromFile(dirname(__DIR__, 2).'/tests/Fixture/image.jpg'),
2828
),
2929
);
3030
$response = $chain->call($messages);

examples/stream-google-gemini.php renamed to examples/google/stream.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['GOOGLE_API_KEY'])) {
1414
echo 'Please set the GOOGLE_API_KEY environment variable.'.PHP_EOL;

examples/chat-llama-ollama.php renamed to examples/ollama/chat-llama.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['OLLAMA_HOST_URL'])) {
1414
echo 'Please set the OLLAMA_HOST_URL environment variable.'.PHP_EOL;

examples/audio-describer.php renamed to examples/openai/audio-input.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
use PhpLlm\LlmChain\Model\Message\MessageBag;
99
use Symfony\Component\Dotenv\Dotenv;
1010

11-
require_once dirname(__DIR__).'/vendor/autoload.php';
12-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
11+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
12+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1313

1414
if (empty($_ENV['OPENAI_API_KEY'])) {
1515
echo 'Please set the OPENAI_API_KEY environment variable.'.PHP_EOL;
@@ -23,7 +23,7 @@
2323
$messages = new MessageBag(
2424
Message::ofUser(
2525
'What is this recording about?',
26-
Audio::fromFile(dirname(__DIR__).'/tests/Fixture/audio.mp3'),
26+
Audio::fromFile(dirname(__DIR__, 2).'/tests/Fixture/audio.mp3'),
2727
),
2828
);
2929
$response = $chain->call($messages);

examples/audio-transcript-whisper.php renamed to examples/openai/audio-transcript.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use PhpLlm\LlmChain\Model\Message\Content\Audio;
66
use Symfony\Component\Dotenv\Dotenv;
77

8-
require_once dirname(__DIR__).'/vendor/autoload.php';
9-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
8+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
9+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1010

1111
if (empty($_ENV['OPENAI_API_KEY'])) {
1212
echo 'Please set the OPENAI_API_KEY environment variable.'.PHP_EOL;
@@ -15,7 +15,7 @@
1515

1616
$platform = PlatformFactory::create($_ENV['OPENAI_API_KEY']);
1717
$model = new Whisper();
18-
$file = Audio::fromFile(dirname(__DIR__).'/tests/Fixture/audio.mp3');
18+
$file = Audio::fromFile(dirname(__DIR__, 2).'/tests/Fixture/audio.mp3');
1919

2020
$response = $platform->request($model, $file);
2121

examples/chat-o1-openai.php renamed to examples/openai/chat-o1.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['OPENAI_API_KEY'])) {
1414
echo 'Please set the OPENAI_API_KEY environment variable.'.PHP_EOL;

examples/chat-gpt-openai.php renamed to examples/openai/chat.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
use PhpLlm\LlmChain\Model\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

10-
require_once dirname(__DIR__).'/vendor/autoload.php';
11-
(new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
10+
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
11+
(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env');
1212

1313
if (empty($_ENV['OPENAI_API_KEY'])) {
1414
echo 'Please set the OPENAI_API_KEY environment variable.'.PHP_EOL;

0 commit comments

Comments
 (0)