import { DifyClient } from "./base"; import type { ChatMessageRequest, ChatMessageResponse } from "../types/chat"; import type { AnnotationCreateRequest, AnnotationListOptions, AnnotationReplyActionRequest, AnnotationResponse, } from "../types/annotation"; import type { DifyResponse, DifyStream, QueryParams, } from "../types/common"; import { ensureNonEmptyString, ensureOptionalInt, ensureOptionalString, } from "./validation"; export class ChatClient extends DifyClient { createChatMessage( request: ChatMessageRequest ): Promise | DifyStream>; createChatMessage( inputs: Record, query: string, user: string, stream?: boolean, conversationId?: string | null, files?: Array> | null ): Promise | DifyStream>; createChatMessage( inputOrRequest: ChatMessageRequest | Record, query?: string, user?: string, stream = false, conversationId?: string | null, files?: Array> | null ): Promise | DifyStream> { let payload: ChatMessageRequest; let shouldStream = stream; if (query === undefined && "user" in (inputOrRequest as ChatMessageRequest)) { payload = inputOrRequest as ChatMessageRequest; shouldStream = payload.response_mode === "streaming"; } else { ensureNonEmptyString(query, "query"); ensureNonEmptyString(user, "user"); payload = { inputs: inputOrRequest as Record, query, user, response_mode: stream ? "streaming" : "blocking", files, }; if (conversationId) { payload.conversation_id = conversationId; } } ensureNonEmptyString(payload.user, "user"); ensureNonEmptyString(payload.query, "query"); if (shouldStream) { return this.http.requestStream({ method: "POST", path: "/chat-messages", data: payload, }); } return this.http.request({ method: "POST", path: "/chat-messages", data: payload, }); } stopChatMessage( taskId: string, user: string ): Promise> { ensureNonEmptyString(taskId, "taskId"); ensureNonEmptyString(user, "user"); return this.http.request({ method: "POST", path: `/chat-messages/${taskId}/stop`, data: { user }, }); } stopMessage( taskId: string, user: string ): Promise> { return this.stopChatMessage(taskId, user); } getSuggested( messageId: string, user: string ): Promise> { ensureNonEmptyString(messageId, "messageId"); ensureNonEmptyString(user, "user"); return this.http.request({ method: "GET", path: `/messages/${messageId}/suggested`, query: { user }, }); } // Note: messageFeedback is inherited from DifyClient getAppFeedbacks( page?: number, limit?: number ): Promise>> { ensureOptionalInt(page, "page"); ensureOptionalInt(limit, "limit"); return this.http.request({ method: "GET", path: "/app/feedbacks", query: { page, limit, }, }); } getConversations( user: string, lastId?: string | null, limit?: number | null, sortByOrPinned?: string | boolean | null ): Promise>> { ensureNonEmptyString(user, "user"); ensureOptionalString(lastId, "lastId"); ensureOptionalInt(limit, "limit"); const params: QueryParams = { user }; if (lastId) { params.last_id = lastId; } if (limit) { params.limit = limit; } if (typeof sortByOrPinned === "string") { params.sort_by = sortByOrPinned; } else if (typeof sortByOrPinned === "boolean") { params.pinned = sortByOrPinned; } return this.http.request({ method: "GET", path: "/conversations", query: params, }); } getConversationMessages( user: string, conversationId: string, firstId?: string | null, limit?: number | null ): Promise>> { ensureNonEmptyString(user, "user"); ensureNonEmptyString(conversationId, "conversationId"); ensureOptionalString(firstId, "firstId"); ensureOptionalInt(limit, "limit"); const params: QueryParams = { user }; params.conversation_id = conversationId; if (firstId) { params.first_id = firstId; } if (limit) { params.limit = limit; } return this.http.request({ method: "GET", path: "/messages", query: params, }); } renameConversation( conversationId: string, name: string, user: string, autoGenerate?: boolean ): Promise>>; renameConversation( conversationId: string, user: string, options?: { name?: string | null; autoGenerate?: boolean } ): Promise>>; renameConversation( conversationId: string, nameOrUser: string, userOrOptions?: string | { name?: string | null; autoGenerate?: boolean }, autoGenerate?: boolean ): Promise>> { ensureNonEmptyString(conversationId, "conversationId"); let name: string | null | undefined; let user: string; let resolvedAutoGenerate: boolean; if (typeof userOrOptions === "string" || userOrOptions === undefined) { name = nameOrUser; user = userOrOptions ?? ""; resolvedAutoGenerate = autoGenerate ?? false; } else { user = nameOrUser; name = userOrOptions.name; resolvedAutoGenerate = userOrOptions.autoGenerate ?? false; } ensureNonEmptyString(user, "user"); if (!resolvedAutoGenerate) { ensureNonEmptyString(name, "name"); } const payload: Record = { user, auto_generate: resolvedAutoGenerate, }; if (typeof name === "string" && name.trim().length > 0) { payload.name = name; } return this.http.request({ method: "POST", path: `/conversations/${conversationId}/name`, data: payload, }); } deleteConversation( conversationId: string, user: string ): Promise>> { ensureNonEmptyString(conversationId, "conversationId"); ensureNonEmptyString(user, "user"); return this.http.request({ method: "DELETE", path: `/conversations/${conversationId}`, data: { user }, }); } getConversationVariables( conversationId: string, user: string, lastId?: string | null, limit?: number | null, variableName?: string | null ): Promise>> { ensureNonEmptyString(conversationId, "conversationId"); ensureNonEmptyString(user, "user"); ensureOptionalString(lastId, "lastId"); ensureOptionalInt(limit, "limit"); ensureOptionalString(variableName, "variableName"); return this.http.request({ method: "GET", path: `/conversations/${conversationId}/variables`, query: { user, last_id: lastId ?? undefined, limit: limit ?? undefined, variable_name: variableName ?? undefined, }, }); } updateConversationVariable( conversationId: string, variableId: string, user: string, value: unknown ): Promise>> { ensureNonEmptyString(conversationId, "conversationId"); ensureNonEmptyString(variableId, "variableId"); ensureNonEmptyString(user, "user"); return this.http.request({ method: "PUT", path: `/conversations/${conversationId}/variables/${variableId}`, data: { user, value, }, }); } annotationReplyAction( action: "enable" | "disable", request: AnnotationReplyActionRequest ): Promise> { ensureNonEmptyString(action, "action"); ensureNonEmptyString(request.embedding_provider_name, "embedding_provider_name"); ensureNonEmptyString(request.embedding_model_name, "embedding_model_name"); return this.http.request({ method: "POST", path: `/apps/annotation-reply/${action}`, data: request, }); } getAnnotationReplyStatus( action: "enable" | "disable", jobId: string ): Promise> { ensureNonEmptyString(action, "action"); ensureNonEmptyString(jobId, "jobId"); return this.http.request({ method: "GET", path: `/apps/annotation-reply/${action}/status/${jobId}`, }); } listAnnotations( options?: AnnotationListOptions ): Promise> { ensureOptionalInt(options?.page, "page"); ensureOptionalInt(options?.limit, "limit"); ensureOptionalString(options?.keyword, "keyword"); return this.http.request({ method: "GET", path: "/apps/annotations", query: { page: options?.page, limit: options?.limit, keyword: options?.keyword ?? undefined, }, }); } createAnnotation( request: AnnotationCreateRequest ): Promise> { ensureNonEmptyString(request.question, "question"); ensureNonEmptyString(request.answer, "answer"); return this.http.request({ method: "POST", path: "/apps/annotations", data: request, }); } updateAnnotation( annotationId: string, request: AnnotationCreateRequest ): Promise> { ensureNonEmptyString(annotationId, "annotationId"); ensureNonEmptyString(request.question, "question"); ensureNonEmptyString(request.answer, "answer"); return this.http.request({ method: "PUT", path: `/apps/annotations/${annotationId}`, data: request, }); } deleteAnnotation( annotationId: string ): Promise> { ensureNonEmptyString(annotationId, "annotationId"); return this.http.request({ method: "DELETE", path: `/apps/annotations/${annotationId}`, }); } // Note: audioToText is inherited from DifyClient }