From cca4af2ee0996ab7181b712c1c62855d9c8898ac Mon Sep 17 00:00:00 2001 From: braginini Date: Mon, 16 Mar 2026 17:41:21 +0100 Subject: [PATCH] Add dify as a provider --- src/server/handler.ts | 6 +++- src/server/index.ts | 1 + src/server/providers/dify.ts | 66 +++++++++++++++++++++++++++++++++++ src/server/providers/types.ts | 1 + 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/server/providers/dify.ts diff --git a/src/server/handler.ts b/src/server/handler.ts index 3e76b85..a72469f 100644 --- a/src/server/handler.ts +++ b/src/server/handler.ts @@ -1,12 +1,14 @@ import type { Message } from "../types"; import { AnthropicProvider } from "./providers/anthropic"; +import { DifyProvider } from "./providers/dify"; import { OpenAIProvider } from "./providers/openai"; import type { LLMProvider, Middleware } from "./providers/types"; export type AssistantConfig = { - provider: "anthropic" | "openai" | LLMProvider; + provider: "anthropic" | "openai" | "dify" | LLMProvider; apiKey?: string; model?: string; + baseUrl?: string; systemPrompt?: string; middleware?: Middleware[]; }; @@ -105,6 +107,8 @@ function createProvider(config: AssistantConfig): LLMProvider { return new AnthropicProvider({ apiKey: config.apiKey, model: config.model }); case "openai": return new OpenAIProvider({ apiKey: config.apiKey, model: config.model }); + case "dify": + return new DifyProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl }); default: throw new Error(`Unknown provider: ${config.provider}`); } diff --git a/src/server/index.ts b/src/server/index.ts index d7fe065..934e1cb 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,5 +1,6 @@ export { createAssistant } from "./handler"; export type { AssistantConfig } from "./handler"; export { AnthropicProvider } from "./providers/anthropic"; +export { DifyProvider } from "./providers/dify"; export { OpenAIProvider } from "./providers/openai"; export type { LLMProvider, ProviderConfig, Middleware } from "./providers/types"; \ No newline at end of file diff --git a/src/server/providers/dify.ts b/src/server/providers/dify.ts new file mode 100644 index 0000000..ae03066 --- /dev/null +++ b/src/server/providers/dify.ts @@ -0,0 +1,66 @@ +import type { Message } from "../../types"; +import type { LLMProvider, ProviderConfig } from "./types"; + +export class DifyProvider implements LLMProvider { + private apiKey: string; + private baseUrl: string; + + constructor(config: ProviderConfig) { + this.apiKey = config.apiKey; + if (!config.baseUrl) { + throw new Error("baseUrl is required for the Dify provider"); + } + this.baseUrl = config.baseUrl.replace(/\/+$/, ""); + } + + async chat(messages: Message[], systemPrompt?: string): Promise { + const query = this.buildQuery(messages, systemPrompt); + + const response = await fetch(`${this.baseUrl}/v1/chat-messages`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + inputs: {}, + query, + response_mode: "blocking", + user: "explain-user", + }), + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`Dify API error ${response.status}: ${text}`); + } + + const data = await response.json(); + if (!data.answer) { + throw new Error("No answer in Dify response"); + } + return data.answer; + } + + private buildQuery(messages: Message[], systemPrompt?: string): string { + const parts: string[] = []; + + if (systemPrompt) { + parts.push(`[System]: ${systemPrompt}`); + } + + for (const m of messages) { + if (m.role === "context") { + parts.push(`[Context]: ${m.content}`); + } else if (m.role === "system") { + parts.push(`[System]: ${m.content}`); + } else if (m.role === "assistant") { + parts.push(`[Assistant]: ${m.content}`); + } else { + parts.push(m.content); + } + } + + return parts.join("\n\n"); + } +} \ No newline at end of file diff --git a/src/server/providers/types.ts b/src/server/providers/types.ts index 58f55a3..bc6cd7b 100644 --- a/src/server/providers/types.ts +++ b/src/server/providers/types.ts @@ -7,6 +7,7 @@ export interface LLMProvider { export type ProviderConfig = { apiKey: string; model?: string; + baseUrl?: string; }; /**