mirror of
https://github.com/langgenius/dify.git
synced 2026-07-25 21:48:30 +08:00
273 lines
7.2 KiB
TypeScript
273 lines
7.2 KiB
TypeScript
import type { HttpRequestBody } from '../http/client'
|
|
import type { SdkFormData } from '../http/form-data'
|
|
import type {
|
|
BinaryStream,
|
|
DifyClientConfig,
|
|
DifyResponse,
|
|
JsonObject,
|
|
MessageFeedbackRequest,
|
|
QueryParams,
|
|
RequestMethod,
|
|
SuccessResponse,
|
|
TextToAudioRequest,
|
|
} from '../types/common'
|
|
import { FileUploadError, ValidationError } from '../errors/dify-error'
|
|
import { HttpClient } from '../http/client'
|
|
import { isFormData } from '../http/form-data'
|
|
import { ensureNonEmptyString, ensureRating } from './validation'
|
|
|
|
const toConfig = (init: string | DifyClientConfig, baseUrl?: string): DifyClientConfig => {
|
|
if (typeof init === 'string') {
|
|
return {
|
|
apiKey: init,
|
|
baseUrl,
|
|
}
|
|
}
|
|
return init
|
|
}
|
|
|
|
const appendUserToFormData = (form: SdkFormData, user: string): void => {
|
|
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: HttpRequestBody = 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<JsonObject>> {
|
|
return this.http.request({
|
|
method: 'GET',
|
|
path: '/',
|
|
})
|
|
}
|
|
|
|
getApplicationParameters(user?: string): Promise<DifyResponse<JsonObject>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, 'user')
|
|
}
|
|
return this.http.request({
|
|
method: 'GET',
|
|
path: '/parameters',
|
|
query: user ? { user } : undefined,
|
|
})
|
|
}
|
|
|
|
async getParameters(user?: string): Promise<DifyResponse<JsonObject>> {
|
|
return this.getApplicationParameters(user)
|
|
}
|
|
|
|
getMeta(user?: string): Promise<DifyResponse<JsonObject>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, 'user')
|
|
}
|
|
return this.http.request({
|
|
method: 'GET',
|
|
path: '/meta',
|
|
query: user ? { user } : undefined,
|
|
})
|
|
}
|
|
|
|
messageFeedback(request: MessageFeedbackRequest): Promise<DifyResponse<SuccessResponse>>
|
|
messageFeedback(
|
|
messageId: string,
|
|
rating: 'like' | 'dislike' | null,
|
|
user: string,
|
|
content?: string,
|
|
): Promise<DifyResponse<SuccessResponse>>
|
|
messageFeedback(
|
|
messageIdOrRequest: string | MessageFeedbackRequest,
|
|
rating?: 'like' | 'dislike' | null,
|
|
user?: string,
|
|
content?: string,
|
|
): Promise<DifyResponse<SuccessResponse>> {
|
|
let messageId: string
|
|
const payload: JsonObject = {}
|
|
|
|
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<JsonObject>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, 'user')
|
|
}
|
|
return this.http.request({
|
|
method: 'GET',
|
|
path: '/info',
|
|
query: user ? { user } : undefined,
|
|
})
|
|
}
|
|
|
|
getSite(user?: string): Promise<DifyResponse<JsonObject>> {
|
|
if (user) {
|
|
ensureNonEmptyString(user, 'user')
|
|
}
|
|
return this.http.request({
|
|
method: 'GET',
|
|
path: '/site',
|
|
query: user ? { user } : undefined,
|
|
})
|
|
}
|
|
|
|
fileUpload(form: unknown, user: string): Promise<DifyResponse<JsonObject>> {
|
|
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, 'bytes'>({
|
|
method: 'GET',
|
|
path: `/files/${fileId}/preview`,
|
|
query: {
|
|
user,
|
|
as_attachment: asAttachment ? 'true' : undefined,
|
|
},
|
|
responseType: 'bytes',
|
|
})
|
|
}
|
|
|
|
audioToText(form: unknown, user: string): Promise<DifyResponse<JsonObject>> {
|
|
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, 'bytes'>({
|
|
method: 'POST',
|
|
path: '/text-to-audio',
|
|
data: payload,
|
|
responseType: 'bytes',
|
|
})
|
|
}
|
|
}
|