dify-node-sdk
Version:
569 lines (558 loc) • 12.8 kB
JavaScript
"use strict";
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const axios = __toESM(require("axios"));
//#region src/utils/streamResponse/handler/base.ts
/**
* 基础流处理器 - 提供通用的流处理机制
*/
var BaseStreamHandler = class {
eventHandlers = new Map();
errorHandlers = [];
completionHandlers = [];
stream;
isStopped = false;
isStart = false;
/**
* 创建流处理器
* @param stream 响应流对象
*/
constructor(stream) {
this.stream = stream;
}
start() {
if (this.isStart) return;
this.isStart = true;
this.processStream();
}
/**
* 处理流内容
*/
processStream() {
let buffer = "";
this.stream.on("data", (chunk) => {
if (this.isStopped) return;
const str = chunk.toString();
buffer += str;
if (buffer.includes("\n\n")) {
const parts = buffer.split("\n\n");
buffer = parts.pop() || "";
for (const part of parts) if (part.startsWith("data: ")) {
const data = part.slice(6);
this.processData(data);
}
}
});
this.stream.on("error", (err) => {
this.emitError(err);
});
this.stream.on("end", () => {
if (buffer && buffer.startsWith("data: ")) {
const data = buffer.slice(6);
this.processData(data);
}
if (!this.isStopped) {
this.emitCompletion();
this.cleanUp();
}
});
}
/**
* 处理单条数据
* @param data 数据字符串
*/
/**
* 处理接收到的数据
*/
processData(data) {
if (data === "ping" || data === "data: ping") return;
try {
const parsed = JSON.parse(data);
this.dispatchEvent(parsed);
} catch (e) {
console.warn("解析数据失败:", e);
}
}
/**
* 分发事件
* @param event 事件对象
*/
dispatchEvent(event) {
const eventType = event.event;
if (eventType) {
const handlers = this.eventHandlers.get(eventType);
if (handlers && handlers.length > 0) handlers.forEach((handler) => handler(event));
}
}
/**
* 触发错误
* @param error 错误对象
*/
emitError(error) {
this.errorHandlers.forEach((handler) => handler(error));
}
/**
* 触发完成
*/
emitCompletion() {
this.completionHandlers.forEach((handler) => handler());
}
/**
* 清理资源
*/
cleanUp() {
this.isStopped = true;
}
/**
* 注册事件处理器
* @param eventType 事件类型
* @param handler 处理函数
*/
registerEventHandler(eventType, handler) {
if (!this.eventHandlers.has(eventType)) this.eventHandlers.set(eventType, []);
this.eventHandlers.get(eventType).push(handler);
}
/**
* 注册错误处理器
* @param handler 错误处理函数
*/
onError(handler) {
this.errorHandlers.push(handler);
return this;
}
/**
* 注册完成处理器
* @param handler 完成处理函数
*/
onFinished(handler) {
this.completionHandlers.push(handler);
return this;
}
/**
* 等待流完成
* @returns Promise 当流完成时解析
*/
async waitForCompletion() {
return new Promise((resolve, reject) => {
this.onFinished(() => resolve());
this.onError((error) => reject(error));
});
}
};
//#endregion
//#region src/utils/streamResponse/handler/chat.ts
/**
* 聊天流处理器
*/
var ChatStreamHandler = class extends BaseStreamHandler {
/**
* 注册消息事件处理器
*/
onMessage(handler) {
this.registerEventHandler("message", handler);
return this;
}
/**
* 注册消息文件事件处理器
*/
onMessageFile(handler) {
this.registerEventHandler("message_file", handler);
return this;
}
/**
* 注册消息结束事件处理器
*/
onMessageEnd(handler) {
this.registerEventHandler("message_end", handler);
return this;
}
/**
* 注册文本转语音消息事件处理器
*/
onTtsMessage(handler) {
this.registerEventHandler("tts_message", handler);
return this;
}
/**
* 注册文本转语音结束事件处理器
*/
onTtsMessageEnd(handler) {
this.registerEventHandler("tts_message_end", handler);
return this;
}
/**
* 注册消息替换事件处理器
*/
onMessageReplace(handler) {
this.registerEventHandler("message_replace", handler);
return this;
}
/**
* 注册错误事件处理器
*/
onErrorEvent(handler) {
this.registerEventHandler("error", handler);
return this;
}
};
//#endregion
//#region src/utils/streamResponse/handler/completion.ts
/**
* 完成流处理器
*/
var CompletionStreamHandler = class extends BaseStreamHandler {
/**
* 注册消息事件处理器
*/
onMessage(handler) {
this.registerEventHandler("message", handler);
return this;
}
/**
* 注册消息结束事件处理器
*/
onMessageEnd(handler) {
this.registerEventHandler("message_end", handler);
return this;
}
/**
* 注册文本转语音消息事件处理器
*/
onTtsMessage(handler) {
this.registerEventHandler("tts_message", handler);
return this;
}
/**
* 注册文本转语音结束事件处理器
*/
onTtsMessageEnd(handler) {
this.registerEventHandler("tts_message_end", handler);
return this;
}
/**
* 注册消息替换事件处理器
*/
onMessageReplace(handler) {
this.registerEventHandler("message_replace", handler);
return this;
}
/**
* 注册错误事件处理器
*/
onErrorEvent(handler) {
this.registerEventHandler("error", handler);
return this;
}
};
//#endregion
//#region src/utils/streamResponse/handler/workflow.ts
/**
* 工作流流处理器
*/
var WorkflowStreamHandler = class extends BaseStreamHandler {
/**
* 注册工作流开始事件处理器
*/
onWorkflowStarted(handler) {
this.registerEventHandler("workflow_started", handler);
return this;
}
/**
* 注册工作流完成事件处理器
*/
onWorkflowFinished(handler) {
this.registerEventHandler("workflow_finished", handler);
return this;
}
/**
* 注册节点开始事件处理器
*/
onNodeStarted(handler) {
this.registerEventHandler("node_started", handler);
return this;
}
/**
* 注册节点完成事件处理器
*/
onNodeFinished(handler) {
this.registerEventHandler("node_finished", handler);
return this;
}
/**
* 注册文本块事件处理器
*/
onTextChunk(handler) {
this.registerEventHandler("text_chunk", handler);
return this;
}
/**
* 注册文本转语音消息事件处理器
*/
onTtsMessage(handler) {
this.registerEventHandler("tts_message", handler);
return this;
}
/**
* 注册文本转语音结束事件处理器
*/
onTtsMessageEnd(handler) {
this.registerEventHandler("tts_message_end", handler);
return this;
}
};
//#endregion
//#region src/utils/request.ts
const createAxiosInstance = (apiKey, baseUrl) => {
const axiosInstance = axios.default.create({
baseURL: baseUrl,
headers: { "Content-Type": "application/json" },
timeout: 5e4
});
axiosInstance.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${apiKey}`;
return config;
});
return axiosInstance;
};
//#endregion
//#region src/client/dify.ts
/**
* Dify API Base Class
*/
var DifyClient = class {
apiKey;
baseUrl;
request;
/**
* Create Dify Client Instance
* @param apiKey API Key
* @param baseUrl API Base URL, default to official API address
*/
constructor(apiKey, baseUrl = "https://api.dify.ai/v1") {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.request = createAxiosInstance(apiKey, baseUrl);
}
messageFeedback(messageId, rating, user) {
return this.request({
method: "POST",
url: `/messages/${messageId}/feedbacks`,
data: {
rating,
user
}
});
}
getApplicationParameters() {
return this.request({
method: "GET",
url: "/parameters"
});
}
getMeta() {
return this.request({
method: "GET",
url: "/meta"
});
}
fileUpload(file, user) {
const formData = new FormData();
formData.append("file", file);
formData.append("user", user);
return this.request({
method: "POST",
url: "/files/upload",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
});
}
/**
* @deprecated dify 源码中还接受了voice参数,同时源码中貌似并未对streaming参数进行处理
*/
textToVideo(data) {
return this.request({
method: "POST",
url: "/text-to-audio",
data,
responseType: data.streaming ? "stream" : "json"
});
}
};
//#endregion
//#region src/client/chat.ts
var ChatClient = class extends DifyClient {
async createChatMessage(params) {
const defaultParams = {
response_mode: "blocking",
inputs: {}
};
const mergeParams = {
...defaultParams,
...params
};
const response = await this.request({
method: "POST",
url: "/chat-messages",
data: mergeParams,
responseType: mergeParams.response_mode === "streaming" ? "stream" : "json"
});
if (mergeParams.response_mode === "streaming") return new ChatStreamHandler(response.data);
return response.data;
}
getSuggested(messageId, user) {
return this.request({
method: "GET",
url: `/messages/${messageId}/suggested`,
params: { user }
});
}
/**
* @param taskId get it from chunk response
* @param user
*/
stopMessage(taskId, user) {
return this.request({
method: "POST",
url: `/chat-messages/${taskId}/stop`,
data: { user }
});
}
getConversations(params) {
return this.request({
method: "GET",
url: "/conversations",
params
});
}
getConversationMessages(params) {
return this.request({
method: "GET",
url: `/messages`,
params
});
}
renameConversation(data) {
const { conversation_id,...rest } = data;
return this.request({
method: "POST",
url: `/conversations/${conversation_id}/name`,
data: rest
});
}
deleteConversation(data) {
const { conversation_id,...rest } = data;
return this.request({
method: "DELETE",
url: `/conversations/${conversation_id}`,
data: rest
});
}
/**
* @param file file support ["mp3", "m4a", "wav", "webm", "amr"], limit 15MB
* @param user 用户
*/
audioToText(file, user) {
const formData = new FormData();
formData.append("file", file);
formData.append("user", user);
return this.request({
method: "POST",
url: "/audio-to-text",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
});
}
};
//#endregion
//#region src/client/workflow.ts
var WorkflowClient = class extends DifyClient {
async run(data) {
const defaultParams = {
response_mode: "blocking",
inputs: {}
};
const mergeParams = {
...defaultParams,
...data
};
const response = await this.request({
method: "POST",
url: "/workflows/run",
data: mergeParams,
responseType: mergeParams.response_mode === "streaming" ? "stream" : "json"
});
if (mergeParams.response_mode === "streaming") return new WorkflowStreamHandler(response.data);
return response.data;
}
getRunDetail(workflowRunId) {
return this.request({
method: "GET",
url: `/workflows/runs/${workflowRunId}`
});
}
stop(taskId, user) {
return this.request({
method: "POST",
url: `/workflows/tasks/${taskId}/stop`,
data: { user }
});
}
getLogs(params) {
return this.request({
method: "GET",
url: `/workflows/logs`,
params
});
}
};
//#endregion
//#region src/client/completion.ts
var CompletionClient = class extends DifyClient {
async createCompletionMessage(data) {
const defaultParams = { response_mode: "blocking" };
const mergeParams = {
...defaultParams,
...data
};
const response = await this.request({
method: "POST",
url: "/completion-messages",
data: mergeParams,
responseType: mergeParams.response_mode === "streaming" ? "stream" : "json"
});
if (mergeParams.response_mode === "streaming") return new CompletionStreamHandler(response.data);
return response.data;
}
stop(taskId, user) {
return this.request({
method: "POST",
url: `/completion-messages/${taskId}/stop`,
data: { user }
});
}
};
//#endregion
exports.ChatClient = ChatClient;
exports.CompletionClient = CompletionClient;
exports.DifyClient = DifyClient;
exports.WorkflowClient = WorkflowClient;