mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
🧩 fix: Preserve Deployment Skill IDs on Agents (#14368)
* fix: preserve deployment skills on agents * fix: expose deployment skills to agent viewers * refactor: centralize deployment skill ID merging --------- Co-authored-by: Dennis Schenk <dennis@gridonic.ch>
This commit is contained in:
parent
ade02054c8
commit
3e9f07976a
7 changed files with 133 additions and 8 deletions
|
|
@ -8,6 +8,7 @@ const {
|
|||
agentUpdateSchema,
|
||||
refreshListAvatars,
|
||||
collectEdgeAgentIds,
|
||||
mergeDeploymentSkillIds,
|
||||
mergeAgentOcrConversion,
|
||||
sanitizeModelParameters,
|
||||
MAX_AVATAR_REFRESH_AGENTS,
|
||||
|
|
@ -1098,7 +1099,9 @@ const getListAgentsHandler = async (req, res) => {
|
|||
resourceType: ResourceType.SKILL,
|
||||
requiredPermissions: PermissionBits.VIEW,
|
||||
});
|
||||
accessibleSkillSet = new Set(accessibleSkillIds.map((oid) => oid.toString()));
|
||||
accessibleSkillSet = new Set(
|
||||
mergeDeploymentSkillIds(accessibleSkillIds).map((oid) => oid.toString()),
|
||||
);
|
||||
}
|
||||
|
||||
const publicSet = new Set(publiclyAccessibleIds.map((oid) => oid.toString()));
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ jest.mock('sharp', () =>
|
|||
|
||||
jest.mock('@librechat/api', () => ({
|
||||
...jest.requireActual('@librechat/api'),
|
||||
mergeDeploymentSkillIds: jest.fn((ids) => ids),
|
||||
refreshS3Url: jest.fn(),
|
||||
}));
|
||||
|
||||
|
|
@ -92,7 +93,7 @@ const {
|
|||
getResourcePermissionsMap,
|
||||
} = require('~/server/services/PermissionService');
|
||||
|
||||
const { refreshS3Url } = require('@librechat/api');
|
||||
const { mergeDeploymentSkillIds, refreshS3Url } = require('@librechat/api');
|
||||
|
||||
/**
|
||||
* @type {import('mongoose').Model<import('@librechat/data-schemas').IAgent>}
|
||||
|
|
@ -155,6 +156,7 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
|
|||
|
||||
// Reset all mocks
|
||||
jest.clearAllMocks();
|
||||
mergeDeploymentSkillIds.mockImplementation((ids) => ids);
|
||||
|
||||
// Setup mock request and response objects
|
||||
mockReq = {
|
||||
|
|
@ -1850,6 +1852,32 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
|
|||
expect(response.data[0].skills_enabled).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should preserve deployment skill scope for VIEW list callers', async () => {
|
||||
const deploymentSkillId = new mongoose.Types.ObjectId();
|
||||
await Agent.findByIdAndUpdate(agentA1._id, {
|
||||
skills_enabled: true,
|
||||
skills: [deploymentSkillId.toString()],
|
||||
});
|
||||
|
||||
mockReq.user.id = userB.toString();
|
||||
mockReq.query.requiredPermission = String(PermissionBits.VIEW);
|
||||
findAccessibleResources.mockImplementation(({ resourceType }) => {
|
||||
if (resourceType === ResourceType.AGENT) {
|
||||
return Promise.resolve([agentA1._id]);
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
});
|
||||
findPubliclyAccessibleResources.mockResolvedValue([]);
|
||||
mergeDeploymentSkillIds.mockImplementation((ids) => [...ids, deploymentSkillId]);
|
||||
|
||||
await getListAgentsHandler(mockReq, mockRes);
|
||||
|
||||
const response = mockRes.json.mock.calls[0][0];
|
||||
expect(response.data).toHaveLength(1);
|
||||
expect(response.data[0].skills_enabled).toBe(true);
|
||||
expect(response.data[0].skills).toEqual([deploymentSkillId.toString()]);
|
||||
});
|
||||
|
||||
test('should preserve enabled skill scope for VIEW list callers with an empty allowlist', async () => {
|
||||
await Agent.findByIdAndUpdate(agentA1._id, {
|
||||
skills_enabled: true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue