diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..b9682fa
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Changelog
+
+All notable changes to `deepseek-php-client` will be documented in this file
+
+## 1.0.0 - 201X-XX-XX
+
+- initial release
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..b4ae1c4
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,55 @@
+# Contributing
+
+Contributions are **welcome** and will be fully **credited**.
+
+Please read and understand the contribution guide before creating an issue or pull request.
+
+## Etiquette
+
+This project is open source, and as such, the maintainers give their free time to build and maintain the source code
+held within. They make the code freely available in the hope that it will be of use to other developers. It would be
+extremely unfair for them to suffer abuse or anger for their hard work.
+
+Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the
+world that developers are civilized and selfless people.
+
+It's the duty of the maintainer to ensure that all submissions to the project are of sufficient
+quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used.
+
+## Viability
+
+When requesting or submitting new features, first consider whether it might be useful to others. Open
+source projects are used by many developers, who may have entirely different needs to your own. Think about
+whether or not your feature is likely to be used by other users of the project.
+
+## Procedure
+
+Before filing an issue:
+
+- Attempt to replicate the problem, to ensure that it wasn't a coincidental incident.
+- Check to make sure your feature suggestion isn't already present within the project.
+- Check the pull requests tab to ensure that the bug doesn't have a fix in progress.
+- Check the pull requests tab to ensure that the feature isn't already in progress.
+
+Before submitting a pull request:
+
+- Check the codebase to ensure that your feature doesn't already exist.
+- Check the pull requests to ensure that another person hasn't already submitted the feature or fix.
+
+## Requirements
+
+If the project maintainer has any additional requirements, you will find them listed here.
+
+- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer).
+
+- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
+
+- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
+
+- **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option.
+
+- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
+
+- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
+
+**Happy coding**!
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..a62defb
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) deepseek-php
+
+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.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c3142bb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+# Deepseek PHP Client
+
+## Table of Contents
+- [Overview](#Overview)
+ - [Features](#key-Features)
+- [Installation](#installation)
+- [Quick Start Guide](#quick-start-guide)
+ - [Basic Usage](#basic-usage)
+ - [Advanced Usage](#advanced-usage)
+- [Testing](#testing)
+- [Contributors](#contributors-)
+- [License](#license)
+
+---
+## Overview
+**Deepseek PHP Client** is a robust and community-driven PHP client library for seamless integration with the Deepseek API, offering efficient access to advanced AI and data processing capabilities
+
+### Key Features
+- **Easy Integration:** Simplifies interaction with the Deepseek API using a PHP client.
+- **Method Chaining:** Supports fluent method chaining for building requests.
+- **Customizable:** Allows setting different models, query roles, and streaming options.
+- **PSR-18 Compliance:** Utilizes PSR-18 HTTP client for making API requests.
+
+---
+
+## Installation
+
+You can install the package via Composer:
+
+```bash
+composer require deepseek-php/deepseek-php-client
+```
+
+**Ensure your project meets the following requirements:**
+- PHP 8.1 or later
+
+---
+
+## **3. Quick Start Guide**
+
+### **Basic Usage**
+
+```php
+use DeepseekPhp\DeepseekClient;
+
+$apiKey = 'your-api-key';
+
+$response = DeepseekClient::build($apiKey)
+ ->query('Hello Deepseek, how are you today?')
+ ->run();
+
+echo 'API Response:'.$response;
+```
+
+**Note**: in easy mode it will take defaults for all configs [Check Default Values](https://github.com/deepseek-php/deepseek-php-client/blob/main/src/Enums/Configs/DefaultConfigs.php)
+
+### **Advanced Usage**
+
+```php
+use DeepseekPhp\DeepseekClient;
+use DeepseekPhp\Enums\Queries\QueryRoles;
+use DeepseekPhp\Enums\Models;
+
+$apiKey = 'your-api-key';
+
+$response = DeepseekClient::build($apiKey, 'https://api.deepseek.com/v2', 500)
+ ->query('System setup query', 'system')
+ ->query('User input message', 'user')
+ ->withModel(Models::CODER->value)
+ ->run();
+
+echo 'API Response:'.$response;
+```
+
+---
+
+## **7. Testing**
+
+tests will come soon .
+
+## Changelog
+
+See [CHANGELOG](CHANGELOG.md) for recent changes.
+
+## Contributors ✨
+
+Thanks to these wonderful people for contributing to this project! 💖
+
+
+
+Want to contribute? Check out the [contributing guidelines](./CONTRIBUTING.md) and submit a pull request! 🚀
+
+## Security
+
+If you discover any security-related issues, please email creator : `omaralwi2010@gmail.com`.
+
+## License
+
+The MIT License (MIT). See [LICENSE](LICENSE.md) for more information.
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..d8e5795
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,115 @@
+{
+ "name": "deepseek-php/deepseek-php-client",
+ "description": "deepseek PHP client is a robust and community-driven PHP client library for seamless integration with the Deepseek API, offering efficient access to advanced AI and data processing capabilities.",
+ "keywords": [
+ "deepseek",
+ "deepseek-php-client",
+ "deepseek-api",
+ "php-deepseek",
+ "deepseek-integration",
+ "openai",
+ "sdk",
+ "codex",
+ "GPT-3",
+ "DALL-E",
+ "api",
+ "client",
+ "deepseek-sdk",
+ "php-sdk",
+ "php-ai",
+ "ai-for-php",
+ "ai-sdk",
+ "ai-api",
+ "natural",
+ "language",
+ "processing",
+ "deepseek-php-library",
+ "deepseek-client",
+ "natural-language-processing",
+ "ai-integration",
+ "machine-learning",
+ "php-machine-learning",
+ "php-iot",
+ "nlp",
+ "data-processing",
+ "deep-learning",
+ "deepseek-library",
+ "php-library",
+ "api-integration",
+ "php-api-client",
+ "deepseek-ai",
+ "php-openai-alternative",
+ "ai-client-library"
+ ],
+ "homepage": "https://github.com/deepseek-php/deepseek-php-client",
+ "license": "MIT",
+ "type": "library",
+ "authors": [
+ {
+ "name": "deepseek-php",
+ "email": "omaralwi2010@gmail.com",
+ "role": "owner"
+ },
+ {
+ "name": "Omar Alalwi",
+ "email": "omaralwi2010@gmail.com",
+ "role": "creator"
+ }
+ ],
+ "version": "1.0.0",
+ "require": {
+ "php": "^8.1.0",
+ "php-http/discovery": "^1.20.0",
+ "php-http/multipart-stream-builder": "^1.4.2",
+ "psr/http-client": "^1.0.3",
+ "psr/http-client-implementation": "^1.0.1",
+ "psr/http-factory-implementation": "*",
+ "psr/http-message": "^1.1.0|^2.0.0"
+ },
+ "require-dev": {
+ "guzzlehttp/guzzle": "^7.9.2",
+ "guzzlehttp/psr7": "^2.7.0",
+ "laravel/pint": "^1.18.1",
+ "mockery/mockery": "^1.6.12",
+ "nunomaduro/collision": "^7.11.0|^8.5.0",
+ "pestphp/pest": "^2.36.0|^3.5.0",
+ "pestphp/pest-plugin-arch": "^2.7|^3.0",
+ "pestphp/pest-plugin-type-coverage": "^2.8.7|^3.1.0",
+ "phpstan/phpstan": "^1.12.7",
+ "roave/security-advisories": "dev-latest",
+ "symfony/var-dumper": "^6.4.11|^7.1.5"
+ },
+ "autoload": {
+ "psr-4": {
+ "DeepseekPhp\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "DeepseekPhp\\Tests\\": "tests/"
+ }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "scripts": {
+ "lint": "pint -v",
+ "test:lint": "pint --test -v",
+ "test:types": "phpstan analyse --ansi",
+ "test:type-coverage": "pest --type-coverage --min=100",
+ "test:unit": "pest --colors=always",
+ "test": [
+ "@test:lint",
+ "@test:types",
+ "@test:type-coverage",
+ "@test:unit"
+ ]
+ },
+ "config": {
+ "sort-packages": true,
+ "preferred-install": "dist",
+ "allow-plugins": {
+ "pestphp/pest-plugin": true,
+ "php-http/discovery": true
+ }
+ }
+}
diff --git a/public/images/deepseek_screenshot.png b/public/images/deepseek_screenshot.png
new file mode 100644
index 0000000..8c28996
Binary files /dev/null and b/public/images/deepseek_screenshot.png differ
diff --git a/src/Contracts/DeepseekApiClientContract.php b/src/Contracts/DeepseekApiClientContract.php
new file mode 100644
index 0000000..0106b90
--- /dev/null
+++ b/src/Contracts/DeepseekApiClientContract.php
@@ -0,0 +1,14 @@
+httpClient = $httpClient;
+ $this->model = null;
+ $this->stream = false;
+ }
+
+ public function run(): string
+ {
+ $requestData = [
+ QueryFlags::MESSAGES->value => $this->queries,
+ QueryFlags::MODEL->value => $this->model,
+ QueryFlags::STREAM->value => $this->stream,
+ ];
+ // Clear queries after sending
+ $this->queries = [];
+ return (new Resource($this->httpClient))->sendRequest($requestData);
+ }
+
+ /**
+ * Create a new DeepseekClient instance with the given API key.
+ *
+ * @param string $apiKey The API key for authentication.
+ * @param string|null $baseUrl The base URL for the API (optional).
+ * @param int|null $timeout The timeout duration for requests in seconds (optional).
+ * @return self A new instance of the DeepseekClient.
+ */
+ public static function build(string $apiKey, ?string $baseUrl = null, ?int $timeout = null): self
+ {
+ $httpClient = ApiFactory::build()
+ ->setBaseUri($baseUrl)
+ ->setTimeout($timeout)
+ ->setKey($apiKey)
+ ->run();
+
+ return new self($httpClient);
+ }
+
+ /**
+ * Add a query to the accumulated queries list.
+ *
+ * @param string $content
+ * @param string|null $role
+ * @return self The current instance for method chaining.
+ */
+ public function query(string $content, ?string $role = null): self
+ {
+ $this->queries[] = $this->buildQuery($content, $role);
+ return $this;
+ }
+
+ /**
+ * Set the model to be used for API requests.
+ *
+ * @param string|null $model The model name (optional).
+ * @return self The current instance for method chaining.
+ */
+ public function withModel(?string $model = null): self
+ {
+ $this->model = $model;
+ return $this;
+ }
+
+ /**
+ * Enable or disable streaming for API responses.
+ *
+ * @param bool $stream Whether to enable streaming (default: true).
+ * @return self The current instance for method chaining.
+ */
+ public function withStream(bool $stream = true): self
+ {
+ $this->stream = $stream;
+ return $this;
+ }
+
+ protected function buildQuery(string $content, ?string $role = null): array
+ {
+ return [
+ 'role' => $role ?: QueryRoles::USER->value,
+ 'content' => $content
+ ];
+ }
+
+}
diff --git a/src/Enums/Configs/DefaultConfigs.php b/src/Enums/Configs/DefaultConfigs.php
new file mode 100644
index 0000000..871cf8d
--- /dev/null
+++ b/src/Enums/Configs/DefaultConfigs.php
@@ -0,0 +1,11 @@
+baseUrl = $baseUrl ? trim($baseUrl) : DefaultConfigs::BASE_URL->value;
+ return $this;
+ }
+
+ /**
+ * Set the API key for authentication.
+ *
+ * @param string $apiKey The API key to set.
+ * @return self The instance of the self for method chaining.
+ */
+ public function setKey(string $apiKey): self
+ {
+ $this->apiKey = trim($apiKey);
+ return $this;
+ }
+
+ /**
+ * Set the timeout for the API request.
+ *
+ * If no timeout is provided, the default timeout value from the configuration is used.
+ *
+ * @param int|null $timeout The timeout value in seconds (optional).
+ * @return self The instance of the self for method chaining.
+ */
+ public function setTimeout(?int $timeout = null): self
+ {
+ $this->timeout = $timeout ?: (int)DefaultConfigs::TIMEOUT->value;
+ return $this;
+ }
+
+ /**
+ * Build and return the Guzzle Client instance.
+ *
+ * This method creates and configures a new Guzzle HTTP client instance
+ * using the provided base URL, timeout, and headers.
+ *
+ * @return Client A Guzzle client instance configured for the API.
+ */
+ public function run(): Client
+ {
+ $clientConfig = [
+ HeaderFlags::BASE_URL->value => $this->baseUrl,
+ HeaderFlags::TIMEOUT->value => $this->timeout,
+ HeaderFlags::HEADERS->value => [
+ HeaderFlags::AUTHORIZATION->value => 'Bearer ' . $this->apiKey,
+ HeaderFlags::CONTENT_TYPE->value => "application/json",
+ ],
+ ];
+
+ return new Client($clientConfig);
+ }
+}
diff --git a/src/Resources/Chat.php b/src/Resources/Chat.php
new file mode 100644
index 0000000..fe0ebda
--- /dev/null
+++ b/src/Resources/Chat.php
@@ -0,0 +1,10 @@
+value;
+ }
+}
diff --git a/src/Resources/Resource.php b/src/Resources/Resource.php
new file mode 100644
index 0000000..4e86a50
--- /dev/null
+++ b/src/Resources/Resource.php
@@ -0,0 +1,150 @@
+client = $client;
+ }
+
+ /**
+ * Send a request to the API endpoint.
+ *
+ * This method sends a POST request to the API endpoint, including the query data
+ * and custom headers, and returns the response body as a string.
+ *
+ * @param array $requestData The data to send in the request.
+ * @return string The response body.
+ *
+ * @throws \RuntimeException If the request fails.
+ */
+ public function sendRequest(array $requestData): string
+ {
+ try {
+ $response = $this->client->post($this->getEndpointSuffix(), [
+ 'json' => $this->resolveHeaders($requestData),
+ ]);
+
+ return $response->getBody()->getContents();
+ } catch (GuzzleException $e) {
+ throw new \RuntimeException("Deepseek API request failed: " . $e->getMessage());
+ }
+ }
+
+ /**
+ * Merge request data with default headers.
+ *
+ * This method merges the given query data with custom headers that are
+ * prepared for the request.
+ *
+ * @param array $requestData The data to send in the request.
+ * @return array The merged request data with default headers.
+ */
+ protected function resolveHeaders(array $requestData): array
+ {
+ return array_merge($requestData, $this->prepareCustomHeaderParams($requestData));
+ }
+
+ /**
+ * Prepare the custom headers for the request.
+ *
+ * This method loops through the query parameters and applies the appropriate
+ * type conversion before returning the final headers.
+ *
+ * @param array $query The data to send in the request.
+ * @return array The custom headers for the request.
+ */
+ public function prepareCustomHeaderParams(array $query): array
+ {
+ $headers = [];
+ $params = $this->getAllowedQueryParamsList();
+
+ // Loop through the parameters and apply the conversion logic dynamically
+ foreach ($params as $key => $type) {
+ $headers[$key] = $this->getQueryParam($query, $key, $this->getDefaultForKey($key), $type);
+ }
+
+ return $headers;
+ }
+
+ /**
+ * Get the endpoint suffix for the resource.
+ *
+ * This method returns the endpoint suffix that is used in the API URL.
+ *
+ * @return string The endpoint suffix.
+ */
+ public function getEndpointSuffix(): string
+ {
+ return EndpointSuffixes::CHAT->value;
+ }
+
+ /**
+ * Get the model associated with the resource.
+ *
+ * This method returns the default model value associated with the resource.
+ *
+ * @return string The default model value.
+ */
+ public function getDefaultModel(): string
+ {
+ return Models::CHAT->value;
+ }
+
+ /**
+ * Check if stream is enabled or not.
+ *
+ * This method checks whether the streaming option is enabled based on the
+ * default configuration.
+ *
+ * @return bool True if streaming is enabled, false otherwise.
+ */
+ public function getDefaultStream(): bool
+ {
+ return DefaultConfigs::STREAM->value === 'true';
+ }
+
+ /**
+ * Get the list of query parameters and their corresponding types for conversion.
+ *
+ * This method returns an array of query keys and their associated data types
+ * for use in preparing the custom headers.
+ *
+ * @return array An associative array of query keys and their data types.
+ */
+ protected function getAllowedQueryParamsList(): array
+ {
+ return [
+ QueryFlags::MODEL->value => DataTypes::STRING->value,
+ QueryFlags::STREAM->value => DataTypes::BOOL->value,
+ ];
+ }
+}
diff --git a/src/Traits/Queries/HasQueryParams.php b/src/Traits/Queries/HasQueryParams.php
new file mode 100644
index 0000000..453c7bb
--- /dev/null
+++ b/src/Traits/Queries/HasQueryParams.php
@@ -0,0 +1,75 @@
+convertValue($value, $type);
+ }
+
+ return $default;
+ }
+
+ /**
+ * Convert the value to the specified type.
+ *
+ * @param mixed $value
+ * @param string $type
+ * @return mixed
+ */
+ private function convertValue($value, string $type): mixed
+ {
+ switch ($type) {
+ case DataTypes::STRING->value:
+ return (string) $value;
+ case DataTypes::INTEGER->value:
+ return (int) $value;
+ case DataTypes::FLOAT->value:
+ return (float) $value;
+ case DataTypes::ARRAY->value:
+ return (array) $value;
+ case DataTypes::OBJECT->value:
+ return (object) $value;
+ case DataTypes::BOOL->value:
+ return (bool) $value;
+ case DataTypes::JSON->value:
+ return json_decode((string) $value, true);
+ default:
+ return $value;
+ }
+ }
+
+ /**
+ * Get default value for specific query keys.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ private function getDefaultForKey(string $key): mixed
+ {
+ switch ($key) {
+ case QueryFlags::MODEL->value:
+ return $this->getDefaultModel();
+ case QueryFlags::STREAM->value:
+ return $this->getDefaultStream();
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/Traits/Resources/HasChat.php b/src/Traits/Resources/HasChat.php
new file mode 100644
index 0000000..29ae330
--- /dev/null
+++ b/src/Traits/Resources/HasChat.php
@@ -0,0 +1,24 @@
+ $this->queries,
+ 'model' => $this->model,
+ 'stream' => $this->stream,
+ ];
+ $this->queries = [];
+ return (new Chat($this->httpClient))->sendRequest($requestData);
+ }
+}
diff --git a/src/Traits/Resources/HasCoder.php b/src/Traits/Resources/HasCoder.php
new file mode 100644
index 0000000..600b92b
--- /dev/null
+++ b/src/Traits/Resources/HasCoder.php
@@ -0,0 +1,24 @@
+ $this->queries,
+ 'model' => $this->model,
+ 'stream' => $this->stream,
+ ];
+ $this->queries = [];
+ return (new Coder($this->httpClient))->sendRequest($requestData);
+ }
+}
diff --git a/tests/DeepseekTest.php b/tests/DeepseekTest.php
new file mode 100644
index 0000000..e97639e
--- /dev/null
+++ b/tests/DeepseekTest.php
@@ -0,0 +1,9 @@
+