Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/sdk vision support #1531

Merged
merged 11 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/controllers/service_api/app/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def post(self, app_model, end_user):
if 'file' not in request.files:
raise NoFileUploadedError()

if not file.mimetype:
raise UnsupportedFileTypeError()

if len(request.files) > 1:
raise TooManyFilesError()

Expand Down
20 changes: 13 additions & 7 deletions sdks/nodejs-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,33 @@ import { DifyClient, ChatClient, CompletionClient } from 'dify-client'

const API_KEY = 'your-api-key-here'
const user = `random-user-id`
const inputs = {
name: 'test name a'
}
const query = "Please tell me a short story in 10 words or less."
const query = 'Please tell me a short story in 10 words or less.'
const remote_url_files = [{
type: 'image',
transfer_method: 'remote_url',
url: 'your_url_addresss'
}]

// Create a completion client
const completionClient = new CompletionClient(API_KEY)
// Create a completion message
completionClient.createCompletionMessage(inputs, query, responseMode, user)
completionClient.createCompletionMessage({'query': query}, user)
// Create a completion message with vision model
completionClient.createCompletionMessage({'query': 'Describe the picture.'}, user, false, remote_url_files)

// Create a chat client
const chatClient = new ChatClient(API_KEY)
// Create a chat message in stream mode
const response = await chatClient.createChatMessage(inputs, query, user, true, null)
const response = await chatClient.createChatMessage({}, query, user, true, null)
const stream = response.data;
stream.on('data', data => {
console.log(data);
});
stream.on('end', () => {
console.log("stream done");
console.log('stream done');
});
// Create a chat message with vision model
chatClient.createChatMessage({}, 'Describe the picture.', user, false, null, remote_url_files)
// Fetch conversations
chatClient.getConversations(user)
// Fetch conversation messages
Expand Down
35 changes: 29 additions & 6 deletions sdks/nodejs-client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const routes = {
method: "DELETE",
url: (conversation_id) => `/conversations/${conversation_id}`,
},
fileUpload: {
method: "POST",
url: () => `/files/upload`,
}
};

export class DifyClient {
Expand All @@ -51,11 +55,15 @@ export class DifyClient {
endpoint,
data = null,
params = null,
stream = false
stream = false,
headerParams = {}
) {
const headers = {
Authorization: `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
...{
Authorization: `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
},
...headerParams
};

const url = `${this.baseUrl}${endpoint}`;
Expand Down Expand Up @@ -104,15 +112,28 @@ export class DifyClient {
params
);
}

fileUpload(data) {
return this.sendRequest(
routes.fileUpload.method,
routes.fileUpload.url(),
data,
null,
false,
{
"Content-Type": 'multipart/form-data'
}
);
}
}

