diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..c90148b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,4 @@
+/.github export-ignore
+/.vscode export-ignore
+/tests export-ignore
+.gitattributes export-ignore
\ No newline at end of file
diff --git a/.github/workflows/close-pull-request.yml b/.github/workflows/close-pull-request.yml
new file mode 100644
index 0000000..fa4b5ca
--- /dev/null
+++ b/.github/workflows/close-pull-request.yml
@@ -0,0 +1,13 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: "Thank you for your pull request. However, you have submitted this PR on the friendsofhyperf organization which is a read-only sub split of `friendsofhyperf/components`. Please submit your PR on the https://github.com/friendsofhyperf/components repository.
Thanks!"
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..dde70ae
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,25 @@
+on:
+ push:
+ # Sequence of patterns matched against refs/tags
+ tags:
+ - 'v*' # Push events to matching v*, i.e. v1.0, v1.0.0
+
+name: Release
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Create Release
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref }}
+ release_name: Release ${{ github.ref }}
+ draft: false
+ prerelease: false
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..bf891ca
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 D.J.Hwang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8ec8b07
--- /dev/null
+++ b/README.md
@@ -0,0 +1,77 @@
+# Hyperf OpenAI Client
+
+[![Latest Test](https://github.com/friendsofhyperf/openai-client/workflows/tests/badge.svg)](https://github.com/friendsofhyperf/openai-client/actions)
+[![Latest Version on Packagist](https://img.shields.io/packagist/v/friendsofhyperf/openai-client.svg?style=flat-square)](https://packagist.org/packages/friendsofhyperf/openai-client)
+[![Total Downloads](https://img.shields.io/packagist/dt/friendsofhyperf/openai-client.svg?style=flat-square)](https://packagist.org/packages/friendsofhyperf/openai-client)
+[![GitHub license](https://img.shields.io/github/license/friendsofhyperf/openai-client)](https://github.com/friendsofhyperf/openai-client)
+
+------
+**OpenAI PHP** for Laravel is a supercharged community PHP API client that allows you to interact with the [Open AI API](https://beta.openai.com/docs/api-reference/introduction).
+
+> **Note:** This repository contains the integration code of the **OpenAI PHP** for Hyperf. If you want to use the **OpenAI PHP** client in a framework-agnostic way, take a look at the [openai-php/client](https://github.com/openai-php/client) repository.
+
+## Get Started
+
+> **Requires [PHP 8.1+](https://php.net/releases/)**
+
+First, install OpenAI via the [Composer](https://getcomposer.org/) package manager:
+
+```bash
+composer require friendsofhyperf/openai-client
+```
+
+Next, publish the configuration file:
+
+```bash
+php bin/hyperf.php vendor:publish friendsofhyperf/openai-client
+```
+
+This will create a `config/autoload/openai.php` configuration file in your project, which you can modify to your needs
+using environment variables:
+
+```env
+OPENAI_API_KEY=sk-...
+```
+
+Finally, you may use the `OpenAI\Client` instance from container to access the OpenAI API:
+
+```php
+use OpenAI\Client;
+
+$result = di(OpenAI\Client::class)->completions()->create([
+ 'model' => 'text-davinci-003',
+ 'prompt' => 'PHP is',
+]);
+
+echo $result['choices'][0]['text']; // an open-source, widely-used, server-side scripting language.
+```
+
+## Azure
+
+In order to use the Azure OpenAI Service, it is necessary to construct the client manually using the factory.
+
+```php
+$client = OpenAI::factory()
+ ->withBaseUri('{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}')
+ ->withHttpHeader('api-key', '{your-api-key}')
+ ->withQueryParam('api-version', '{version}')
+ ->make();
+```
+
+To use Azure, you must deploy a model, identified by the {deployment-id}, which is already incorporated into the API calls. As a result, you do not have to provide the model during the calls since it is included in the BaseUri.
+
+Therefore, a basic sample completion call would be:
+
+```php
+$result = $client->completions()->create([
+ 'prompt' => 'PHP is'
+]);
+```
+
+## Usage
+
+For usage examples, take a look at the [openai-php/client](https://github.com/openai-php/client) repository.
+
+---
+
+OpenAI PHP for Hyperf is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..47fd6d3
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "friendsofhyperf/openai-client",
+ "description": "The openai client component for Hyperf.",
+ "type": "library",
+ "keywords": [
+ "hyperf",
+ "openai"
+ ],
+ "homepage": "https://github.com/friendsofhyperf/openai-client",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "huangdijia",
+ "email": "huangdijia@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=8.1",
+ "hyperf/config": "~3.0.0",
+ "hyperf/di": "~3.0.0",
+ "hyperf/guzzle": "~3.0.0",
+ "openai-php/client": "^0.5.1"
+ },
+ "autoload": {
+ "psr-4": {
+ "FriendsOfHyperf\\OpenAi\\": "src/"
+ }
+ },
+ "extra": {
+ "hyperf": {
+ "config": "FriendsOfHyperf\\OpenAi\\ConfigProvider"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "support": {
+ "issues": "https://github.com/friendsofhyperf/components/issues",
+ "source": "https://github.com/friendsofhyperf/components"
+ }
+}
diff --git a/publish/openai.php b/publish/openai.php
new file mode 100644
index 0000000..a1ab56d
--- /dev/null
+++ b/publish/openai.php
@@ -0,0 +1,16 @@
+ env('OPENAI_API_KEY', ''),
+ 'organization' => env('OPENAI_ORGANIZATION'),
+];
diff --git a/src/ClientFactory.php b/src/ClientFactory.php
new file mode 100644
index 0000000..8d5843f
--- /dev/null
+++ b/src/ClientFactory.php
@@ -0,0 +1,40 @@
+withApiKey($apiKey)
+ ->withOrganization($organization)
+ ->withBaseUri('api.openai.com/v1')
+ ->withHttpClient(
+ $container->get(GuzzleClientFactory::class)->create()
+ )
+ ->make();
+ }
+}
diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php
new file mode 100644
index 0000000..3023864
--- /dev/null
+++ b/src/ConfigProvider.php
@@ -0,0 +1,37 @@
+ [
+ Client::class => ClientFactory::class,
+ ClientContract::class => fn ($container) => $container->get(Client::class), // alias for Client::class
+ ],
+ 'publish' => [
+ [
+ 'id' => 'config',
+ 'description' => 'The config file for OpenAI.',
+ 'source' => __DIR__ . '/../publish/openai.php',
+ 'destination' => BASE_PATH . '/config/autoload/openai.php',
+ ],
+ ],
+ ];
+ }
+}
diff --git a/src/Exception/ApiKeyIsMissing.php b/src/Exception/ApiKeyIsMissing.php
new file mode 100644
index 0000000..b8c3724
--- /dev/null
+++ b/src/Exception/ApiKeyIsMissing.php
@@ -0,0 +1,29 @@
+