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
-
+
@@ -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';
}