export class CompletionClient extends DifyClient {
createCompletionMessage(inputs, query, user, stream = false) {
createCompletionMessage(inputs, user, stream = false, files = null) {
const data = {
inputs,
query,
user,
response_mode: stream ? "streaming" : "blocking",
files,
};
return this.sendRequest(
routes.createCompletionMessage.method,
Expand All @@ -130,13 +151,15 @@ export class ChatClient extends DifyClient {
query,
user,
stream = false,
conversation_id = null
conversation_id = null,
files = null
) {
const data = {
inputs,
query,
user,
response_mode: stream ? "streaming" : "blocking",
files,
};
if (conversation_id) data.conversation_id = conversation_id;

Expand Down
2 changes: 1 addition & 1 deletion sdks/nodejs-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dify-client",
"version": "2.0.0",
"version": "2.1.0",
"description": "This is the Node.js SDK for the Dify.AI API, which allows you to easily integrate Dify.AI into your Node.js applications.",
"main": "index.js",
"type": "module",
Expand Down
43 changes: 38 additions & 5 deletions sdks/php-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This is the PHP SDK for the Dify API, which allows you to easily integrate Dify

After installing the SDK, you can use it in your project like this:

```
```php
<?php

require 'vendor/autoload.php';
Expand All @@ -26,17 +26,50 @@ $difyClient = new DifyClient($apiKey);

// Create a completion client
$completionClient = new CompletionClient($apiKey);
$response = $completionClient->create_completion_message($inputs, $query, $response_mode, $user);
$response = $completionClient->create_completion_message(array("query" => "Who are you?"), "blocking", "user_id");

// Create a chat client
$chatClient = new ChatClient($apiKey);
$response = $chatClient->create_chat_message($inputs, $query, $user, $response_mode, $conversation_id);
$response = $chatClient->create_chat_message(array(), "Who are you?", "user_id", "blocking", $conversation_id);

$fileForVision = [
[
"type" => "image",
"transfer_method" => "remote_url",
"url" => "your_image_url"
]
];

// $fileForVision = [
// [
// "type" => "image",
// "transfer_method" => "local_file",
// "url" => "your_file_id"
// ]
// ];

// Create a completion client with vision model like gpt-4-vision
$response = $completionClient->create_completion_message(array("query" => "Describe this image."), "blocking", "user_id", $fileForVision);

// Create a chat client with vision model like gpt-4-vision
$response = $chatClient->create_chat_message(array(), "Describe this image.", "user_id", "blocking", $conversation_id, $fileForVision);

// File Upload
$fileForUpload = [
[
'tmp_name' => '/path/to/file/filename.jpg',
'name' => 'filename.jpg'
]
];
$response = $difyClient->file_upload("user_id", $fileForUpload);
$result = json_decode($response->getBody(), true);
echo 'upload_file_id: ' . $result['id'];

// Fetch application parameters
$response = $difyClient->get_application_parameters($user);
$response = $difyClient->get_application_parameters("user_id");

// Provide feedback for a message
$response = $difyClient->message_feedback($message_id, $rating, $user);
$response = $difyClient->message_feedback($message_id, $rating, "user_id");

// Other available methods:
// - get_conversation_messages()
Expand Down
43 changes: 40 additions & 3 deletions sdks/php-client/dify-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ public function __construct($api_key) {
'Content-Type' => 'application/json',
],
]);
$this->file_client = new Client([
'base_uri' => $this->base_url,
'headers' => [
'Authorization' => 'Bearer ' . $this->api_key,
'Content-Type' => 'multipart/form-data',
],
]);
}

protected function send_request($method, $endpoint, $data = null, $params = null, $stream = false) {
Expand All @@ -44,27 +51,57 @@ public function get_application_parameters($user) {
$params = ['user' => $user];
return $this->send_request('GET', 'parameters', null, $params);
}

public function file_upload($user, $files) {
$data = ['user' => $user];
$options = [
'multipart' => $this->prepareMultipart($data, $files)
];

return $this->file_client->request('POST', 'files/upload', $options);
}

protected function prepareMultipart($data, $files) {
$multipart = [];
foreach ($data as $key => $value) {
$multipart[] = [
'name' => $key,
'contents' => $value
];
}

foreach ($files as $file) {
$multipart[] = [
'name' => 'file',
'contents' => fopen($file['tmp_name'], 'r'),
'filename' => $file['name']
];
}

return $multipart;
}
}

class CompletionClient extends DifyClient {
public function create_completion_message($inputs, $query, $response_mode, $user) {
public function create_completion_message($inputs, $response_mode, $user, $files = null) {
$data = [
'inputs' => $inputs,
'query' => $query,
'response_mode' => $response_mode,
'user' => $user,
'files' => $files,
];
return $this->send_request('POST', 'completion-messages', $data, null, $response_mode === 'streaming');
}
}

class ChatClient extends DifyClient {
public function create_chat_message($inputs, $query, $user, $response_mode = 'blocking', $conversation_id = null) {
public function create_chat_message($inputs, $query, $user, $response_mode = 'blocking', $conversation_id = null, $files = null) {
$data = [
'inputs' => $inputs,
'query' => $query,
'user' => $user,
'response_mode' => $response_mode,
'files' => $files,
];
if ($conversation_id) {
$data['conversation_id'] = $conversation_id;
Expand Down
Loading
Loading