mirror of
https://github.com/langgenius/dify.git
synced 2026-01-29 07:02:11 +08:00
Some checks are pending
autofix.ci / autofix (push) Waiting to run
Build and Push API & Web / build (api, DIFY_API_IMAGE_NAME, linux/amd64, build-api-amd64) (push) Waiting to run
Build and Push API & Web / build (api, DIFY_API_IMAGE_NAME, linux/arm64, build-api-arm64) (push) Waiting to run
Build and Push API & Web / build (web, DIFY_WEB_IMAGE_NAME, linux/amd64, build-web-amd64) (push) Waiting to run
Build and Push API & Web / build (web, DIFY_WEB_IMAGE_NAME, linux/arm64, build-web-arm64) (push) Waiting to run
Build and Push API & Web / create-manifest (api, DIFY_API_IMAGE_NAME, merge-api-images) (push) Blocked by required conditions
Build and Push API & Web / create-manifest (web, DIFY_WEB_IMAGE_NAME, merge-web-images) (push) Blocked by required conditions
Main CI Pipeline / Check Changed Files (push) Waiting to run
Main CI Pipeline / API Tests (push) Blocked by required conditions
Main CI Pipeline / Web Tests (push) Blocked by required conditions
Main CI Pipeline / Style Check (push) Waiting to run
Main CI Pipeline / VDB Tests (push) Blocked by required conditions
Main CI Pipeline / DB Migration Test (push) Blocked by required conditions
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
285 lines
7.3 KiB
TypeScript
285 lines
7.3 KiB
TypeScript
import type {
|
|
BinaryStream,
|
|
DifyClientConfig,
|
|
DifyResponse,
|
|
MessageFeedbackRequest,
|
|
QueryParams,
|
|
RequestMethod,
|
|
TextToAudioRequest,
|
|
} from "../types/common";
|
|
import { HttpClient } from "../http/client";
|
|
import { ensureNonEmptyString, ensureRating } from "./validation";
|
|
import { FileUploadError, ValidationError } from "../errors/dify-error";
|
|
import { isFormData } from "../http/form-data";
|
|
|
|
const toConfig = (
|
|
init: string | DifyClientConfig,
|
|
baseUrl?: string
|
|
): DifyClientConfig => {
|
|
if (typeof init === "string") {
|
|
return {
|
|
apiKey: init,
|
|
baseUrl,
|
|
};
|
|
}
|
|
return init;
|
|
};
|
|
|
|
const appendUserToFormData = (form: unknown, user: string): void => {
|
|
if (!isFormData(form)) {
|
|
throw new FileUploadError("FormData is required for file uploads");
|
|
}
|
|
if (typeof form.append === "function") {
|
|
form.append("user", user);
|
|
}
|
|
};
|
|
|
|
export class DifyClient {
|
|
protected http: HttpClient;
|
|
|
|
constructor(config: string | DifyClientConfig | HttpClient, baseUrl?: string) {
|
|
if (config instanceof HttpClient) {
|
|
this.http = config;
|
|
} else {
|
|
this.http = new HttpClient(toConfig(config, baseUrl));
|
|
}
|
|
}
|
|
|
|
updateApiKey(apiKey: string): void {
|
|
ensureNonEmptyString(apiKey, "apiKey");
|
|
this.http.updateApiKey(apiKey);
|
|
}
|
|
|
|
getHttpClient(): HttpClient {
|
|
return this.http;
|
|
}
|
|
|
|
sendRequest(
|
|
method: RequestMethod,
|
|
endpoint: string,
|
|
data: unknown = null,
|
|
params: QueryParams | null = null,
|
|
stream = false,
|
|
headerParams: Record<string, string> = {}
|
|
): ReturnType<HttpClient["requestRaw"]> {
|
|
return this.http.requestRaw({
|
|
method,
|
|
path: endpoint,
|
|
data,
|
|
query: params ?? undefined,
|
|
headers: headerParams,
|
|
responseType: stream ? "stream" : "json",
|
|
});
|
|
}
|
|
|
|
getRoot(): Promise<DifyResponse<unknown>> {
|
|
return this.http.request({
|
|
method: "GET",
|
|
path: "/",
|
|
});
|
|
}
|
|
|
|
getApplicationParameters(user?: string): Promise<DifyResponse<unknown>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, "user");
|
|
}
|
|
return this.http.request({
|
|
method: "GET",
|
|
path: "/parameters",
|
|
query: user ? { user } : undefined,
|
|
});
|
|
}
|
|
|
|
async getParameters(user?: string): Promise<DifyResponse<unknown>> {
|
|
return this.getApplicationParameters(user);
|
|
}
|
|
|
|
getMeta(user?: string): Promise<DifyResponse<unknown>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, "user");
|
|
}
|
|
return this.http.request({
|
|
method: "GET",
|
|
path: "/meta",
|
|
query: user ? { user } : undefined,
|
|
});
|
|
}
|
|
|
|
messageFeedback(
|
|
request: MessageFeedbackRequest
|
|
): Promise<DifyResponse<Record<string, unknown>>>;
|
|
messageFeedback(
|
|
messageId: string,
|
|
rating: "like" | "dislike" | null,
|
|
user: string,
|
|
content?: string
|
|
): Promise<DifyResponse<Record<string, unknown>>>;
|
|
messageFeedback(
|
|
messageIdOrRequest: string | MessageFeedbackRequest,
|
|
rating?: "like" | "dislike" | null,
|
|
user?: string,
|
|
content?: string
|
|
): Promise<DifyResponse<Record<string, unknown>>> {
|
|
let messageId: string;
|
|
const payload: Record<string, unknown> = {};
|
|
|
|
if (typeof messageIdOrRequest === "string") {
|
|
messageId = messageIdOrRequest;
|
|
ensureNonEmptyString(messageId, "messageId");
|
|
ensureNonEmptyString(user, "user");
|
|
payload.user = user;
|
|
if (rating !== undefined && rating !== null) {
|
|
ensureRating(rating);
|
|
payload.rating = rating;
|
|
}
|
|
if (content !== undefined) {
|
|
payload.content = content;
|
|
}
|
|
} else {
|
|
const request = messageIdOrRequest;
|
|
messageId = request.messageId;
|
|
ensureNonEmptyString(messageId, "messageId");
|
|
ensureNonEmptyString(request.user, "user");
|
|
payload.user = request.user;
|
|
if (request.rating !== undefined && request.rating !== null) {
|
|
ensureRating(request.rating);
|
|
payload.rating = request.rating;
|
|
}
|
|
if (request.content !== undefined) {
|
|
payload.content = request.content;
|
|
}
|
|
}
|
|
|
|
return this.http.request({
|
|
method: "POST",
|
|
path: `/messages/${messageId}/feedbacks`,
|
|
data: payload,
|
|
});
|
|
}
|
|
|
|
getInfo(user?: string): Promise<DifyResponse<unknown>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, "user");
|
|
}
|
|
return this.http.request({
|
|
method: "GET",
|
|
path: "/info",
|
|
query: user ? { user } : undefined,
|
|
});
|
|
}
|
|
|
|
getSite(user?: string): Promise<DifyResponse<unknown>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, "user");
|
|
}
|
|
return this.http.request({
|
|
method: "GET",
|
|
path: "/site",
|
|
query: user ? { user } : undefined,
|
|
});
|
|
}
|
|
|
|
fileUpload(form: unknown, user: string): Promise<DifyResponse<unknown>> {
|
|
if (!isFormData(form)) {
|
|
throw new FileUploadError("FormData is required for file uploads");
|
|
}
|
|
ensureNonEmptyString(user, "user");
|
|
appendUserToFormData(form, user);
|
|
return this.http.request({
|
|
method: "POST",
|
|
path: "/files/upload",
|
|
data: form,
|
|
});
|
|
}
|
|
|
|
filePreview(
|
|
fileId: string,
|
|
user: string,
|
|
asAttachment?: boolean
|
|
): Promise<DifyResponse<Buffer>> {
|
|
ensureNonEmptyString(fileId, "fileId");
|
|
ensureNonEmptyString(user, "user");
|
|
return this.http.request<Buffer>({
|
|
method: "GET",
|
|
path: `/files/${fileId}/preview`,
|
|
query: {
|
|
user,
|
|
as_attachment: asAttachment ? "true" : undefined,
|
|
},
|
|
responseType: "arraybuffer",
|
|
});
|
|
}
|
|
|
|
audioToText(form: unknown, user: string): Promise<DifyResponse<unknown>> {
|
|
if (!isFormData(form)) {
|
|
throw new FileUploadError("FormData is required for audio uploads");
|
|
}
|
|
ensureNonEmptyString(user, "user");
|
|
appendUserToFormData(form, user);
|
|
return this.http.request({
|
|
method: "POST",
|
|
path: "/audio-to-text",
|
|
data: form,
|
|
});
|
|
}
|
|
|
|
textToAudio(
|
|
request: TextToAudioRequest
|
|
): Promise<DifyResponse<Buffer> | BinaryStream>;
|
|
textToAudio(
|
|
text: string,
|
|
user: string,
|
|
streaming?: boolean,
|
|
voice?: string
|
|
): Promise<DifyResponse<Buffer> | BinaryStream>;
|
|
textToAudio(
|
|
textOrRequest: string | TextToAudioRequest,
|
|
user?: string,
|
|
streaming = false,
|
|
voice?: string
|
|
): Promise<DifyResponse<Buffer> | BinaryStream> {
|
|
let payload: TextToAudioRequest;
|
|
|
|
if (typeof textOrRequest === "string") {
|
|
ensureNonEmptyString(textOrRequest, "text");
|
|
ensureNonEmptyString(user, "user");
|
|
payload = {
|
|
text: textOrRequest,
|
|
user,
|
|
streaming,
|
|
};
|
|
if (voice) {
|
|
payload.voice = voice;
|
|
}
|
|
} else {
|
|
payload = { ...textOrRequest };
|
|
ensureNonEmptyString(payload.user, "user");
|
|
if (payload.text !== undefined && payload.text !== null) {
|
|
ensureNonEmptyString(payload.text, "text");
|
|
}
|
|
if (payload.message_id !== undefined && payload.message_id !== null) {
|
|
ensureNonEmptyString(payload.message_id, "messageId");
|
|
}
|
|
if (!payload.text && !payload.message_id) {
|
|
throw new ValidationError("text or message_id is required");
|
|
}
|
|
payload.streaming = payload.streaming ?? false;
|
|
}
|
|
|
|
if (payload.streaming) {
|
|
return this.http.requestBinaryStream({
|
|
method: "POST",
|
|
path: "/text-to-audio",
|
|
data: payload,
|
|
});
|
|
}
|
|
|
|
return this.http.request<Buffer>({
|
|
method: "POST",
|
|
path: "/text-to-audio",
|
|
data: payload,
|
|
responseType: "arraybuffer",
|
|
});
|
|
}
|
|
}
|