mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🔧 refactor: Centralize Default Agent Capabilities and Better Logging (#7598)
* refactor: Simplify grid column calculation in SourcesGroup component * refactor: Centralize default agent capabilities and simplify capability assignment * Edge case: use defined/fallback capabilities for ephemeral agents when the "agents" endpoint is not enabled * refactor: consolidate gemini 2 vision check * feat: enhance capability check logging for agents * chore: update librechat-data-provider version to 0.7.86 * refactor: import default agent capabilities for enhanced capability management * chore: standardize quotes in error message check for consistency * fix: improve error logging both client and api-side for mistral ocr upload errors * ci: update error handling in MistralOCR tests to use specific error message
This commit is contained in:
parent
077b7e7e79
commit
2f462c9b3c
11 changed files with 57 additions and 44 deletions
|
|
@ -283,6 +283,10 @@ router.post('/', async (req, res) => {
|
|||
message += ': ' + error.message;
|
||||
}
|
||||
|
||||
if (error.message?.includes('Invalid file format')) {
|
||||
message = error.message;
|
||||
}
|
||||
|
||||
// TODO: delete remote file if it exists
|
||||
try {
|
||||
await fs.unlink(req.file.path);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ async function uploadDocumentToMistral({
|
|||
})
|
||||
.then((res) => res.data)
|
||||
.catch((error) => {
|
||||
logger.error('Error uploading document to Mistral:', error.message);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
|
@ -217,8 +216,16 @@ const uploadMistralOCR = async ({ req, file, file_id, entity_id }) => {
|
|||
images,
|
||||
};
|
||||
} catch (error) {
|
||||
const message = 'Error uploading document to Mistral OCR API';
|
||||
throw new Error(logAxiosError({ error, message }));
|
||||
let message = 'Error uploading document to Mistral OCR API';
|
||||
const detail = error?.response?.data?.detail;
|
||||
if (detail && detail !== '') {
|
||||
message = detail;
|
||||
}
|
||||
|
||||
const responseMessage = error?.response?.data?.message;
|
||||
throw new Error(
|
||||
`${logAxiosError({ error, message })}${responseMessage && responseMessage !== '' ? ` - ${responseMessage}` : ''}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -124,13 +124,7 @@ describe('MistralOCR Service', () => {
|
|||
fileName: 'test.pdf',
|
||||
apiKey: 'test-api-key',
|
||||
}),
|
||||
).rejects.toThrow();
|
||||
|
||||
const { logger } = require('~/config');
|
||||
expect(logger.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Error uploading document to Mistral:'),
|
||||
expect.any(String),
|
||||
);
|
||||
).rejects.toThrow(errorMessage);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const { Calculator } = require('@langchain/community/tools/calculator');
|
|||
const { tool: toolFn, Tool, DynamicStructuredTool } = require('@langchain/core/tools');
|
||||
const {
|
||||
Tools,
|
||||
Constants,
|
||||
ErrorTypes,
|
||||
ContentTypes,
|
||||
imageGenTools,
|
||||
|
|
@ -14,6 +15,7 @@ const {
|
|||
ImageVisionTool,
|
||||
openapiToFunction,
|
||||
AgentCapabilities,
|
||||
defaultAgentCapabilities,
|
||||
validateAndParseOpenAPISpec,
|
||||
} = require('librechat-data-provider');
|
||||
const {
|
||||
|
|
@ -501,8 +503,22 @@ async function loadAgentTools({ req, res, agent, tool_resources, openAIApiKey })
|
|||
}
|
||||
|
||||
const endpointsConfig = await getEndpointsConfig(req);
|
||||
const enabledCapabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
|
||||
const checkCapability = (capability) => enabledCapabilities.has(capability);
|
||||
let enabledCapabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
|
||||
/** Edge case: use defined/fallback capabilities when the "agents" endpoint is not enabled */
|
||||
if (enabledCapabilities.size === 0 && agent.id === Constants.EPHEMERAL_AGENT_ID) {
|
||||
enabledCapabilities = new Set(
|
||||
req.app?.locals?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
|
||||
);
|
||||
}
|
||||
const checkCapability = (capability) => {
|
||||
const enabled = enabledCapabilities.has(capability);
|
||||
if (!enabled) {
|
||||
logger.warn(
|
||||
`Capability "${capability}" disabled${capability === AgentCapabilities.tools ? '.' : ' despite configured tool.'} User: ${req.user.id} | Agent: ${agent.id}`,
|
||||
);
|
||||
}
|
||||
return enabled;
|
||||
};
|
||||
const areToolsEnabled = checkCapability(AgentCapabilities.tools);
|
||||
|
||||
let includesWebSearch = false;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ const {
|
|||
Capabilities,
|
||||
EModelEndpoint,
|
||||
isAgentsEndpoint,
|
||||
AgentCapabilities,
|
||||
isAssistantsEndpoint,
|
||||
defaultRetrievalModels,
|
||||
defaultAssistantsVersion,
|
||||
defaultAgentCapabilities,
|
||||
} = require('librechat-data-provider');
|
||||
const { Providers } = require('@librechat/agents');
|
||||
const partialRight = require('lodash/partialRight');
|
||||
|
|
@ -197,16 +197,7 @@ function generateConfig(key, baseURL, endpoint) {
|
|||
}
|
||||
|
||||
if (agents) {
|
||||
config.capabilities = [
|
||||
AgentCapabilities.execute_code,
|
||||
AgentCapabilities.file_search,
|
||||
AgentCapabilities.web_search,
|
||||
AgentCapabilities.artifacts,
|
||||
AgentCapabilities.actions,
|
||||
AgentCapabilities.tools,
|
||||
AgentCapabilities.chain,
|
||||
AgentCapabilities.ocr,
|
||||
];
|
||||
config.capabilities = defaultAgentCapabilities;
|
||||
}
|
||||
|
||||
if (assistants && endpoint === EModelEndpoint.azureAssistants) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const logAxiosError = ({ message, error }) => {
|
|||
requestInfo: { method, url },
|
||||
stack,
|
||||
});
|
||||
} else if (error?.message?.includes('Cannot read properties of undefined (reading \'status\')')) {
|
||||
} else if (error?.message?.includes("Cannot read properties of undefined (reading 'status')")) {
|
||||
logMessage = `${message} It appears the request timed out or was unsuccessful: ${error.message}`;
|
||||
logger.error(logMessage, { stack });
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import * as Ariakit from '@ariakit/react';
|
||||
import React, { useRef, useState, useMemo } from 'react';
|
||||
import { EToolResources, EModelEndpoint } from 'librechat-data-provider';
|
||||
import { FileSearch, ImageUpIcon, TerminalSquareIcon, FileType2Icon } from 'lucide-react';
|
||||
import { EToolResources, EModelEndpoint, defaultAgentCapabilities } from 'librechat-data-provider';
|
||||
import { FileUpload, TooltipAnchor, DropdownPopup, AttachmentIcon } from '~/components';
|
||||
import { useGetEndpointsQuery } from '~/data-provider';
|
||||
import { useLocalize, useFileHandling } from '~/hooks';
|
||||
|
|
@ -22,6 +22,10 @@ const AttachFile = ({ disabled }: AttachFileProps) => {
|
|||
overrideEndpoint: EModelEndpoint.agents,
|
||||
});
|
||||
|
||||
/** TODO: Ephemeral Agent Capabilities
|
||||
* Allow defining agent capabilities on a per-endpoint basis
|
||||
* Use definition for agents endpoint for ephemeral agents
|
||||
* */
|
||||
const capabilities = useMemo(
|
||||
() => endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? [],
|
||||
[endpointsConfig],
|
||||
|
|
|
|||
|
|
@ -190,12 +190,8 @@ function SourcesGroup({ sources, limit = 3 }: { sources: ValidSource[]; limit?:
|
|||
const remainingSources = sources.slice(limit);
|
||||
const hasMoreSources = remainingSources.length > 0;
|
||||
|
||||
/** Calculate grid columns based on number of items (including the +X sources button if present) */
|
||||
const totalItems = hasMoreSources ? visibleSources.length + 1 : visibleSources.length;
|
||||
const gridCols = `grid-cols-${Math.min(totalItems, 4)}`;
|
||||
|
||||
return (
|
||||
<div className={`grid ${gridCols} scrollbar-none w-full gap-2 overflow-x-auto`}>
|
||||
<div className="scrollbar-none grid w-full grid-cols-4 gap-2 overflow-x-auto">
|
||||
<OGDialog>
|
||||
{visibleSources.map((source, i) => (
|
||||
<div key={`source-${i}`} className="w-full min-w-[120px]">
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -45274,7 +45274,7 @@
|
|||
},
|
||||
"packages/data-provider": {
|
||||
"name": "librechat-data-provider",
|
||||
"version": "0.7.85",
|
||||
"version": "0.7.86",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"axios": "^1.8.2",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "librechat-data-provider",
|
||||
"version": "0.7.85",
|
||||
"version": "0.7.86",
|
||||
"description": "data services for librechat apps",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.es.js",
|
||||
|
|
|
|||
|
|
@ -233,6 +233,17 @@ export const assistantEndpointSchema = baseEndpointSchema.merge(
|
|||
|
||||
export type TAssistantEndpoint = z.infer<typeof assistantEndpointSchema>;
|
||||
|
||||
export const defaultAgentCapabilities = [
|
||||
AgentCapabilities.execute_code,
|
||||
AgentCapabilities.file_search,
|
||||
AgentCapabilities.web_search,
|
||||
AgentCapabilities.artifacts,
|
||||
AgentCapabilities.actions,
|
||||
AgentCapabilities.tools,
|
||||
AgentCapabilities.chain,
|
||||
AgentCapabilities.ocr,
|
||||
];
|
||||
|
||||
export const agentsEndpointSChema = baseEndpointSchema.merge(
|
||||
z.object({
|
||||
/* agents specific */
|
||||
|
|
@ -243,16 +254,7 @@ export const agentsEndpointSChema = baseEndpointSchema.merge(
|
|||
capabilities: z
|
||||
.array(z.nativeEnum(AgentCapabilities))
|
||||
.optional()
|
||||
.default([
|
||||
AgentCapabilities.execute_code,
|
||||
AgentCapabilities.file_search,
|
||||
AgentCapabilities.web_search,
|
||||
AgentCapabilities.artifacts,
|
||||
AgentCapabilities.actions,
|
||||
AgentCapabilities.tools,
|
||||
AgentCapabilities.chain,
|
||||
AgentCapabilities.ocr,
|
||||
]),
|
||||
.default(defaultAgentCapabilities),
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
@ -950,8 +952,7 @@ export const visionModels = [
|
|||
'gemma',
|
||||
'gemini-exp',
|
||||
'gemini-1.5',
|
||||
'gemini-2.0',
|
||||
'gemini-2.5',
|
||||
'gemini-2',
|
||||
'gemini-3',
|
||||
'moondream',
|
||||
'llama3.2-vision',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue