chore: import upstream snapshot with attribution
Publish `@librechat/data-schemas` to NPM / pack (push) Failing after 8s
Publish `@librechat/client` to NPM / pack (push) Failing after 0s
GitNexus Index / index (push) Failing after 1s
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been skipped
Sync Helm Chart Tags / Sync chart tags (push) Failing after 2s
Publish `librechat-data-provider` to NPM / pack (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Failing after 0s
Sync Helm Chart Tags / Ignore non-main push (push) Has been skipped
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Failing after 1s
Publish `@librechat/client` to NPM / publish-npm (push) Has been cancelled
Publish `librechat-data-provider` to NPM / publish-npm (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Publish `@librechat/data-schemas` to NPM / publish-npm (push) Has been cancelled
Publish `@librechat/data-schemas` to NPM / pack (push) Failing after 8s
Publish `@librechat/client` to NPM / pack (push) Failing after 0s
GitNexus Index / index (push) Failing after 1s
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Has been skipped
Sync Helm Chart Tags / Sync chart tags (push) Failing after 2s
Publish `librechat-data-provider` to NPM / pack (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile, librechat-dev, node) (push) Failing after 1s
Docker Dev Images Build / build (Dockerfile.multi, librechat-dev-api, api-build) (push) Failing after 0s
Sync Helm Chart Tags / Ignore non-main push (push) Has been skipped
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Failing after 1s
Publish `@librechat/client` to NPM / publish-npm (push) Has been cancelled
Publish `librechat-data-provider` to NPM / publish-npm (push) Has been cancelled
GitNexus Index / post-index (push) Has been cancelled
Publish `@librechat/data-schemas` to NPM / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const {
|
||||
MAX_SKILL_STATES,
|
||||
toSkillStatesRecord,
|
||||
validateSkillStatesPayload,
|
||||
pruneOrphanSkillStates,
|
||||
getDeploymentSkillIds,
|
||||
mergeDeploymentSkillIds,
|
||||
} = require('@librechat/api');
|
||||
const { ResourceType, PermissionBits } = require('librechat-data-provider');
|
||||
const { findAccessibleResources } = require('~/server/services/PermissionService');
|
||||
const { updateUser, getUserById } = require('~/models');
|
||||
|
||||
/** Builds the injected deps for `pruneOrphanSkillStates` from live models. */
|
||||
function buildPruneDeps(user) {
|
||||
return {
|
||||
findExistingSkillIds: async (validIds) => {
|
||||
const Skill = mongoose.models.Skill;
|
||||
if (!Skill) {
|
||||
return validIds;
|
||||
}
|
||||
const existing = await Skill.find({ _id: { $in: validIds } })
|
||||
.select('_id')
|
||||
.lean();
|
||||
const deploymentIds = getDeploymentSkillIds()
|
||||
.map((id) => id.toString())
|
||||
.filter((id) => validIds.includes(id));
|
||||
return [...existing.map((doc) => doc._id.toString()), ...deploymentIds];
|
||||
},
|
||||
findAccessibleSkillIds: async () =>
|
||||
mergeDeploymentSkillIds(
|
||||
await findAccessibleResources({
|
||||
userId: user.id,
|
||||
role: user.role,
|
||||
resourceType: ResourceType.SKILL,
|
||||
requiredPermissions: PermissionBits.VIEW,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const getSkillStatesController = async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const user = await getUserById(userId, 'skillStates');
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ message: 'User not found' });
|
||||
}
|
||||
|
||||
const states = toSkillStatesRecord(user.skillStates);
|
||||
const pruned = await pruneOrphanSkillStates(states, buildPruneDeps(req.user));
|
||||
return res.status(200).json(pruned);
|
||||
} catch (error) {
|
||||
logger.error('[SkillStatesController] Error fetching skill states:', error);
|
||||
return res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
const updateSkillStatesController = async (req, res) => {
|
||||
try {
|
||||
const { skillStates } = req.body;
|
||||
|
||||
const validationError = validateSkillStatesPayload(skillStates);
|
||||
if (validationError) {
|
||||
const { message, code, limit } = validationError;
|
||||
const payload = { message };
|
||||
if (code) payload.code = code;
|
||||
if (limit != null) payload.limit = limit;
|
||||
return res.status(400).json(payload);
|
||||
}
|
||||
|
||||
const pruned = await pruneOrphanSkillStates(skillStates, buildPruneDeps(req.user));
|
||||
|
||||
if (Object.keys(pruned).length > MAX_SKILL_STATES) {
|
||||
return res.status(400).json({
|
||||
code: 'MAX_SKILL_STATES_EXCEEDED',
|
||||
message: `Maximum ${MAX_SKILL_STATES} skill state overrides allowed`,
|
||||
limit: MAX_SKILL_STATES,
|
||||
});
|
||||
}
|
||||
|
||||
const user = await updateUser(req.user.id, { skillStates: pruned });
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ message: 'User not found' });
|
||||
}
|
||||
|
||||
return res.status(200).json(toSkillStatesRecord(user.skillStates));
|
||||
} catch (error) {
|
||||
logger.error('[SkillStatesController] Error updating skill states:', error);
|
||||
return res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getSkillStatesController,
|
||||
updateSkillStatesController,
|
||||
};
|
||||
Reference in New Issue
Block a user