mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-04-07 00:15:23 +02:00
Merge e321792e8b into 8ed0bcf5ca
This commit is contained in:
commit
2f439cfbb0
2 changed files with 95 additions and 1 deletions
|
|
@ -29,6 +29,72 @@ describe('formatToolContent', () => {
|
|||
expect(content).toBe('(No response)');
|
||||
expect(artifacts).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return string for known non-OpenAI providers', () => {
|
||||
const result: t.MCPToolCallResponse = {
|
||||
content: [{ type: 'text', text: 'Test content' }],
|
||||
};
|
||||
const [content] = formatToolContent(result, 'google' as t.Provider);
|
||||
// Google is recognized but uses array format, so this should be an array
|
||||
expect(Array.isArray(content)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('automatic detection of OpenAI-compatible custom endpoints', () => {
|
||||
it('should automatically recognize new OpenAI-compatible custom endpoints', () => {
|
||||
const result: t.MCPToolCallResponse = {
|
||||
content: [
|
||||
{ type: 'text', text: 'First text' },
|
||||
{ type: 'text', text: 'Second text' },
|
||||
],
|
||||
};
|
||||
|
||||
// Test with a custom endpoint that's not explicitly listed
|
||||
const [content, artifacts] = formatToolContent(result, 'scaleway' as t.Provider);
|
||||
// Should be recognized and use array format (OpenAI-compatible)
|
||||
expect(Array.isArray(content)).toBe(true);
|
||||
expect(content).toEqual([{ type: 'text', text: 'First text\n\nSecond text' }]);
|
||||
expect(artifacts).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should use array format for unknown OpenAI-compatible endpoints', () => {
|
||||
const result: t.MCPToolCallResponse = {
|
||||
content: [
|
||||
{ type: 'text', text: 'Before image' },
|
||||
{ type: 'image', data: 'base64data', mimeType: 'image/png' },
|
||||
{ type: 'text', text: 'After image' },
|
||||
],
|
||||
};
|
||||
|
||||
// Test with another custom endpoint (e.g., together, perplexity, anyscale)
|
||||
const [content, artifacts] = formatToolContent(result, 'together' as t.Provider);
|
||||
// Should use array format like OpenAI
|
||||
expect(Array.isArray(content)).toBe(true);
|
||||
expect(content).toEqual([
|
||||
{ type: 'text', text: 'Before image' },
|
||||
{ type: 'text', text: 'After image' },
|
||||
]);
|
||||
expect(artifacts).toEqual({
|
||||
content: [
|
||||
{
|
||||
type: 'image_url',
|
||||
image_url: { url: 'data:image/png;base64,base64data' },
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT recognize known non-OpenAI providers', () => {
|
||||
const result: t.MCPToolCallResponse = {
|
||||
content: [{ type: 'text', text: 'Test content' }],
|
||||
};
|
||||
|
||||
// Non-OpenAI providers should return string format
|
||||
const [content, artifacts] = formatToolContent(result, 'bedrock' as t.Provider);
|
||||
expect(typeof content).toBe('string');
|
||||
expect(content).toBe('Test content');
|
||||
expect(artifacts).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('recognized providers', () => {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ function generateResourceId(text: string): string {
|
|||
return crypto.createHash('sha256').update(text).digest('hex').substring(0, 10);
|
||||
}
|
||||
|
||||
// Known providers that are NOT OpenAI-compatible
|
||||
// This is a small, stable list that rarely changes
|
||||
const NON_OPENAI_PROVIDERS = new Set(['google', 'anthropic', 'bedrock', 'ollama']);
|
||||
|
||||
const RECOGNIZED_PROVIDERS = new Set([
|
||||
'google',
|
||||
'anthropic',
|
||||
|
|
@ -17,8 +21,32 @@ const RECOGNIZED_PROVIDERS = new Set([
|
|||
'deepseek',
|
||||
'ollama',
|
||||
'bedrock',
|
||||
// Note: Custom OpenAI-compatible endpoints (like scaleway, together, perplexity, etc.)
|
||||
// are automatically recognized if they're not in NON_OPENAI_PROVIDERS
|
||||
]);
|
||||
|
||||
/**
|
||||
* Check if a provider should receive structured content formatting for MCP tool responses.
|
||||
*
|
||||
* Recognizes:
|
||||
* 1. Explicitly listed providers in RECOGNIZED_PROVIDERS
|
||||
* 2. Custom OpenAI-compatible endpoints (any provider not in NON_OPENAI_PROVIDERS)
|
||||
*
|
||||
* Custom endpoints are passed with their endpoint name (not "openai"), so we automatically
|
||||
* detect them rather than requiring explicit additions for each new provider.
|
||||
*/
|
||||
function isRecognizedProvider(provider: t.Provider): boolean {
|
||||
if (RECOGNIZED_PROVIDERS.has(provider)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!NON_OPENAI_PROVIDERS.has(provider)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const imageFormatters: Record<string, undefined | t.ImageFormatter> = {
|
||||
// google: (item) => ({
|
||||
// type: 'image',
|
||||
|
|
@ -92,7 +120,7 @@ export function formatToolContent(
|
|||
result: t.MCPToolCallResponse,
|
||||
provider: t.Provider,
|
||||
): t.FormattedContentResult {
|
||||
if (!RECOGNIZED_PROVIDERS.has(provider)) {
|
||||
if (!isRecognizedProvider(provider)) {
|
||||
return [parseAsString(result), undefined];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue