├── .gitignore ├── src ├── Responses │ ├── StreamChunked.php │ ├── StreamResponse.php │ └── Response.php ├── DifyException.php ├── Dify.php ├── Apps │ ├── Completion.php │ ├── App.php │ ├── Chat.php │ └── Dataset.php ├── Utils.php ├── Client.php └── Factory.php ├── composer.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | vendor 3 | .idea 4 | .vscode 5 | -------------------------------------------------------------------------------- /src/Responses/StreamChunked.php: -------------------------------------------------------------------------------- 1 | event = $chunk['event']; 23 | $this->data = $chunk; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simonetoo/dify-php", 3 | "description": "This is the PHP SDK for the Dify API.", 4 | "keywords": [ 5 | "php", 6 | "dify", 7 | "sdk" 8 | ], 9 | "license": "MIT", 10 | "autoload": { 11 | "psr-4": { 12 | "Simonetoo\\Dify\\": "src/" 13 | } 14 | }, 15 | "autoload-dev": { 16 | "psr-4": { 17 | "Tests\\": "tests/" 18 | } 19 | }, 20 | "authors": [ 21 | { 22 | "name": "Simon" 23 | } 24 | ], 25 | "require": { 26 | "php": "^7.2|^8.0", 27 | "guzzlehttp/guzzle": "^7.8", 28 | "ext-json": "*" 29 | }, 30 | "minimum-stability": "dev", 31 | "prefer-stable": true, 32 | "config": { 33 | "sort-packages": true, 34 | "preferred-install": "dist" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/DifyException.php: -------------------------------------------------------------------------------- 1 | context = array_merge($this->context, $context); 41 | } else if (is_string($context)) { 42 | $this->context[$context] = $value; 43 | } 44 | return $this; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Dify.php: -------------------------------------------------------------------------------- 1 | parameters(); 37 | 38 | // Get the app meta information. 39 | $response = $chat->meta('user-id'); 40 | 41 | // Send a request to the chat application. 42 | $response = $chat->send('user-id', 'Hello World!'); 43 | 44 | // Send a request to the chat application with enable streaming mode. 45 | $streamResponse = $chat->stream('user-id','hello World!'); 46 | 47 | // Provide feedback for a message 48 | $response = $chat->messageFeedback('user-id','message-id','like or dislike'); 49 | 50 | // Other methods: 51 | // $chat->suggested(); 52 | // $chat->conversations(); 53 | // $chat->messages(); 54 | // .... 55 | // 56 | 57 | ``` 58 | 59 | Replace 'your-api-key-here' with your actual Dify API key. 60 | 61 | 62 | ## License 63 | 64 | This SDK is released under the MIT License. 65 | -------------------------------------------------------------------------------- /src/Responses/StreamResponse.php: -------------------------------------------------------------------------------- 1 | response = $response; 27 | } 28 | 29 | /** 30 | * {@inheritDoc} 31 | */ 32 | public function getIterator(): Generator 33 | { 34 | while (!$this->response->getBody()->eof()) { 35 | $line = $this->readLine($this->response->getBody()); 36 | 37 | if (strpos($line, 'data:') !== 0) { 38 | continue; 39 | } 40 | 41 | $response = json_decode(trim(substr($line, strlen('data:'))), true); 42 | if (empty($response['event'])) { 43 | throw new DifyException('Stream data parse error:' . $line); 44 | } 45 | 46 | yield new StreamChunked($response); 47 | } 48 | } 49 | 50 | /** 51 | * Read a line from the stream. 52 | */ 53 | private function readLine(StreamInterface $stream): string 54 | { 55 | $buffer = ''; 56 | 57 | while (!$stream->eof()) { 58 | if ('' === ($byte = $stream->read(1))) { 59 | return $buffer; 60 | } 61 | $buffer .= $byte; 62 | if ($byte === "\n") { 63 | break; 64 | } 65 | } 66 | 67 | return $buffer; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Apps/Completion.php: -------------------------------------------------------------------------------- 1 | client->postJson('completion-messages', array_merge([ 22 | 'inputs' => [], 23 | ], $parameters, [ 24 | 'user' => $userId, 25 | 'response_mode' => 'blocking', 26 | ])); 27 | } 28 | 29 | /** 30 | * Send a request to the chat application with enable streaming mode. 31 | * 32 | * @param string $userId 33 | * @param string $query 34 | * @param array $parameters 35 | * @return StreamResponse 36 | */ 37 | public function stream(string $userId, array $parameters = []): StreamResponse 38 | { 39 | $response = $this->client->postJson('completion-messages', array_merge([ 40 | 'inputs' => [], 41 | ], $parameters, [ 42 | 'user' => $userId, 43 | 'response_mode' => 'streaming', 44 | ]), ['stream' => true])->throwIfHttpFailed(); 45 | return new StreamResponse($response); 46 | } 47 | 48 | /** 49 | * Stop generate 50 | * Only supported in streaming mode. 51 | * 52 | * @param string $userId 53 | * @param string $taskId 54 | * @return Response 55 | */ 56 | public function stop(string $userId, string $taskId): Response 57 | { 58 | return $this->client->postJson("completion-messages/{$taskId}/stop", [ 59 | 'user' => $userId 60 | ]); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Utils.php: -------------------------------------------------------------------------------- 1 | $segment) { 51 | unset($key[$i]); 52 | 53 | if (is_null($segment)) { 54 | return $target; 55 | } 56 | 57 | if ($segment === '*') { 58 | if (!is_iterable($target)) { 59 | return static::value($default); 60 | } 61 | 62 | $result = []; 63 | 64 | foreach ($target as $item) { 65 | $result[] = static::arrayGet($item, $key); 66 | } 67 | 68 | return in_array('*', $key) ? static::arrayCollapse($result) : $result; 69 | } 70 | 71 | if ((is_array($target) && array_key_exists($segment, $target)) || ($target instanceof ArrayAccess && $target->offsetExists($segment))) { 72 | $target = $target[$segment]; 73 | } elseif (is_object($target) && isset($target->{$segment})) { 74 | $target = $target->{$segment}; 75 | } else { 76 | return static::value($default); 77 | } 78 | } 79 | 80 | return $target; 81 | } 82 | 83 | /** 84 | * Return the default value of the given value. 85 | * 86 | * @param $value 87 | * @param ...$args 88 | * @return mixed 89 | */ 90 | public static function value($value, ...$args) 91 | { 92 | return $value instanceof Closure ? $value(...$args) : $value; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | client = $client; 23 | } 24 | 25 | /** 26 | * Send a request. 27 | * 28 | * @param string $method 29 | * @param string $uri 30 | * @param array $options 31 | * @return Response 32 | * @throws DifyException 33 | */ 34 | public function request(string $method, string $uri, array $options = []): Response 35 | { 36 | try { 37 | $response = $this->client->request($method, $uri, $options); 38 | return new Response($response); 39 | } catch (ClientException $exception) { 40 | if ($exception->hasResponse()) { 41 | return new Response($exception->getResponse()); 42 | } 43 | throw new DifyException($exception->getMessage(), $exception->getCode(), $exception); 44 | } catch (\Throwable $exception) { 45 | throw new DifyException($exception->getMessage(), $exception->getCode(), $exception); 46 | } 47 | } 48 | 49 | /** 50 | * Send a get request. 51 | * 52 | * @param string $uri 53 | * @param array $query 54 | * @param array $options 55 | * @return Response 56 | */ 57 | public function get(string $uri, array $query = [], array $options = []): Response 58 | { 59 | $options['query'] = $query; 60 | return $this->request('GET', $uri, $options); 61 | } 62 | 63 | /** 64 | * Send a post request with form-data. 65 | * 66 | * @param string $uri 67 | * @param array $data 68 | * @param array $options 69 | * @return Response 70 | */ 71 | public function postForm(string $uri, array $data = [], array $options = []): Response 72 | { 73 | $options['form_params'] = $data; 74 | return $this->request('POST', $uri, $options); 75 | } 76 | 77 | /** 78 | * Send a post request with json. 79 | * 80 | * @param string $uri 81 | * @param array $data 82 | * @param array $options 83 | * @return Response 84 | */ 85 | public function postJson(string $uri, array $data = [], array $options = []): Response 86 | { 87 | $options['json'] = $data; 88 | return $this->request('POST', $uri, $options); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Apps/App.php: -------------------------------------------------------------------------------- 1 | client = $client; 27 | } 28 | 29 | /** 30 | * Get the dify app information. 31 | * 32 | * @return Response 33 | */ 34 | public function parameters(): Response 35 | { 36 | return $this->client->get('parameters'); 37 | } 38 | 39 | /** 40 | * Provide feedback for a message. 41 | * 42 | * @param string $userId 43 | * @param string $messageId 44 | * @param string|null $rating 45 | * @return Response 46 | */ 47 | public function messageFeedback(string $userId, string $messageId, string $rating = null): Response 48 | { 49 | return $this->client->postJson("messages/{$messageId}/feedbacks", [ 50 | 'user' => $userId, 51 | 'rating' => $rating 52 | ]); 53 | } 54 | 55 | /** 56 | * Upload a file (currently only images are supported) for use when sending messages, enabling multimodal understanding of images and text. 57 | * Supports png, jpg, jpeg, webp, gif formats. 58 | * Uploaded files are for use by the current end-user only. 59 | * 60 | * @param string $userId 61 | * @param string $path 62 | * @param string $filename 63 | * @return Response 64 | */ 65 | public function fileUpload(string $userId, string $path, string $filename): Response 66 | { 67 | $multipart = [ 68 | [ 69 | 'name' => 'user', 70 | 'contents' => $userId 71 | ], 72 | [ 73 | 'name' => 'file', 74 | 'contents' => fopen($path, 'r+'), 75 | 'filename' => $filename 76 | ] 77 | ]; 78 | return $this->client->request('POST', 'files/upload', [ 79 | 'multipart' => $multipart 80 | ]); 81 | } 82 | 83 | /** 84 | * Text to speech. 85 | * 86 | * @param string $userId 87 | * @param string $text 88 | * @return Response 89 | */ 90 | public function textToAudio(string $userId, string $text): Response 91 | { 92 | return $this->client->postJson('text-to-audio', [ 93 | 'text' => $text, 94 | 'user' => $userId, 95 | 'streaming' => false 96 | ]); 97 | } 98 | 99 | /** 100 | * Text to speech with enable streaming output. 101 | * 102 | * @param string $userId 103 | * @param string $text 104 | * @return StreamResponse 105 | */ 106 | public function textToAudioStream(string $userId, string $text): StreamResponse 107 | { 108 | $response = $this->client->postJson('text-to-audio', [ 109 | 'text' => $text, 110 | 'user' => $userId, 111 | 'streaming' => true 112 | ]); 113 | return new StreamResponse($response); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Factory.php: -------------------------------------------------------------------------------- 1 | Dify::DEFAULT_BASE_URI, 21 | 'headers' => [] 22 | ]; 23 | 24 | /** 25 | * The guzzle http client middlewares. 26 | * 27 | * @var array 28 | */ 29 | protected $middlewares = []; 30 | 31 | /** 32 | * 33 | * @var Factory 34 | */ 35 | protected static $instance; 36 | 37 | /** 38 | * Get the single instance of factory. 39 | * 40 | * @return Factory 41 | */ 42 | public static function make(): Factory 43 | { 44 | if (is_null(static::$instance)) { 45 | static::$instance = new static; 46 | } 47 | return static::$instance; 48 | } 49 | 50 | /** 51 | * 52 | */ 53 | private function __construct() 54 | { 55 | 56 | } 57 | 58 | /** 59 | * Set a guzzle http client option. 60 | * 61 | * @param string $key 62 | * @param $value 63 | * @return $this 64 | */ 65 | public function setOption(string $key, $value): Factory 66 | { 67 | $this->options[$key] = $value; 68 | return $this; 69 | } 70 | 71 | /** 72 | * Set guzzle http client options. 73 | * 74 | * @param array $options 75 | * @return $this 76 | */ 77 | public function setOptions(array $options): Factory 78 | { 79 | $this->options = array_merge($this->options, $options); 80 | return $this; 81 | } 82 | 83 | /** 84 | * Set guzzle http client headers. 85 | * 86 | * @param array $headers 87 | * @return $this 88 | */ 89 | public function setHeaders(array $headers): Factory 90 | { 91 | $this->options['headers'] = array_merge($this->options['header'], $headers); 92 | return $this; 93 | } 94 | 95 | /** 96 | * Set a guzzle http client header. 97 | * 98 | * @param string $key 99 | * @param string $value 100 | * @return $this 101 | */ 102 | public function setHeader(string $key, string $value): Factory 103 | { 104 | $this->options['headers'][$key] = $value; 105 | return $this; 106 | } 107 | 108 | /** 109 | * @param string $key 110 | * @return $this 111 | */ 112 | public function removeHeader(string $key): Factory 113 | { 114 | unset($this->options['headers'][$key]); 115 | return $this; 116 | } 117 | 118 | /** 119 | * Set the dify base uri. 120 | * 121 | * @param string $baseUri 122 | * @return $this 123 | */ 124 | public function setBaseUri(string $baseUri): Factory 125 | { 126 | return $this->setOption('base_uri', $baseUri); 127 | } 128 | 129 | /** 130 | * Set a middleware for guzzle http client. 131 | * 132 | * @param callable $middleware 133 | * @return $this 134 | */ 135 | public function setMiddleware(callable $middleware): Factory 136 | { 137 | $this->middlewares[] = $middleware; 138 | return $this; 139 | } 140 | 141 | /** 142 | * Create a new client. 143 | * 144 | * @return Client 145 | */ 146 | public function create(): Client 147 | { 148 | $handler = $this->options['handler'] ?? HandlerStack::create(); 149 | foreach ($this->middlewares as $middleware) { 150 | $handler->push($middleware); 151 | } 152 | return new Client(new GuzzleClient($this->options)); 153 | } 154 | 155 | /** 156 | * Create a new client with api key. 157 | * @param string $apiKey 158 | * @return Client 159 | */ 160 | public function createWithApiKey(string $apiKey): Client 161 | { 162 | $authorization = $this->options['headers']['Authorization'] ?? []; 163 | $this->options['headers']['Authorization'] = 'Bearer ' . $apiKey; 164 | $client = $this->create(); 165 | if (!empty($authorization)) { 166 | $this->options['headers']['Authorization'] = $authorization; 167 | } 168 | return $client; 169 | } 170 | 171 | /** 172 | * Create a chat app. 173 | * 174 | * @param string $apiKey 175 | * @return Chat 176 | */ 177 | public function chat(string $apiKey): Chat 178 | { 179 | return new Chat($this->createWithApiKey($apiKey)); 180 | } 181 | 182 | /** 183 | * Create a completion app. 184 | * 185 | * @param string $apiKey 186 | * @return Completion 187 | */ 188 | public function completion(string $apiKey): Completion 189 | { 190 | return new Completion($this->createWithApiKey($apiKey)); 191 | } 192 | /** 193 | * Create a dataset app. 194 | * 195 | * @param string $apiKey 196 | * @return Dataset 197 | */ 198 | public function dataset(string $apiKey): Dataset 199 | { 200 | return new Dataset($this->createWithApiKey($apiKey)); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/Apps/Chat.php: -------------------------------------------------------------------------------- 1 | client->get('meta', [ 20 | 'user' => $userId 21 | ]); 22 | } 23 | 24 | /** 25 | * Stop generate 26 | * Only supported in streaming mode. 27 | * 28 | * @param string $taskId 29 | * @param string $userId 30 | * @return Response 31 | */ 32 | public function stop(string $userId, string $taskId): Response 33 | { 34 | return $this->client->postJson('chat-message/' . $taskId . '/stop', [ 35 | 'user' => $userId 36 | ]); 37 | } 38 | 39 | /** 40 | * Send a request to the chat application. 41 | * 42 | * @param string $userId 43 | * @param string $query 44 | * @param array $parameters 45 | * @return Response 46 | */ 47 | public function send(string $userId, string $query, array $parameters = []): Response 48 | { 49 | return $this->client->postJson('chat-messages', array_merge([ 50 | 'inputs' => [], 51 | ], $parameters, [ 52 | 'user' => $userId, 53 | 'query' => $query, 54 | 'response_mode' => 'blocking', 55 | ])); 56 | } 57 | 58 | /** 59 | * Send a request to the chat application with enable streaming mode. 60 | * 61 | * @param string $userId 62 | * @param string $query 63 | * @param array $parameters 64 | * @return StreamResponse 65 | */ 66 | public function stream(string $userId, string $query, array $parameters = []): StreamResponse 67 | { 68 | $response = $this->client->postJson('chat-messages', array_merge([ 69 | 'inputs' => [], 70 | ], $parameters, [ 71 | 'user' => $userId, 72 | 'query' => $query, 73 | 'response_mode' => 'streaming', 74 | ]), ['stream' => true])->throwIfHttpFailed(); 75 | return new StreamResponse($response); 76 | } 77 | 78 | /** 79 | * Get next questions suggestions for the current message. 80 | * 81 | * @param string $userId 82 | * @param string $messageId 83 | * @return Response 84 | */ 85 | public function suggested(string $userId, string $messageId): Response 86 | { 87 | return $this->client->get("messages/{$messageId}/suggested", [ 88 | 'user' => $userId 89 | ]); 90 | } 91 | 92 | /** 93 | * Get conversation history messages. 94 | * 95 | * @param string $userId 96 | * @param string $conversationId 97 | * @param array $parameters 98 | * @return Response 99 | */ 100 | public function messages(string $userId, string $conversationId, array $parameters = []): Response 101 | { 102 | return $this->client->get('messages', array_merge($parameters, [ 103 | 'conversation_id' => $conversationId, 104 | 'user' => $userId, 105 | ])); 106 | } 107 | 108 | /** 109 | * Get conversations. 110 | * 111 | * @param string $userId 112 | * @param array $parameters 113 | * @return Response 114 | */ 115 | public function conversations(string $userId, array $parameters = []): Response 116 | { 117 | return $this->client->get('conversations', array_merge($parameters, [ 118 | 'user' => $userId, 119 | ])); 120 | } 121 | 122 | /** 123 | * Conversation rename. 124 | * 125 | * @param string $userId 126 | * @param string $conversationId 127 | * @param string $name 128 | * @return Response 129 | */ 130 | public function conversationRename(string $userId, string $conversationId, string $name): Response 131 | { 132 | return $this->client->postJson("conversations/{$conversationId}/name", [ 133 | 'name' => $name, 134 | 'user' => $userId 135 | ]); 136 | } 137 | 138 | /** 139 | * Automatically generate the conversation name. 140 | * 141 | * @param string $userId 142 | * @param string $conversationId 143 | * @return Response 144 | */ 145 | public function conversationAutoGenerateName(string $userId, string $conversationId): Response 146 | { 147 | return $this->client->postJson("conversations/{$conversationId}/name", [ 148 | 'auto_generate' => true, 149 | 'user' => $userId 150 | ]); 151 | } 152 | 153 | /** 154 | * Delete a conversation. 155 | * 156 | * @param string $userId 157 | * @param string $conversationId 158 | * @return Response 159 | */ 160 | public function conversationDelete(string $userId, string $conversationId): Response 161 | { 162 | return $this->client->request('DELETE', "conversations/{$conversationId}", [ 163 | 'json' => [ 164 | 'user' => $userId 165 | ] 166 | ]); 167 | } 168 | 169 | /** 170 | * Speech to text. 171 | * 172 | * @param string $userId 173 | * @param string $filePath 174 | * @param string $filename 175 | * @return Response 176 | */ 177 | public function audioToText(string $userId, string $filePath, string $filename): Response 178 | { 179 | return $this->client->request('POST', 'audio-to-text', [ 180 | 'multipart' => [ 181 | [ 182 | 'name' => 'file', 183 | 'contents' => fopen($filePath, 'r'), 184 | 'filename' => $filename 185 | ], 186 | [ 187 | 'name' => 'user', 188 | 'contents' => $userId 189 | ] 190 | ] 191 | 192 | ]); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/Responses/Response.php: -------------------------------------------------------------------------------- 1 | response = $baseResponse; 36 | } 37 | 38 | /** 39 | * Get the PSR Response instance. 40 | * 41 | * @return ResponseInterface 42 | */ 43 | public function getPsrResponse(): ResponseInterface 44 | { 45 | return $this->response; 46 | } 47 | 48 | /** 49 | * Get the body of the response. 50 | * 51 | * @return string 52 | */ 53 | public function body(): string 54 | { 55 | return (string)$this->response->getBody(); 56 | } 57 | 58 | /** 59 | * Get the JSON decoded body of the response as an array or scalar value. 60 | * 61 | * @param string|null $key 62 | * @param mixed $default 63 | * @return mixed 64 | */ 65 | public function json(string $key = null, $default = null) 66 | { 67 | if (!$this->decoded) { 68 | $this->decoded = json_decode($this->body(), true); 69 | } 70 | 71 | if (is_null($key)) { 72 | return $this->decoded; 73 | } 74 | 75 | return Utils::arrayGet($this->decoded, $key, $default); 76 | } 77 | 78 | /** 79 | * Get the JSON decoded body of the response as an object. 80 | * 81 | * @return object|null 82 | */ 83 | public function object(): ?object 84 | { 85 | return (object)$this->json(); 86 | } 87 | 88 | /** 89 | * 90 | * @return bool 91 | */ 92 | public function isHttpSuccessful(): bool 93 | { 94 | return $this->getStatusCode() === 200; 95 | } 96 | 97 | /** 98 | * 99 | * @return bool 100 | */ 101 | public function isSuccessful(): bool 102 | { 103 | return $this->isHttpSuccessful() && $this->json('code') === null; 104 | } 105 | 106 | /** 107 | * 108 | * @return bool 109 | */ 110 | public function isFailed(): bool 111 | { 112 | return !$this->isSuccessful(); 113 | } 114 | 115 | /** 116 | * Throw an exception if a http error occurred. 117 | * 118 | * @return $this 119 | */ 120 | public function throwIfHttpFailed(): Response 121 | { 122 | if (!$this->isHttpSuccessful()) { 123 | throw new DifyException($this->json('message') ?? $this->getReasonPhrase(), $this->json('status') ?? $this->getStatusCode()); 124 | } 125 | return $this; 126 | } 127 | 128 | /** 129 | * Throw an exception if a http or server error occurred. 130 | * 131 | * @return $this 132 | */ 133 | public function throwIfFailed(): Response 134 | { 135 | if ($this->isFailed()) { 136 | throw new DifyException($this->json('message') ?? $this->getReasonPhrase(), $this->json('status') ?? $this->getStatusCode()); 137 | } 138 | return $this; 139 | } 140 | 141 | /** 142 | * Get the http status code. 143 | * 144 | * @return int 145 | */ 146 | public function getStatusCode(): int 147 | { 148 | return $this->response->getStatusCode(); 149 | } 150 | 151 | /** 152 | * Return an instance with the specified status code and, optionally, reason phrase. 153 | * 154 | * @param int $code status code 155 | * @param string $reasonPhrase reason phrase 156 | * @return ResponseInterface 157 | */ 158 | public function withStatus(int $code, string $reasonPhrase = ''): ResponseInterface 159 | { 160 | $this->response = $this->response->withStatus($code, $reasonPhrase); 161 | 162 | return $this; 163 | } 164 | 165 | /** 166 | * Gets the response reason phrase associated with the status code. 167 | * @return string 168 | */ 169 | public function getReasonPhrase(): string 170 | { 171 | return $this->response->getReasonPhrase(); 172 | } 173 | 174 | /** 175 | * @return string 176 | */ 177 | public function getProtocolVersion(): string 178 | { 179 | return $this->response->getProtocolVersion(); 180 | } 181 | 182 | /** 183 | * @param string $version 184 | * @return MessageInterface 185 | */ 186 | public function withProtocolVersion(string $version): MessageInterface 187 | { 188 | $this->response = $this->response->withProtocolVersion($version); 189 | return $this; 190 | } 191 | 192 | /** 193 | * @return array|\string[][] 194 | */ 195 | public function getHeaders(): array 196 | { 197 | return $this->response->getHeaders(); 198 | } 199 | 200 | /** 201 | * @param string $name 202 | * @return bool 203 | */ 204 | public function hasHeader(string $name): bool 205 | { 206 | return $this->response->hasHeader($name); 207 | } 208 | 209 | /** 210 | * @param string $name 211 | * @return array|string[] 212 | */ 213 | public function getHeader(string $name): array 214 | { 215 | return $this->response->getHeader($name); 216 | } 217 | 218 | /** 219 | * @param string $name 220 | * @return string 221 | */ 222 | public function getHeaderLine(string $name): string 223 | { 224 | return $this->response->getHeaderLine($name); 225 | } 226 | 227 | /** 228 | * @param string $name 229 | * @param $value 230 | * @return MessageInterface 231 | */ 232 | public function withHeader(string $name, $value): MessageInterface 233 | { 234 | $this->response = $this->withHeader($name, $value); 235 | return $this; 236 | } 237 | 238 | /** 239 | * @param string $name 240 | * @param $value 241 | * @return MessageInterface 242 | */ 243 | public function withAddedHeader(string $name, $value): MessageInterface 244 | { 245 | $this->response = $this->withAddedHeader($name, $value); 246 | return $this; 247 | } 248 | 249 | /** 250 | * @param string $name 251 | * @return MessageInterface 252 | */ 253 | public function withoutHeader(string $name): MessageInterface 254 | { 255 | $this->response = $this->withoutHeader($name); 256 | return $this; 257 | } 258 | 259 | /** 260 | * @return StreamInterface 261 | */ 262 | public function getBody(): StreamInterface 263 | { 264 | return $this->response->getBody(); 265 | } 266 | 267 | /** 268 | * @param StreamInterface $body 269 | * @return MessageInterface 270 | */ 271 | public function withBody(StreamInterface $body): MessageInterface 272 | { 273 | $this->response = $this->withBody($body); 274 | return $this; 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/Apps/Dataset.php: -------------------------------------------------------------------------------- 1 | client->get("datasets", ['page' => $page, 'limit' => $limit]); 21 | } 22 | /** 23 | * Summary of createDataset 24 | * @param string $name 25 | * @return \Simonetoo\Dify\Responses\Response 26 | */ 27 | public function createDataset(string $name): Response 28 | { 29 | return $this->client->postJson("datasets", [ 30 | 'name' => $name 31 | ]); 32 | } 33 | /** 34 | * Summary of deleteDataset 35 | * @param string $dataset_id 36 | * @return \Simonetoo\Dify\Responses\Response 37 | */ 38 | public function deleteDataset(string $dataset_id): Response 39 | { 40 | return $this->client->request("DELETE","datasets/{$dataset_id}"); 41 | } 42 | /** 43 | * Summary of createDocumentByText 44 | * @param string $dataset_id 45 | * @param string $name 46 | * @param string $text 47 | * @param string $indexing_technique 48 | * @param array $process_rule 49 | * @return \Simonetoo\Dify\Responses\Response 50 | */ 51 | public function createDocumentByText(string $dataset_id, string $name, string $text, string $indexing_technique = "high_quality", array $process_rule = []): Response 52 | { 53 | $process_rule = $this->getProcessRule($process_rule); 54 | return $this->client->postJson("datasets/{$dataset_id}/document/create_by_text", [ 55 | 'name' => $name, 56 | 'text' => $text, 57 | 'indexing_technique' => $indexing_technique, 58 | 'process_rule' => $process_rule, 59 | ]); 60 | } 61 | /** 62 | * Summary of updateDocumentByText 63 | * @param string $dataset_id 64 | * @param string $document_id 65 | * @param string $name 66 | * @param string $text 67 | * @param array $process_rule 68 | * @return \Simonetoo\Dify\Responses\Response 69 | */ 70 | public function updateDocumentByText(string $dataset_id, string $document_id, string $name, string $text, array $process_rule = []): Response 71 | { 72 | $process_rule = $this->getProcessRule($process_rule); 73 | return $this->client->postJson("datasets/{$dataset_id}/documents/{$document_id}/update_by_text", [ 74 | 'name' => $name, 75 | 'text' => $text, 76 | 'process_rule' => $process_rule, 77 | ]); 78 | } 79 | /** 80 | * Summary of createDocumentByFile 81 | * @param string $dataset_id 82 | * @param string $filename 83 | * @param string $filePath 84 | * @param string $indexing_technique 85 | * @param array $process_rule 86 | * @return \Simonetoo\Dify\Responses\Response 87 | */ 88 | public function createDocumentByFile(string $dataset_id, string $filename, string $filePath, string $indexing_technique = "high_quality", array $process_rule = []): Response 89 | { 90 | $process_rule = $this->getProcessRule($process_rule); 91 | $data = [ 92 | 'name' => $filename, 93 | 'indexing_technique' => $indexing_technique, 94 | 'process_rule' => $process_rule, 95 | ]; 96 | return $this->client->request('POST', "datasets/{$dataset_id}/document/create_by_file", [ 97 | 'multipart' => [ 98 | [ 99 | 'name' => 'file', 100 | 'contents' => fopen($filePath, 'r'), 101 | ], 102 | [ 103 | 'name' => 'data', 104 | 'contents' => json_encode($data) 105 | ] 106 | ] 107 | 108 | ]); 109 | } 110 | /** 111 | * Summary of updateDocumentByFile 112 | * @param string $dataset_id 113 | * @param string $document_id 114 | * @param string $filename 115 | * @param string $filePath 116 | * @param array $process_rule 117 | * @return \Simonetoo\Dify\Responses\Response 118 | */ 119 | public function updateDocumentByFile(string $dataset_id, string $document_id, string $filename, string $filePath, array $process_rule = []): Response 120 | { 121 | $process_rule = $this->getProcessRule($process_rule); 122 | $data = [ 123 | 'name' => $filename, 124 | 'process_rule' => $process_rule, 125 | ]; 126 | return $this->client->request('POST', "datasets/{$dataset_id}/documents/{$document_id}/update_by_file", [ 127 | 'multipart' => [ 128 | [ 129 | 'name' => 'file', 130 | 'contents' => fopen($filePath, 'r'), 131 | 'filename' => $filename 132 | ], 133 | [ 134 | 'name' => 'data', 135 | 'contents' => $data 136 | ] 137 | ] 138 | 139 | ]); 140 | } 141 | /** 142 | * Summary of deleteDocument 143 | * @param string $dataset_id 144 | * @param string $document_id 145 | * @return \Simonetoo\Dify\Responses\Response 146 | */ 147 | public function deleteDocument(string $dataset_id, string $document_id): Response 148 | { 149 | return $this->client->request('DELETE',"datasets/{$dataset_id}/documents/{$document_id}"); 150 | } 151 | /** 152 | * Summary of listDocument 153 | * @param string $dataset_id 154 | * @param string $keyword 155 | * @param int $page 156 | * @param int $limit 157 | * @return \Simonetoo\Dify\Responses\Response 158 | */ 159 | public function listDocument(string $dataset_id, string $keyword, int $page = 0, int $limit = 20): Response 160 | { 161 | return $this->client->get("datasets/{$dataset_id}/documents", [ 162 | "keyword" => $keyword, 163 | "page" => $page, 164 | "limit" => $limit, 165 | ]); 166 | } 167 | /** 168 | * Summary of getDocumentIndexStatus 169 | * @param string $dataset_id 170 | * @param string $batch 171 | * @return \Simonetoo\Dify\Responses\Response 172 | */ 173 | public function getDocumentIndexStatus(string $dataset_id, string $batch): Response 174 | { 175 | return $this->client->get("datasets/{$dataset_id}/documents/{$batch}/indexing-status"); 176 | } 177 | /** 178 | * Summary of createDocumentSegments 179 | * @param string $dataset_id 180 | * @param string $document_id 181 | * @param array $segments 182 | * @return \Simonetoo\Dify\Responses\Response 183 | */ 184 | public function createDocumentSegments(string $dataset_id, string $document_id, array $segments = []): Response 185 | { 186 | return $this->client->postJson("datasets/{$dataset_id}/documents/{$document_id}/segments", [ 187 | 'segments' => $segments, 188 | ]); 189 | } 190 | /** 191 | * Summary of listDocumentSegments 192 | * @param string $dataset_id 193 | * @param string $document_id 194 | * @param string $keyword 195 | * @return \Simonetoo\Dify\Responses\Response 196 | */ 197 | public function listDocumentSegments(string $dataset_id, string $document_id, string $keyword = null): Response 198 | { 199 | return $this->client->get("datasets/{$dataset_id}/documents/{$document_id}/segments", [ 200 | 'keyword' => $keyword, 201 | ]); 202 | } 203 | /** 204 | * Summary of updateDocumentSegment 205 | * @param string $dataset_id 206 | * @param string $document_id 207 | * @param string $segment_id 208 | * @param array $segment 209 | * @return \Simonetoo\Dify\Responses\Response 210 | */ 211 | public function updateDocumentSegment(string $dataset_id, string $document_id, string $segment_id, array $segment): Response 212 | { 213 | return $this->client->postJson("datasets/{$dataset_id}/documents/{$document_id}/segments/{$segment_id}", [ 214 | 'segment' => $segment 215 | ]); 216 | } 217 | /** 218 | * Summary of deleteDocumentSegment 219 | * @param string $dataset_id 220 | * @param string $document_id 221 | * @param string $segment_id 222 | * @return \Simonetoo\Dify\Responses\Response 223 | */ 224 | public function deleteDocumentSegment(string $dataset_id, string $document_id, string $segment_id): Response 225 | { 226 | return $this->client->request('DELETE',"datasets/{$dataset_id}/documents/{$document_id}/segments/{$segment_id}"); 227 | } 228 | /** 229 | * Summary of getProcessRule 230 | * @param array $process_rule 231 | * @return array 232 | */ 233 | public function getProcessRule(array $process_rule = []) { 234 | $process_rule = array_merge_recursive( 235 | [ 236 | 'mode' => "custom", 237 | 'rules' => [ 238 | "pre_processing_rules" => [ 239 | [ 240 | "id" => "remove_extra_spaces", 241 | "enabled" => true 242 | ], 243 | [ 244 | "id" => "remove_urls_emails", 245 | "enabled" => true 246 | ], 247 | ], 248 | "segmentation" => [ 249 | "separator" => "\n", 250 | "max_tokens" => 500 251 | ] 252 | ] 253 | ], 254 | $process_rule 255 | ); 256 | return $process_rule; 257 | } 258 | } 259 | --------------------------------------------------------------------------------