diff --git a/README.md b/README.md index 1ec6776..dd35c2b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

DeepSeek PHP Client

🚀 Community-Driven PHP SDK for DeepSeek AI API Integration

- +

Latest Version @@ -29,6 +29,7 @@ - [Advanced Configuration](#advanced-configuration) - [Use with Symfony HttpClient](#use-with-symfony-httpclient) - [Get Models List](#get-models-list) + - [Function Calling](#function-calling) - [Framework Integration](#-framework-integration) - [🆕 Migration Guide](#-migration-guide) - [📝 Changelog](#-changelog) @@ -103,7 +104,7 @@ echo 'API Response:'.$response; ### Use with Symfony HttpClient the package already built with `symfony Http client`, if you need to use package with `symfony` Http Client , it is easy to achieve that, just pass `clientType:'symfony'` with `build` function. - + ex with symfony: ```php @@ -128,6 +129,42 @@ $response = DeepSeekClient::build('your-api-key') echo $response; // {"object":"list","data":[{"id":"deepseek-chat","object":"model","owned_by":"deepseek"},{"id":"deepseek-reasoner","object":"model","owned_by":"deepseek"}]} ``` +### Function Calling + +Function Calling allows the model to call external tools to enhance its capabilities. + +[please check original DeepSeek Doc](https://api-docs.deepseek.com/guides/function_calling) + +```php +use DeepSeek\DeepSeekClient; +use DeepSeek\Enums\Models; + +$response = DeepSeekClient::build('your-api-key') + ->withModel(Models::CHAT) + ->withTools([ + [ + 'type' => 'function', + 'function' => [ + 'name' => 'get_weather', + 'description' => 'Get weather of an location, the user shoud supply a location first', + 'parameters' => [ + 'type' => 'object', + 'properties' => [ + 'location' => [ + 'type' => 'string', + 'description' => 'The city and state, e.g. San Francisco, CA', + ], + ], + 'required' => ['location'], + ], + ], + ], + ]) + ->run(); + +echo 'API Response:'.$response; +```` + ### 🛠 Framework Integration ### [Laravel Deepseek Package](https://github.com/deepseek-php/deepseek-laravel) @@ -178,7 +215,7 @@ Click the button bellow or [join here](https://t.me/deepseek_php_community) to b ## 🔒 Security -**Report Vulnerabilities**: to [omaralwi2010@gmail.com](mailto:omaralwi2010@gmail.com) +**Report Vulnerabilities**: to [omaralwi2010@gmail.com](mailto:omaralwi2010@gmail.com) --- diff --git a/src/Contracts/ClientContract.php b/src/Contracts/ClientContract.php index 12172e3..8ebe15d 100644 --- a/src/Contracts/ClientContract.php +++ b/src/Contracts/ClientContract.php @@ -6,9 +6,9 @@ interface ClientContract { public function run(): string; public static function build(string $apiKey, ?string $baseUrl = null, ?int $timeout = null): self; - public function query(string $content, ?string $role = "user"): self; + public function query(?string $content = null, ?string $role = "user", ?string $toolCallId = null, ?array $toolCalls = null,): self; public function getModelsList(): self; public function withModel(?string $model = null): self; public function withStream(bool $stream = true): self; - public function buildQuery(string $content, ?string $role = null): array; + public function buildQuery(?string $content = null, ?string $role = null, ?string $toolCallId = null, ?array $toolCalls = null,): array; } diff --git a/src/DeepSeekClient.php b/src/DeepSeekClient.php index a8d7f01..0ba2843 100644 --- a/src/DeepSeekClient.php +++ b/src/DeepSeekClient.php @@ -58,6 +58,8 @@ class DeepSeekClient implements ClientContract protected ?string $endpointSuffixes; + protected array $tools = []; + /** * Initialize the DeepSeekClient with a PSR-compliant HTTP client. * @@ -81,6 +83,9 @@ public function run(): string QueryFlags::STREAM->value => $this->stream, QueryFlags::TEMPERATURE->value => $this->temperature, ]; + if (count($this->tools)) { + $requestData[QueryFlags::TOOLS->value] = $this->tools; + } // Clear queries after sending $this->queries = []; $this->setResult((new Resource($this->httpClient, $this->endpointSuffixes))->sendRequest($requestData, $this->requestMethod)); @@ -111,13 +116,20 @@ public static function build(string $apiKey, ?string $baseUrl = null, ?int $time /** * Add a query to the accumulated queries list. * - * @param string $content + * @param string|null $content * @param string|null $role + * @param string|null $toolCallId + * @param array|null $toolCalls * @return self The current instance for method chaining. */ - public function query(string $content, ?string $role = "user"): self + public function query( + ?string $content = null, + ?string $role = null, + ?string $toolCallId = null, + ?array $toolCalls = null, + ): self { - $this->queries[] = $this->buildQuery($content, $role); + $this->queries[] = $this->buildQuery($content, $role, $toolCallId, $toolCalls); return $this; } @@ -163,12 +175,33 @@ public function setTemperature(float $temperature): self return $this; } - public function buildQuery(string $content, ?string $role = null): array + public function setTools(array $tools): self + { + $this->tools = $tools; + return $this; + } + + public function buildQuery( + ?string $content = null, + ?string $role = null, + ?string $toolCallId = null, + ?array $toolCalls = null, +): array { - return [ + $query = [ 'role' => $role ?: QueryRoles::USER->value, - 'content' => $content ]; + if ($content !== null) { + $query['content'] = $content; + } + if ($toolCallId !== null) { + $query['tool_call_id'] = $toolCallId; + } + if ($toolCalls !== null) { + $query['tool_calls'] = $toolCalls; + } + + return $query; } /** diff --git a/src/Enums/Queries/QueryRoles.php b/src/Enums/Queries/QueryRoles.php index 4659084..a23925c 100644 --- a/src/Enums/Queries/QueryRoles.php +++ b/src/Enums/Queries/QueryRoles.php @@ -6,4 +6,6 @@ enum QueryRoles: string { case USER = 'user'; case SYSTEM = 'system'; + case ASSISTANT = 'assistant'; + case TOOL = 'tool'; } diff --git a/src/Enums/Requests/QueryFlags.php b/src/Enums/Requests/QueryFlags.php index 19c1cdd..0e2b49a 100644 --- a/src/Enums/Requests/QueryFlags.php +++ b/src/Enums/Requests/QueryFlags.php @@ -8,4 +8,5 @@ enum QueryFlags: string case MODEL = 'model'; case STREAM = 'stream'; case TEMPERATURE = 'temperature'; + case TOOLS = 'tools'; }