mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
Merge branch 'main' into feat/model-spec-group-icons
This commit is contained in:
commit
94819c7d0c
10 changed files with 12319 additions and 35 deletions
|
|
@ -317,14 +317,22 @@ const loadTools = async ({
|
|||
requestedTools[tool] = async () => {
|
||||
toolContextMap[tool] = `# \`${tool}\`:
|
||||
Current Date & Time: ${replaceSpecialVars({ text: '{{iso_datetime}}' })}
|
||||
1. **Execute immediately without preface** when using \`${tool}\`.
|
||||
2. **After the search, begin with a brief summary** that directly addresses the query without headers or explaining your process.
|
||||
3. **Structure your response clearly** using Markdown formatting (Level 2 headers for sections, lists for multiple points, tables for comparisons).
|
||||
4. **Cite sources properly** according to the citation anchor format, utilizing group anchors when appropriate.
|
||||
5. **Tailor your approach to the query type** (academic, news, coding, etc.) while maintaining an expert, journalistic, unbiased tone.
|
||||
6. **Provide comprehensive information** with specific details, examples, and as much relevant context as possible from search results.
|
||||
7. **Avoid moralizing language.**
|
||||
`.trim();
|
||||
|
||||
**Execute immediately without preface.** After search, provide a brief summary addressing the query directly, then structure your response with clear Markdown formatting (## headers, lists, tables). Cite sources properly, tailor tone to query type, and provide comprehensive details.
|
||||
|
||||
**CITATION FORMAT - INVISIBLE UNICODE ANCHORS ONLY:**
|
||||
Use these Unicode characters: \\ue202 (before each anchor), \\ue200 (group start), \\ue201 (group end), \\ue203 (highlight start), \\ue204 (highlight end)
|
||||
|
||||
Anchor pattern: turn{N}{type}{index} where N=turn number, type=search|news|image|ref, index=0,1,2...
|
||||
|
||||
**Examples:**
|
||||
- Single: "Statement.\\ue202turn0search0"
|
||||
- Multiple: "Statement.\\ue202turn0search0\\ue202turn0news1"
|
||||
- Group: "Statement. \\ue200\\ue202turn0search0\\ue202turn0news1\\ue201"
|
||||
- Highlight: "\\ue203Cited text.\\ue204\\ue202turn0search0"
|
||||
- Image: "See photo\\ue202turn0image0."
|
||||
|
||||
**CRITICAL:** Place anchors AFTER punctuation. Cite every non-obvious fact/quote. NEVER use markdown links, [1], footnotes, or HTML tags.`.trim();
|
||||
return createSearchTool({
|
||||
...result.authResult,
|
||||
onSearchResults,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
"@langchain/google-genai": "^0.2.13",
|
||||
"@langchain/google-vertexai": "^0.2.13",
|
||||
"@langchain/textsplitters": "^0.1.0",
|
||||
"@librechat/agents": "^3.0.36",
|
||||
"@librechat/agents": "^3.0.50",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ const fs = require('fs').promises;
|
|||
const FormData = require('form-data');
|
||||
const { Readable } = require('stream');
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const { genAzureEndpoint } = require('@librechat/api');
|
||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
const { genAzureEndpoint, logAxiosError } = require('@librechat/api');
|
||||
const { extractEnvVariable, STTProviders } = require('librechat-data-provider');
|
||||
const { getAppConfig } = require('~/server/services/Config');
|
||||
|
||||
|
|
@ -34,6 +35,34 @@ const MIME_TO_EXTENSION_MAP = {
|
|||
'audio/x-flac': 'flac',
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates and extracts ISO-639-1 language code from a locale string.
|
||||
* @param {string} language - The language/locale string (e.g., "en-US", "en", "zh-CN")
|
||||
* @returns {string|null} The ISO-639-1 language code (e.g., "en") or null if invalid
|
||||
*/
|
||||
function getValidatedLanguageCode(language) {
|
||||
try {
|
||||
if (!language) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const normalizedLanguage = language.toLowerCase();
|
||||
const isValidLocaleCode = /^[a-z]{2}(-[a-z]{2})?$/.test(normalizedLanguage);
|
||||
|
||||
if (isValidLocaleCode) {
|
||||
return normalizedLanguage.split('-')[0];
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
`[STT] Invalid language format "${language}". Expected ISO-639-1 locale code like "en-US" or "en". Skipping language parameter.`,
|
||||
);
|
||||
return null;
|
||||
} catch (error) {
|
||||
logger.error(`[STT] Error validating language code "${language}":`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file extension from the MIME type.
|
||||
* @param {string} mimeType - The MIME type.
|
||||
|
|
@ -172,10 +201,9 @@ class STTService {
|
|||
model: sttSchema.model,
|
||||
};
|
||||
|
||||
if (language) {
|
||||
/** Converted locale code (e.g., "en-US") to ISO-639-1 format (e.g., "en") */
|
||||
const isoLanguage = language.split('-')[0];
|
||||
data.language = isoLanguage;
|
||||
const validLanguage = getValidatedLanguageCode(language);
|
||||
if (validLanguage) {
|
||||
data.language = validLanguage;
|
||||
}
|
||||
|
||||
const headers = {
|
||||
|
|
@ -220,10 +248,9 @@ class STTService {
|
|||
contentType: audioFile.mimetype,
|
||||
});
|
||||
|
||||
if (language) {
|
||||
/** Converted locale code (e.g., "en-US") to ISO-639-1 format (e.g., "en") */
|
||||
const isoLanguage = language.split('-')[0];
|
||||
formData.append('language', isoLanguage);
|
||||
const validLanguage = getValidatedLanguageCode(language);
|
||||
if (validLanguage) {
|
||||
formData.append('language', validLanguage);
|
||||
}
|
||||
|
||||
const headers = {
|
||||
|
|
@ -266,8 +293,14 @@ class STTService {
|
|||
language,
|
||||
);
|
||||
|
||||
const options = { headers };
|
||||
|
||||
if (process.env.PROXY) {
|
||||
options.httpsAgent = new HttpsProxyAgent(process.env.PROXY);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(url, data, { headers });
|
||||
const response = await axios.post(url, data, options);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error('Invalid response from the STT API');
|
||||
|
|
@ -279,7 +312,7 @@ class STTService {
|
|||
|
||||
return response.data.text.trim();
|
||||
} catch (error) {
|
||||
logger.error(`STT request failed for provider ${provider}:`, error);
|
||||
logAxiosError({ message: `STT request failed for provider ${provider}:`, error });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
@ -309,7 +342,7 @@ class STTService {
|
|||
const text = await this.sttRequest(provider, sttSchema, { audioBuffer, audioFile, language });
|
||||
res.json({ text });
|
||||
} catch (error) {
|
||||
logger.error('An error occurred while processing the audio:', error);
|
||||
logAxiosError({ message: 'An error occurred while processing the audio:', error });
|
||||
res.sendStatus(500);
|
||||
} finally {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const axios = require('axios');
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const { genAzureEndpoint } = require('@librechat/api');
|
||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
const { genAzureEndpoint, logAxiosError } = require('@librechat/api');
|
||||
const { extractEnvVariable, TTSProviders } = require('librechat-data-provider');
|
||||
const { getRandomVoiceId, createChunkProcessor, splitTextIntoChunks } = require('./streamAudio');
|
||||
const { getAppConfig } = require('~/server/services/Config');
|
||||
|
|
@ -266,10 +267,14 @@ class TTSService {
|
|||
|
||||
const options = { headers, responseType: stream ? 'stream' : 'arraybuffer' };
|
||||
|
||||
if (process.env.PROXY) {
|
||||
options.httpsAgent = new HttpsProxyAgent(process.env.PROXY);
|
||||
}
|
||||
|
||||
try {
|
||||
return await axios.post(url, data, options);
|
||||
} catch (error) {
|
||||
logger.error(`TTS request failed for provider ${provider}:`, error);
|
||||
logAxiosError({ message: `TTS request failed for provider ${provider}:`, error });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
|
@ -325,7 +330,10 @@ class TTSService {
|
|||
break;
|
||||
}
|
||||
} catch (innerError) {
|
||||
logger.error('Error processing manual update:', chunk, innerError);
|
||||
logAxiosError({
|
||||
message: `[TTS] Error processing manual update for chunk: ${chunk?.text?.substring(0, 50)}...`,
|
||||
error: innerError,
|
||||
});
|
||||
if (!res.headersSent) {
|
||||
return res.status(500).end();
|
||||
}
|
||||
|
|
@ -337,7 +345,7 @@ class TTSService {
|
|||
res.end();
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Error creating the audio stream:', error);
|
||||
logAxiosError({ message: '[TTS] Error creating the audio stream:', error });
|
||||
if (!res.headersSent) {
|
||||
return res.status(500).send('An error occurred');
|
||||
}
|
||||
|
|
@ -407,7 +415,10 @@ class TTSService {
|
|||
break;
|
||||
}
|
||||
} catch (innerError) {
|
||||
logger.error('Error processing audio stream update:', update, innerError);
|
||||
logAxiosError({
|
||||
message: `[TTS] Error processing audio stream update: ${update?.text?.substring(0, 50)}...`,
|
||||
error: innerError,
|
||||
});
|
||||
if (!res.headersSent) {
|
||||
return res.status(500).end();
|
||||
}
|
||||
|
|
@ -424,7 +435,7 @@ class TTSService {
|
|||
res.end();
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch audio:', error);
|
||||
logAxiosError({ message: '[TTS] Failed to fetch audio:', error });
|
||||
if (!res.headersSent) {
|
||||
res.status(500).end();
|
||||
}
|
||||
|
|
|
|||
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
10
package-lock.json
generated
10
package-lock.json
generated
|
|
@ -61,7 +61,7 @@
|
|||
"@langchain/google-genai": "^0.2.13",
|
||||
"@langchain/google-vertexai": "^0.2.13",
|
||||
"@langchain/textsplitters": "^0.1.0",
|
||||
"@librechat/agents": "^3.0.36",
|
||||
"@librechat/agents": "^3.0.50",
|
||||
"@librechat/api": "*",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
|
|
@ -16281,9 +16281,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@librechat/agents": {
|
||||
"version": "3.0.36",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-3.0.36.tgz",
|
||||
"integrity": "sha512-52+uNiG0X2B4TZX03ldFRvqtJrExnntEFQV5UfA38+2sNbYgPm4lcdKyAHr9OTPdmmtbmDY/gKKguRiUzLVL2g==",
|
||||
"version": "3.0.50",
|
||||
"resolved": "https://registry.npmjs.org/@librechat/agents/-/agents-3.0.50.tgz",
|
||||
"integrity": "sha512-oovj3BsP/QoxPbWFAc71Ddplwd9BT8ucfYs+n+kiR37aCWtvxdvL9/XldRYfnaq9boNE324njQJyqc8v8AAPFQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@langchain/anthropic": "^0.3.26",
|
||||
|
|
@ -46276,7 +46276,7 @@
|
|||
"@azure/storage-blob": "^12.27.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@langchain/core": "^0.3.79",
|
||||
"@librechat/agents": "^3.0.36",
|
||||
"@librechat/agents": "^3.0.50",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.21.0",
|
||||
"axios": "^1.12.1",
|
||||
|
|
|
|||
|
|
@ -67,10 +67,11 @@
|
|||
"b:api-inspect": "NODE_ENV=production bun --inspect run api/server/index.js",
|
||||
"b:api:dev": "NODE_ENV=production bun run --watch api/server/index.js",
|
||||
"b:data": "cd packages/data-provider && bun run b:build",
|
||||
"b:mcp": "cd packages/api && bun run b:build",
|
||||
"b:build:client-package": "cd packages/client && bun run b:build",
|
||||
"b:data-schemas": "cd packages/data-schemas && bun run b:build",
|
||||
"b:build:api": "cd packages/api && bun run b:build",
|
||||
"b:client": "bun --bun run b:data && bun --bun run b:mcp && bun --bun run b:data-schemas && cd client && bun --bun run b:build",
|
||||
"b:build:client": "cd client && bun --bun run b:build",
|
||||
"b:client": "bun --bun run b:data && bun --bun run b:data-schemas && bun --bun run b:build:api && bun --bun run b:build:client-package && bun --bun run b:build:client",
|
||||
"b:client:dev": "cd client && bun run b:dev",
|
||||
"b:test:client": "cd client && bun run b:test",
|
||||
"b:test:api": "cd api && bun run b:test",
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@
|
|||
"@azure/storage-blob": "^12.27.0",
|
||||
"@keyv/redis": "^4.3.3",
|
||||
"@langchain/core": "^0.3.79",
|
||||
"@librechat/agents": "^3.0.36",
|
||||
"@librechat/agents": "^3.0.50",
|
||||
"@librechat/data-schemas": "*",
|
||||
"@modelcontextprotocol/sdk": "^1.21.0",
|
||||
"axios": "^1.12.1",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"b:clean": "bun run rimraf dist",
|
||||
"build": "npm run clean && rollup -c --bundleConfigAsCjs",
|
||||
"b:build": "bun run b:clean && bun run rollup -c --silent --bundleConfigAsCjs",
|
||||
"build:watch": "rollup -c -w --bundleConfigAsCjs",
|
||||
"dev": "rollup -c -w --bundleConfigAsCjs"
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue