diff --git a/docs/API/SEARCH.md b/docs/API/SEARCH.md index 3a28a78..b67b62b 100644 --- a/docs/API/SEARCH.md +++ b/docs/API/SEARCH.md @@ -33,6 +33,7 @@ The API accepts a JSON object in the request body, where you define the focus mo ["human", "Hi, how are you?"], ["assistant", "I am doing well, how can I help you today?"] ], + "systemInstructions": "Focus on providing technical details about Perplexica's architecture.", "stream": false } ``` @@ -63,6 +64,8 @@ The API accepts a JSON object in the request body, where you define the focus mo - **`query`** (string, required): The search query or question. +- **`systemInstructions`** (string, optional): Custom instructions provided by the user to guide the AI's response. These instructions are treated as user preferences and have lower priority than the system's core instructions. For example, you can specify a particular writing style, format, or focus area. + - **`history`** (array, optional): An array of message pairs representing the conversation history. Each pair consists of a role (either 'human' or 'assistant') and the message content. This allows the system to use the context of the conversation to refine results. Example: ```json diff --git a/sample.config.toml b/sample.config.toml index 691b964..980e99d 100644 --- a/sample.config.toml +++ b/sample.config.toml @@ -22,5 +22,8 @@ MODEL_NAME = "" [MODELS.OLLAMA] API_URL = "" # Ollama API URL - http://host.docker.internal:11434 +[MODELS.DEEPSEEK] +API_KEY = "" + [API_ENDPOINTS] SEARXNG = "" # SearxNG API URL - http://localhost:32768 \ No newline at end of file diff --git a/src/app/api/chat/route.ts b/src/app/api/chat/route.ts index d48fbb6..e566edb 100644 --- a/src/app/api/chat/route.ts +++ b/src/app/api/chat/route.ts @@ -49,6 +49,7 @@ type Body = { files: Array; chatModel: ChatModel; embeddingModel: EmbeddingModel; + systemInstructions: string; }; const handleEmitterEvents = async ( @@ -278,6 +279,7 @@ export const POST = async (req: Request) => { embedding, body.optimizationMode, body.files, + body.systemInstructions, ); const responseStream = new TransformStream(); diff --git a/src/app/api/config/route.ts b/src/app/api/config/route.ts index 871bb21..39c1f84 100644 --- a/src/app/api/config/route.ts +++ b/src/app/api/config/route.ts @@ -7,6 +7,7 @@ import { getGroqApiKey, getOllamaApiEndpoint, getOpenaiApiKey, + getDeepseekApiKey, updateConfig, } from '@/lib/config'; import { @@ -53,6 +54,7 @@ export const GET = async (req: Request) => { config['anthropicApiKey'] = getAnthropicApiKey(); config['groqApiKey'] = getGroqApiKey(); config['geminiApiKey'] = getGeminiApiKey(); + config['deepseekApiKey'] = getDeepseekApiKey(); config['customOpenaiApiUrl'] = getCustomOpenaiApiUrl(); config['customOpenaiApiKey'] = getCustomOpenaiApiKey(); config['customOpenaiModelName'] = getCustomOpenaiModelName(); @@ -88,6 +90,9 @@ export const POST = async (req: Request) => { OLLAMA: { API_URL: config.ollamaApiUrl, }, + DEEPSEEK: { + API_KEY: config.deepseekApiKey, + }, CUSTOM_OPENAI: { API_URL: config.customOpenaiApiUrl, API_KEY: config.customOpenaiApiKey, diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts index d3e98ca..970ec42 100644 --- a/src/app/api/search/route.ts +++ b/src/app/api/search/route.ts @@ -34,6 +34,7 @@ interface ChatRequestBody { query: string; history: Array<[string, string]>; stream?: boolean; + systemInstructions?: string; } export const POST = async (req: Request) => { @@ -125,6 +126,7 @@ export const POST = async (req: Request) => { embeddings, body.optimizationMode, [], + body.systemInstructions || '', ); if (!body.stream) { diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index efe54d5..8eee9a4 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -20,6 +20,7 @@ interface SettingsType { anthropicApiKey: string; geminiApiKey: string; ollamaApiUrl: string; + deepseekApiKey: string; customOpenaiApiKey: string; customOpenaiApiUrl: string; customOpenaiModelName: string; @@ -54,6 +55,38 @@ const Input = ({ className, isSaving, onSave, ...restProps }: InputProps) => { ); }; +interface TextareaProps extends React.InputHTMLAttributes { + isSaving?: boolean; + onSave?: (value: string) => void; +} + +const Textarea = ({ + className, + isSaving, + onSave, + ...restProps +}: TextareaProps) => { + return ( +
+