mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 10:20:15 +01:00
refactor: consolidate agent marketplace endpoints into main agents API and improve data management consistency
- Remove dedicated marketplace controller and routes, merging functionality into main agents v1 API - Add countPromotedAgents function to Agent model for promoted agents count - Enhance getListAgents handler with marketplace filtering (category, search, promoted status) - Move getAgentCategories from marketplace to v1 controller with same functionality - Update agent mutations to invalidate marketplace queries and handle multiple permission levels - Improve cache management by updating all agent query variants (VIEW/EDIT permissions) - Consolidate agent data access patterns for better maintainability and consistency - Remove duplicate marketplace route definitions and middleware
This commit is contained in:
parent
d549a64317
commit
722e40f276
14 changed files with 291 additions and 412 deletions
|
|
@ -751,6 +751,14 @@ const generateActionMetadataHash = async (actionIds, actions) => {
|
||||||
|
|
||||||
return hashHex;
|
return hashHex;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Counts the number of promoted agents.
|
||||||
|
* @returns {Promise<number>} - The count of promoted agents
|
||||||
|
*/
|
||||||
|
const countPromotedAgents = async () => {
|
||||||
|
const count = await Agent.countDocuments({ is_promoted: true });
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a default agent based on the endpoint
|
* Load a default agent based on the endpoint
|
||||||
|
|
@ -771,4 +779,5 @@ module.exports = {
|
||||||
getListAgentsByAccess,
|
getListAgentsByAccess,
|
||||||
removeAgentResourceFiles,
|
removeAgentResourceFiles,
|
||||||
generateActionMetadataHash,
|
generateActionMetadataHash,
|
||||||
|
countPromotedAgents,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,195 +0,0 @@
|
||||||
const mongoose = require('mongoose');
|
|
||||||
const { logger } = require('~/config');
|
|
||||||
const { findCategoryByValue, getCategoriesWithCounts } = require('~/models');
|
|
||||||
const { getListAgentsByAccess } = require('~/models/Agent');
|
|
||||||
const {
|
|
||||||
findAccessibleResources,
|
|
||||||
findPubliclyAccessibleResources,
|
|
||||||
} = require('~/server/services/PermissionService');
|
|
||||||
// Get the Agent model
|
|
||||||
const Agent = mongoose.model('Agent');
|
|
||||||
|
|
||||||
// Default page size for agent browsing
|
|
||||||
const DEFAULT_PAGE_SIZE = 6;
|
|
||||||
|
|
||||||
const getAgentsPagedByAccess = async (
|
|
||||||
userId,
|
|
||||||
requiredPermission,
|
|
||||||
filter,
|
|
||||||
limit = DEFAULT_PAGE_SIZE,
|
|
||||||
cursor,
|
|
||||||
) => {
|
|
||||||
const accessibleIds = await findAccessibleResources({
|
|
||||||
userId,
|
|
||||||
resourceType: 'agent',
|
|
||||||
requiredPermissions: requiredPermission,
|
|
||||||
});
|
|
||||||
const publiclyAccessibleIds = await findPubliclyAccessibleResources({
|
|
||||||
resourceType: 'agent',
|
|
||||||
requiredPermissions: requiredPermission,
|
|
||||||
});
|
|
||||||
// Use the new ACL-aware function
|
|
||||||
const data = await getListAgentsByAccess({
|
|
||||||
accessibleIds,
|
|
||||||
otherParams: filter,
|
|
||||||
limit,
|
|
||||||
after: cursor,
|
|
||||||
});
|
|
||||||
if (data?.data?.length) {
|
|
||||||
data.data = data.data.map((agent) => {
|
|
||||||
if (publiclyAccessibleIds.some((id) => id.equals(agent._id))) {
|
|
||||||
agent.isPublic = true;
|
|
||||||
}
|
|
||||||
return agent;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unified marketplace agents endpoint with query string controls
|
|
||||||
* Query parameters:
|
|
||||||
* - category: string (filter by specific category - if undefined, no category filter applied)
|
|
||||||
* - search: string (search term for name/description)
|
|
||||||
* - limit: number (page size, default 6)
|
|
||||||
* - cursor: base64 string (for cursor-based pagination)
|
|
||||||
* - promoted: 0|1 (filter promoted agents, 1=promoted only, 0=exclude promoted)
|
|
||||||
* - requiredPermission: number (permission level required to access agents, default 1)
|
|
||||||
*
|
|
||||||
* @param {Object} req - Express request object
|
|
||||||
* @param {Object} res - Express response object
|
|
||||||
*/
|
|
||||||
const getMarketplaceAgents = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const {
|
|
||||||
category,
|
|
||||||
search,
|
|
||||||
limit = DEFAULT_PAGE_SIZE,
|
|
||||||
cursor,
|
|
||||||
promoted,
|
|
||||||
requiredPermission = 1,
|
|
||||||
} = req.query;
|
|
||||||
|
|
||||||
const parsedLimit = parseInt(limit) || DEFAULT_PAGE_SIZE;
|
|
||||||
const parsedRequiredPermission = parseInt(requiredPermission) || 1;
|
|
||||||
|
|
||||||
// Base filter
|
|
||||||
const filter = {};
|
|
||||||
|
|
||||||
// Handle category filter - only apply if category is defined
|
|
||||||
if (category !== undefined && category.trim() !== '') {
|
|
||||||
filter.category = category;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle promoted filter - only from query param
|
|
||||||
if (promoted === '1') {
|
|
||||||
filter.is_promoted = true;
|
|
||||||
} else if (promoted === '0') {
|
|
||||||
filter.is_promoted = { $ne: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle search filter
|
|
||||||
if (search && search.trim() !== '') {
|
|
||||||
filter.$or = [
|
|
||||||
{ name: { $regex: search.trim(), $options: 'i' } },
|
|
||||||
{ description: { $regex: search.trim(), $options: 'i' } },
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use ACL-aware function for proper permission handling
|
|
||||||
const result = await getAgentsPagedByAccess(
|
|
||||||
req.user.id,
|
|
||||||
parsedRequiredPermission, // Required permission as number
|
|
||||||
filter,
|
|
||||||
parsedLimit,
|
|
||||||
cursor,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add category info if category was specified
|
|
||||||
if (category !== undefined && category.trim() !== '') {
|
|
||||||
const categoryDoc = await findCategoryByValue(category);
|
|
||||||
result.category = {
|
|
||||||
name: category,
|
|
||||||
description: categoryDoc?.description || '',
|
|
||||||
total: result.pagination?.total || result.data?.length || 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add search info if search was performed
|
|
||||||
if (search && search.trim() !== '') {
|
|
||||||
result.query = search.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).json(result);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('[/Agents/Marketplace] Error fetching marketplace agents:', error);
|
|
||||||
res.status(500).json({
|
|
||||||
error: 'Failed to fetch marketplace agents',
|
|
||||||
userMessage: 'Unable to load agents. Please try refreshing the page.',
|
|
||||||
suggestion: 'Try refreshing the page or check your network connection',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all agent categories with counts
|
|
||||||
*
|
|
||||||
* @param {Object} _req - Express request object (unused)
|
|
||||||
* @param {Object} res - Express response object
|
|
||||||
*/
|
|
||||||
const getAgentCategories = async (_req, res) => {
|
|
||||||
try {
|
|
||||||
// Get categories with agent counts from database
|
|
||||||
const categories = await getCategoriesWithCounts();
|
|
||||||
|
|
||||||
// Get count of promoted agents for Top Picks
|
|
||||||
const promotedCount = await Agent.countDocuments({
|
|
||||||
is_promoted: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Convert to marketplace format (TCategory structure)
|
|
||||||
const formattedCategories = categories.map((category) => ({
|
|
||||||
value: category.value,
|
|
||||||
label: category.label,
|
|
||||||
count: category.agentCount,
|
|
||||||
description: category.description,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Add promoted category if agents exist
|
|
||||||
if (promotedCount > 0) {
|
|
||||||
formattedCategories.unshift({
|
|
||||||
value: 'promoted',
|
|
||||||
label: 'Promoted',
|
|
||||||
count: promotedCount,
|
|
||||||
description: 'Our recommended agents',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total count of all shared agents for "All" category
|
|
||||||
const totalAgents = await Agent.countDocuments({
|
|
||||||
projectIds: { $exists: true, $ne: [] },
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add "All" category at the end
|
|
||||||
formattedCategories.push({
|
|
||||||
value: 'all',
|
|
||||||
label: 'All',
|
|
||||||
count: totalAgents,
|
|
||||||
description: 'All available agents',
|
|
||||||
});
|
|
||||||
|
|
||||||
res.status(200).json(formattedCategories);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('[/Agents/Marketplace] Error fetching agent categories:', error);
|
|
||||||
res.status(500).json({
|
|
||||||
error: 'Failed to fetch agent categories',
|
|
||||||
userMessage: 'Unable to load categories. Please refresh the page.',
|
|
||||||
suggestion: 'Try refreshing the page or check your network connection',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getMarketplaceAgents,
|
|
||||||
getAgentCategories,
|
|
||||||
};
|
|
||||||
|
|
@ -14,6 +14,9 @@ const {
|
||||||
updateAgent,
|
updateAgent,
|
||||||
deleteAgent,
|
deleteAgent,
|
||||||
getListAgentsByAccess,
|
getListAgentsByAccess,
|
||||||
|
countPromotedAgents,
|
||||||
|
updateAgentProjects,
|
||||||
|
revertAgentVersion,
|
||||||
} = require('~/models/Agent');
|
} = require('~/models/Agent');
|
||||||
const {
|
const {
|
||||||
grantPermission,
|
grantPermission,
|
||||||
|
|
@ -29,6 +32,7 @@ const { updateAction, getActions } = require('~/models/Action');
|
||||||
const { getCachedTools } = require('~/server/services/Config');
|
const { getCachedTools } = require('~/server/services/Config');
|
||||||
const { revertAgentVersion } = require('~/models/Agent');
|
const { revertAgentVersion } = require('~/models/Agent');
|
||||||
const { deleteFileByFilter } = require('~/models/File');
|
const { deleteFileByFilter } = require('~/models/File');
|
||||||
|
const { getCategoriesWithCounts } = require('~/models');
|
||||||
|
|
||||||
const systemTools = {
|
const systemTools = {
|
||||||
[Tools.execute_code]: true,
|
[Tools.execute_code]: true,
|
||||||
|
|
@ -389,17 +393,38 @@ const deleteAgentHandler = async (req, res) => {
|
||||||
const getListAgentsHandler = async (req, res) => {
|
const getListAgentsHandler = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
if (!req.query.requiredPermission) {
|
const { category, search, limit, cursor, promoted } = req.query;
|
||||||
req.query.requiredPermission = PermissionBits.VIEW;
|
let requiredPermission = req.query.requiredPermission;
|
||||||
} else if (typeof req.query.requiredPermission === 'string') {
|
if (typeof requiredPermission === 'string') {
|
||||||
req.query.requiredPermission = parseInt(req.query.requiredPermission, 10);
|
requiredPermission = parseInt(requiredPermission, 10);
|
||||||
if (isNaN(req.query.requiredPermission)) {
|
if (isNaN(requiredPermission)) {
|
||||||
req.query.requiredPermission = PermissionBits.VIEW;
|
requiredPermission = PermissionBits.VIEW;
|
||||||
}
|
}
|
||||||
} else if (typeof req.query.requiredPermission !== 'number') {
|
} else if (typeof requiredPermission !== 'number') {
|
||||||
req.query.requiredPermission = PermissionBits.VIEW;
|
requiredPermission = PermissionBits.VIEW;
|
||||||
|
}
|
||||||
|
// Base filter
|
||||||
|
const filter = {};
|
||||||
|
|
||||||
|
// Handle category filter - only apply if category is defined
|
||||||
|
if (category !== undefined && category.trim() !== '') {
|
||||||
|
filter.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle promoted filter - only from query param
|
||||||
|
if (promoted === '1') {
|
||||||
|
filter.is_promoted = true;
|
||||||
|
} else if (promoted === '0') {
|
||||||
|
filter.is_promoted = { $ne: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle search filter
|
||||||
|
if (search && search.trim() !== '') {
|
||||||
|
filter.$or = [
|
||||||
|
{ name: { $regex: search.trim(), $options: 'i' } },
|
||||||
|
{ description: { $regex: search.trim(), $options: 'i' } },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
const requiredPermission = req.query.requiredPermission || PermissionBits.VIEW;
|
|
||||||
// Get agent IDs the user has VIEW access to via ACL
|
// Get agent IDs the user has VIEW access to via ACL
|
||||||
const accessibleIds = await findAccessibleResources({
|
const accessibleIds = await findAccessibleResources({
|
||||||
userId,
|
userId,
|
||||||
|
|
@ -413,7 +438,9 @@ const getListAgentsHandler = async (req, res) => {
|
||||||
// Use the new ACL-aware function
|
// Use the new ACL-aware function
|
||||||
const data = await getListAgentsByAccess({
|
const data = await getListAgentsByAccess({
|
||||||
accessibleIds,
|
accessibleIds,
|
||||||
otherParams: {}, // Can add query params here if needed
|
otherParams: filter,
|
||||||
|
limit,
|
||||||
|
after: cursor,
|
||||||
});
|
});
|
||||||
if (data?.data?.length) {
|
if (data?.data?.length) {
|
||||||
data.data = data.data.map((agent) => {
|
data.data = data.data.map((agent) => {
|
||||||
|
|
@ -580,7 +607,48 @@ const revertAgentVersionHandler = async (req, res) => {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Get all agent categories with counts
|
||||||
|
*
|
||||||
|
* @param {Object} _req - Express request object (unused)
|
||||||
|
* @param {Object} res - Express response object
|
||||||
|
*/
|
||||||
|
const getAgentCategories = async (_req, res) => {
|
||||||
|
try {
|
||||||
|
const categories = await getCategoriesWithCounts();
|
||||||
|
const promotedCount = await countPromotedAgents();
|
||||||
|
const formattedCategories = categories.map((category) => ({
|
||||||
|
value: category.value,
|
||||||
|
label: category.label,
|
||||||
|
count: category.agentCount,
|
||||||
|
description: category.description,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (promotedCount > 0) {
|
||||||
|
formattedCategories.unshift({
|
||||||
|
value: 'promoted',
|
||||||
|
label: 'Promoted',
|
||||||
|
count: promotedCount,
|
||||||
|
description: 'Our recommended agents',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedCategories.push({
|
||||||
|
value: 'all',
|
||||||
|
label: 'All',
|
||||||
|
description: 'All available agents',
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json(formattedCategories);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('[/Agents/Marketplace] Error fetching agent categories:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
error: 'Failed to fetch agent categories',
|
||||||
|
userMessage: 'Unable to load categories. Please refresh the page.',
|
||||||
|
suggestion: 'Try refreshing the page or check your network connection',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createAgent: createAgentHandler,
|
createAgent: createAgentHandler,
|
||||||
getAgent: getAgentHandler,
|
getAgent: getAgentHandler,
|
||||||
|
|
@ -590,4 +658,5 @@ module.exports = {
|
||||||
getListAgents: getListAgentsHandler,
|
getListAgents: getListAgentsHandler,
|
||||||
uploadAgentAvatar: uploadAgentAvatarHandler,
|
uploadAgentAvatar: uploadAgentAvatarHandler,
|
||||||
revertAgentVersion: revertAgentVersionHandler,
|
revertAgentVersion: revertAgentVersionHandler,
|
||||||
|
getAgentCategories,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ const {
|
||||||
const { isEnabled } = require('~/server/utils');
|
const { isEnabled } = require('~/server/utils');
|
||||||
const { v1 } = require('./v1');
|
const { v1 } = require('./v1');
|
||||||
const chat = require('./chat');
|
const chat = require('./chat');
|
||||||
const marketplace = require('./marketplace');
|
|
||||||
|
|
||||||
const { LIMIT_CONCURRENT_MESSAGES, LIMIT_MESSAGE_IP, LIMIT_MESSAGE_USER } = process.env ?? {};
|
const { LIMIT_CONCURRENT_MESSAGES, LIMIT_MESSAGE_IP, LIMIT_MESSAGE_USER } = process.env ?? {};
|
||||||
|
|
||||||
|
|
@ -20,8 +19,6 @@ router.use(requireJwtAuth);
|
||||||
router.use(checkBan);
|
router.use(checkBan);
|
||||||
router.use(uaParser);
|
router.use(uaParser);
|
||||||
|
|
||||||
router.use('/marketplace', marketplace);
|
|
||||||
|
|
||||||
router.use('/', v1);
|
router.use('/', v1);
|
||||||
|
|
||||||
const chatRouter = express.Router();
|
const chatRouter = express.Router();
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
const express = require('express');
|
|
||||||
const { requireJwtAuth, checkBan, generateCheckAccess } = require('~/server/middleware');
|
|
||||||
const { PermissionTypes, Permissions } = require('librechat-data-provider');
|
|
||||||
const marketplace = require('~/server/controllers/agents/marketplace');
|
|
||||||
|
|
||||||
const router = express.Router();
|
|
||||||
|
|
||||||
// Apply middleware for authentication and authorization
|
|
||||||
router.use(requireJwtAuth);
|
|
||||||
router.use(checkBan);
|
|
||||||
|
|
||||||
// Check if user has permission to use agents
|
|
||||||
const checkAgentAccess = generateCheckAccess(PermissionTypes.AGENTS, [Permissions.USE]);
|
|
||||||
router.use(checkAgentAccess);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unified marketplace agents endpoint with query string controls
|
|
||||||
* Query parameters:
|
|
||||||
* - category: string (filter by category, or 'all' for all agents, 'promoted' for promoted)
|
|
||||||
* - search: string (search term for name/description)
|
|
||||||
* - limit: number (page size, default 6)
|
|
||||||
* - cursor: base64 string (for cursor-based pagination)
|
|
||||||
* - promoted: 0|1 (filter promoted agents, 1=promoted only, 0=exclude promoted)
|
|
||||||
* - requiredPermission: number (permission level required to access agents, default 1)
|
|
||||||
* @route GET /agents/marketplace
|
|
||||||
*/
|
|
||||||
router.get('/', marketplace.getMarketplaceAgents);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all agent categories with counts
|
|
||||||
* @route GET /agents/marketplace/categories
|
|
||||||
*/
|
|
||||||
router.get('/categories', marketplace.getAgentCategories);
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
|
|
@ -42,6 +42,11 @@ router.use('/actions', actions);
|
||||||
*/
|
*/
|
||||||
router.use('/tools', tools);
|
router.use('/tools', tools);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all agent categories with counts
|
||||||
|
* @route GET /agents/marketplace/categories
|
||||||
|
*/
|
||||||
|
router.get('/categories', v1.getAgentCategories);
|
||||||
/**
|
/**
|
||||||
* Creates an agent.
|
* Creates an agent.
|
||||||
* @route POST /agents
|
* @route POST /agents
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,12 @@ import type {
|
||||||
AgentCreateParams,
|
AgentCreateParams,
|
||||||
AgentListResponse,
|
AgentListResponse,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import { useUploadAgentAvatarMutation, useGetFileConfig } from '~/data-provider';
|
import {
|
||||||
|
useUploadAgentAvatarMutation,
|
||||||
|
useGetFileConfig,
|
||||||
|
allAgentViewAndEditQueryKeys,
|
||||||
|
invalidateAgentMarketplaceQueries,
|
||||||
|
} from '~/data-provider';
|
||||||
import { AgentAvatarRender, NoImage, AvatarMenu } from './Images';
|
import { AgentAvatarRender, NoImage, AvatarMenu } from './Images';
|
||||||
import { useToastContext } from '~/Providers';
|
import { useToastContext } from '~/Providers';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
@ -57,30 +62,31 @@ function Avatar({
|
||||||
const newUrl = data.avatar?.filepath ?? '';
|
const newUrl = data.avatar?.filepath ?? '';
|
||||||
setPreviewUrl(newUrl);
|
setPreviewUrl(newUrl);
|
||||||
|
|
||||||
const res = queryClient.getQueryData<AgentListResponse>([
|
((keys) => {
|
||||||
QueryKeys.agents,
|
keys.forEach((key) => {
|
||||||
defaultOrderQuery,
|
const res = queryClient.getQueryData<AgentListResponse>([QueryKeys.agents, key]);
|
||||||
]);
|
|
||||||
|
|
||||||
if (!res?.data) {
|
if (!res?.data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const agents = res.data.map((agent) => {
|
const agents = res.data.map((agent) => {
|
||||||
if (agent.id === agent_id) {
|
if (agent.id === agent_id) {
|
||||||
return {
|
return {
|
||||||
...agent,
|
...agent,
|
||||||
...data,
|
...data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return agent;
|
return agent;
|
||||||
});
|
});
|
||||||
|
|
||||||
queryClient.setQueryData<AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
|
||||||
...res,
|
|
||||||
data: agents,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
queryClient.setQueryData<AgentListResponse>([QueryKeys.agents, key], {
|
||||||
|
...res,
|
||||||
|
data: agents,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
invalidateAgentMarketplaceQueries(queryClient);
|
||||||
setProgress(1);
|
setProgress(1);
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { dataService, MutationKeys, QueryKeys, defaultOrderQuery } from 'librechat-data-provider';
|
import { dataService, MutationKeys, PERMISSION_BITS, QueryKeys } from 'librechat-data-provider';
|
||||||
import type * as t from 'librechat-data-provider';
|
import type * as t from 'librechat-data-provider';
|
||||||
import type { UseMutationResult } from '@tanstack/react-query';
|
import type { QueryClient, UseMutationResult } from '@tanstack/react-query';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AGENTS
|
* AGENTS
|
||||||
*/
|
*/
|
||||||
|
export const allAgentViewAndEditQueryKeys: t.AgentListParams[] = [
|
||||||
|
{ requiredPermission: PERMISSION_BITS.VIEW },
|
||||||
|
{ requiredPermission: PERMISSION_BITS.EDIT },
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Create a new agent
|
* Create a new agent
|
||||||
*/
|
*/
|
||||||
|
|
@ -18,21 +21,22 @@ export const useCreateAgentMutation = (
|
||||||
onMutate: (variables) => options?.onMutate?.(variables),
|
onMutate: (variables) => options?.onMutate?.(variables),
|
||||||
onError: (error, variables, context) => options?.onError?.(error, variables, context),
|
onError: (error, variables, context) => options?.onError?.(error, variables, context),
|
||||||
onSuccess: (newAgent, variables, context) => {
|
onSuccess: (newAgent, variables, context) => {
|
||||||
const listRes = queryClient.getQueryData<t.AgentListResponse>([
|
((keys: t.AgentListParams[]) => {
|
||||||
QueryKeys.agents,
|
keys.forEach((key) => {
|
||||||
defaultOrderQuery,
|
const listRes = queryClient.getQueryData<t.AgentListResponse>([QueryKeys.agents, key]);
|
||||||
]);
|
if (!listRes) {
|
||||||
|
return options?.onSuccess?.(newAgent, variables, context);
|
||||||
|
}
|
||||||
|
const currentAgents = [newAgent, ...JSON.parse(JSON.stringify(listRes.data))];
|
||||||
|
|
||||||
if (!listRes) {
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], {
|
||||||
return options?.onSuccess?.(newAgent, variables, context);
|
...listRes,
|
||||||
}
|
data: currentAgents,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
invalidateAgentMarketplaceQueries(queryClient);
|
||||||
|
|
||||||
const currentAgents = [newAgent, ...JSON.parse(JSON.stringify(listRes.data))];
|
|
||||||
|
|
||||||
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
|
||||||
...listRes,
|
|
||||||
data: currentAgents,
|
|
||||||
});
|
|
||||||
return options?.onSuccess?.(newAgent, variables, context);
|
return options?.onSuccess?.(newAgent, variables, context);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -63,30 +67,33 @@ export const useUpdateAgentMutation = (
|
||||||
return options?.onError?.(typedError, variables, context);
|
return options?.onError?.(typedError, variables, context);
|
||||||
},
|
},
|
||||||
onSuccess: (updatedAgent, variables, context) => {
|
onSuccess: (updatedAgent, variables, context) => {
|
||||||
const listRes = queryClient.getQueryData<t.AgentListResponse>([
|
((keys: t.AgentListParams[]) => {
|
||||||
QueryKeys.agents,
|
keys.forEach((key) => {
|
||||||
defaultOrderQuery,
|
const listRes = queryClient.getQueryData<t.AgentListResponse>([QueryKeys.agents, key]);
|
||||||
]);
|
|
||||||
|
|
||||||
if (!listRes) {
|
if (!listRes) {
|
||||||
return options?.onSuccess?.(updatedAgent, variables, context);
|
return options?.onSuccess?.(updatedAgent, variables, context);
|
||||||
}
|
|
||||||
|
|
||||||
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
|
||||||
...listRes,
|
|
||||||
data: listRes.data.map((agent) => {
|
|
||||||
if (agent.id === variables.agent_id) {
|
|
||||||
return updatedAgent;
|
|
||||||
}
|
}
|
||||||
return agent;
|
|
||||||
}),
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], {
|
||||||
});
|
...listRes,
|
||||||
|
data: listRes.data.map((agent) => {
|
||||||
|
if (agent.id === variables.agent_id) {
|
||||||
|
return updatedAgent;
|
||||||
|
}
|
||||||
|
return agent;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
|
||||||
queryClient.setQueryData<t.Agent>([QueryKeys.agent, variables.agent_id], updatedAgent);
|
queryClient.setQueryData<t.Agent>([QueryKeys.agent, variables.agent_id], updatedAgent);
|
||||||
queryClient.setQueryData<t.Agent>(
|
queryClient.setQueryData<t.Agent>(
|
||||||
[QueryKeys.agent, variables.agent_id, 'expanded'],
|
[QueryKeys.agent, variables.agent_id, 'expanded'],
|
||||||
updatedAgent,
|
updatedAgent,
|
||||||
);
|
);
|
||||||
|
invalidateAgentMarketplaceQueries(queryClient);
|
||||||
|
|
||||||
return options?.onSuccess?.(updatedAgent, variables, context);
|
return options?.onSuccess?.(updatedAgent, variables, context);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -108,24 +115,28 @@ export const useDeleteAgentMutation = (
|
||||||
onMutate: (variables) => options?.onMutate?.(variables),
|
onMutate: (variables) => options?.onMutate?.(variables),
|
||||||
onError: (error, variables, context) => options?.onError?.(error, variables, context),
|
onError: (error, variables, context) => options?.onError?.(error, variables, context),
|
||||||
onSuccess: (_data, variables, context) => {
|
onSuccess: (_data, variables, context) => {
|
||||||
const listRes = queryClient.getQueryData<t.AgentListResponse>([
|
const data = ((keys: t.AgentListParams[]) => {
|
||||||
QueryKeys.agents,
|
let data: t.Agent[] = [];
|
||||||
defaultOrderQuery,
|
keys.forEach((key) => {
|
||||||
]);
|
const listRes = queryClient.getQueryData<t.AgentListResponse>([QueryKeys.agents, key]);
|
||||||
|
|
||||||
if (!listRes) {
|
if (!listRes) {
|
||||||
return options?.onSuccess?.(_data, variables, context);
|
return options?.onSuccess?.(_data, variables, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = listRes.data.filter((agent) => agent.id !== variables.agent_id);
|
data = listRes.data.filter((agent) => agent.id !== variables.agent_id);
|
||||||
|
|
||||||
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], {
|
||||||
...listRes,
|
...listRes,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
|
||||||
queryClient.removeQueries([QueryKeys.agent, variables.agent_id]);
|
queryClient.removeQueries([QueryKeys.agent, variables.agent_id]);
|
||||||
queryClient.removeQueries([QueryKeys.agent, variables.agent_id, 'expanded']);
|
queryClient.removeQueries([QueryKeys.agent, variables.agent_id, 'expanded']);
|
||||||
|
invalidateAgentMarketplaceQueries(queryClient);
|
||||||
|
|
||||||
return options?.onSuccess?.(_data, variables, data);
|
return options?.onSuccess?.(_data, variables, data);
|
||||||
},
|
},
|
||||||
|
|
@ -147,22 +158,23 @@ export const useDuplicateAgentMutation = (
|
||||||
onMutate: options?.onMutate,
|
onMutate: options?.onMutate,
|
||||||
onError: options?.onError,
|
onError: options?.onError,
|
||||||
onSuccess: ({ agent, actions }, variables, context) => {
|
onSuccess: ({ agent, actions }, variables, context) => {
|
||||||
const listRes = queryClient.getQueryData<t.AgentListResponse>([
|
((keys: t.AgentListParams[]) => {
|
||||||
QueryKeys.agents,
|
keys.forEach((key) => {
|
||||||
defaultOrderQuery,
|
const listRes = queryClient.getQueryData<t.AgentListResponse>([QueryKeys.agents, key]);
|
||||||
]);
|
if (listRes) {
|
||||||
|
const currentAgents = [agent, ...listRes.data];
|
||||||
if (listRes) {
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], {
|
||||||
const currentAgents = [agent, ...listRes.data];
|
...listRes,
|
||||||
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
data: currentAgents,
|
||||||
...listRes,
|
});
|
||||||
data: currentAgents,
|
}
|
||||||
});
|
});
|
||||||
}
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
|
||||||
const existingActions = queryClient.getQueryData<t.Action[]>([QueryKeys.actions]) || [];
|
const existingActions = queryClient.getQueryData<t.Action[]>([QueryKeys.actions]) || [];
|
||||||
|
|
||||||
queryClient.setQueryData<t.Action[]>([QueryKeys.actions], existingActions.concat(actions));
|
queryClient.setQueryData<t.Action[]>([QueryKeys.actions], existingActions.concat(actions));
|
||||||
|
invalidateAgentMarketplaceQueries(queryClient);
|
||||||
|
|
||||||
return options?.onSuccess?.({ agent, actions }, variables, context);
|
return options?.onSuccess?.({ agent, actions }, variables, context);
|
||||||
},
|
},
|
||||||
|
|
@ -181,6 +193,8 @@ export const useUploadAgentAvatarMutation = (
|
||||||
t.AgentAvatarVariables, // request
|
t.AgentAvatarVariables, // request
|
||||||
unknown // context
|
unknown // context
|
||||||
> => {
|
> => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation([MutationKeys.agentAvatarUpload], {
|
return useMutation([MutationKeys.agentAvatarUpload], {
|
||||||
mutationFn: ({ postCreation, ...variables }: t.AgentAvatarVariables) =>
|
mutationFn: ({ postCreation, ...variables }: t.AgentAvatarVariables) =>
|
||||||
dataService.uploadAgentAvatar(variables),
|
dataService.uploadAgentAvatar(variables),
|
||||||
|
|
@ -207,26 +221,25 @@ export const useUpdateAgentAction = (
|
||||||
onMutate: (variables) => options?.onMutate?.(variables),
|
onMutate: (variables) => options?.onMutate?.(variables),
|
||||||
onError: (error, variables, context) => options?.onError?.(error, variables, context),
|
onError: (error, variables, context) => options?.onError?.(error, variables, context),
|
||||||
onSuccess: (updateAgentActionResponse, variables, context) => {
|
onSuccess: (updateAgentActionResponse, variables, context) => {
|
||||||
const listRes = queryClient.getQueryData<t.AgentListResponse>([
|
|
||||||
QueryKeys.agents,
|
|
||||||
defaultOrderQuery,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!listRes) {
|
|
||||||
return options?.onSuccess?.(updateAgentActionResponse, variables, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedAgent = updateAgentActionResponse[0];
|
const updatedAgent = updateAgentActionResponse[0];
|
||||||
|
((keys: t.AgentListParams[]) => {
|
||||||
|
keys.forEach((key) => {
|
||||||
|
const listRes = queryClient.getQueryData<t.AgentListResponse>([QueryKeys.agents, key]);
|
||||||
|
|
||||||
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
if (!listRes) {
|
||||||
...listRes,
|
return options?.onSuccess?.(updateAgentActionResponse, variables, context);
|
||||||
data: listRes.data.map((agent) => {
|
|
||||||
if (agent.id === variables.agent_id) {
|
|
||||||
return updatedAgent;
|
|
||||||
}
|
}
|
||||||
return agent;
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], {
|
||||||
}),
|
...listRes,
|
||||||
});
|
data: listRes.data.map((agent) => {
|
||||||
|
if (agent.id === variables.agent_id) {
|
||||||
|
return updatedAgent;
|
||||||
|
}
|
||||||
|
return agent;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
|
||||||
queryClient.setQueryData<t.Action[]>([QueryKeys.actions], (prev) => {
|
queryClient.setQueryData<t.Action[]>([QueryKeys.actions], (prev) => {
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
|
|
@ -280,28 +293,28 @@ export const useDeleteAgentAction = (
|
||||||
return action.action_id !== variables.action_id;
|
return action.action_id !== variables.action_id;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
((keys: t.AgentListParams[]) => {
|
||||||
|
keys.forEach((key) => {
|
||||||
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], (prev) => {
|
||||||
|
if (!prev) {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
queryClient.setQueryData<t.AgentListResponse>(
|
return {
|
||||||
[QueryKeys.agents, defaultOrderQuery],
|
...prev,
|
||||||
(prev) => {
|
data: prev.data.map((agent) => {
|
||||||
if (!prev) {
|
if (agent.id === variables.agent_id) {
|
||||||
return prev;
|
return {
|
||||||
}
|
...agent,
|
||||||
|
tools: agent.tools?.filter((tool) => !tool.includes(domain ?? '')),
|
||||||
return {
|
};
|
||||||
...prev,
|
}
|
||||||
data: prev.data.map((agent) => {
|
return agent;
|
||||||
if (agent.id === variables.agent_id) {
|
}),
|
||||||
return {
|
};
|
||||||
...agent,
|
});
|
||||||
tools: agent.tools?.filter((tool) => !tool.includes(domain ?? '')),
|
});
|
||||||
};
|
})(allAgentViewAndEditQueryKeys);
|
||||||
}
|
|
||||||
return agent;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const updaterFn = (prev) => {
|
const updaterFn = (prev) => {
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
return prev;
|
return prev;
|
||||||
|
|
@ -342,25 +355,30 @@ export const useRevertAgentVersionMutation = (
|
||||||
onSuccess: (revertedAgent, variables, context) => {
|
onSuccess: (revertedAgent, variables, context) => {
|
||||||
queryClient.setQueryData<t.Agent>([QueryKeys.agent, variables.agent_id], revertedAgent);
|
queryClient.setQueryData<t.Agent>([QueryKeys.agent, variables.agent_id], revertedAgent);
|
||||||
|
|
||||||
const listRes = queryClient.getQueryData<t.AgentListResponse>([
|
((keys: t.AgentListParams[]) => {
|
||||||
QueryKeys.agents,
|
keys.forEach((key) => {
|
||||||
defaultOrderQuery,
|
const listRes = queryClient.getQueryData<t.AgentListResponse>([QueryKeys.agents, key]);
|
||||||
]);
|
|
||||||
|
|
||||||
if (listRes) {
|
if (listRes) {
|
||||||
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, defaultOrderQuery], {
|
queryClient.setQueryData<t.AgentListResponse>([QueryKeys.agents, key], {
|
||||||
...listRes,
|
...listRes,
|
||||||
data: listRes.data.map((agent) => {
|
data: listRes.data.map((agent) => {
|
||||||
if (agent.id === variables.agent_id) {
|
if (agent.id === variables.agent_id) {
|
||||||
return revertedAgent;
|
return revertedAgent;
|
||||||
}
|
}
|
||||||
return agent;
|
return agent;
|
||||||
}),
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
})(allAgentViewAndEditQueryKeys);
|
||||||
|
|
||||||
return options?.onSuccess?.(revertedAgent, variables, context);
|
return options?.onSuccess?.(revertedAgent, variables, context);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const invalidateAgentMarketplaceQueries = (queryClient: QueryClient) => {
|
||||||
|
queryClient.invalidateQueries([QueryKeys.marketplaceAgents]);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { QueryKeys, dataService, EModelEndpoint, defaultOrderQuery } from 'librechat-data-provider';
|
import { QueryKeys, dataService, EModelEndpoint, PERMISSION_BITS } from 'librechat-data-provider';
|
||||||
import { useQuery, useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import type {
|
import type {
|
||||||
QueryObserverResult,
|
QueryObserverResult,
|
||||||
|
|
@ -11,7 +11,10 @@ import type t from 'librechat-data-provider';
|
||||||
/**
|
/**
|
||||||
* AGENTS
|
* AGENTS
|
||||||
*/
|
*/
|
||||||
|
export const defaultAgentParams: t.AgentListParams = {
|
||||||
|
limit: 10,
|
||||||
|
requiredPermission: PERMISSION_BITS.EDIT,
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Hook for getting all available tools for A
|
* Hook for getting all available tools for A
|
||||||
*/
|
*/
|
||||||
|
|
@ -32,7 +35,7 @@ export const useAvailableAgentToolsQuery = (): QueryObserverResult<t.TPlugin[]>
|
||||||
* Hook for listing all Agents, with optional parameters provided for pagination and sorting
|
* Hook for listing all Agents, with optional parameters provided for pagination and sorting
|
||||||
*/
|
*/
|
||||||
export const useListAgentsQuery = <TData = t.AgentListResponse>(
|
export const useListAgentsQuery = <TData = t.AgentListResponse>(
|
||||||
params: t.AgentListParams = defaultOrderQuery,
|
params: t.AgentListParams = defaultAgentParams,
|
||||||
config?: UseQueryOptions<t.AgentListResponse, unknown, TData>,
|
config?: UseQueryOptions<t.AgentListResponse, unknown, TData>,
|
||||||
): QueryObserverResult<TData> => {
|
): QueryObserverResult<TData> => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,7 @@ export default function useAgentsMap({
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
}): TAgentsMap | undefined {
|
}): TAgentsMap | undefined {
|
||||||
const { data: agentsList = null } = useListAgentsQuery(
|
const { data: agentsList = null } = useListAgentsQuery(
|
||||||
{
|
{ requiredPermission: PERMISSION_BITS.EDIT },
|
||||||
requiredPermission: PERMISSION_BITS.EDIT,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
select: (res) => mapAgents(res.data),
|
select: (res) => mapAgents(res.data),
|
||||||
enabled: isAuthenticated,
|
enabled: isAuthenticated,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
isAgentsEndpoint,
|
isAgentsEndpoint,
|
||||||
getConfigDefaults,
|
getConfigDefaults,
|
||||||
isAssistantsEndpoint,
|
isAssistantsEndpoint,
|
||||||
|
PERMISSION_BITS,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import type { TAssistantsMap, TEndpointsConfig } from 'librechat-data-provider';
|
import type { TAssistantsMap, TEndpointsConfig } from 'librechat-data-provider';
|
||||||
import type { MentionOption } from '~/common';
|
import type { MentionOption } from '~/common';
|
||||||
|
|
@ -79,28 +80,31 @@ export default function useMentions({
|
||||||
() => startupConfig?.interface ?? defaultInterface,
|
() => startupConfig?.interface ?? defaultInterface,
|
||||||
[startupConfig?.interface],
|
[startupConfig?.interface],
|
||||||
);
|
);
|
||||||
const { data: agentsList = null } = useListAgentsQuery(undefined, {
|
const { data: agentsList = null } = useListAgentsQuery(
|
||||||
enabled: hasAgentAccess && interfaceConfig.modelSelect === true,
|
{ requiredPermission: PERMISSION_BITS.VIEW },
|
||||||
select: (res) => {
|
{
|
||||||
const { data } = res;
|
enabled: hasAgentAccess && interfaceConfig.modelSelect === true,
|
||||||
return data.map(({ id, name, avatar }) => ({
|
select: (res) => {
|
||||||
value: id,
|
const { data } = res;
|
||||||
label: name ?? '',
|
return data.map(({ id, name, avatar }) => ({
|
||||||
type: EModelEndpoint.agents,
|
value: id,
|
||||||
icon: EndpointIcon({
|
label: name ?? '',
|
||||||
conversation: {
|
type: EModelEndpoint.agents,
|
||||||
agent_id: id,
|
icon: EndpointIcon({
|
||||||
endpoint: EModelEndpoint.agents,
|
conversation: {
|
||||||
iconURL: avatar?.filepath,
|
agent_id: id,
|
||||||
},
|
endpoint: EModelEndpoint.agents,
|
||||||
containerClassName: 'shadow-stroke overflow-hidden rounded-full',
|
iconURL: avatar?.filepath,
|
||||||
endpointsConfig: endpointsConfig,
|
},
|
||||||
context: 'menu-item',
|
containerClassName: 'shadow-stroke overflow-hidden rounded-full',
|
||||||
size: 20,
|
endpointsConfig: endpointsConfig,
|
||||||
}),
|
context: 'menu-item',
|
||||||
}));
|
size: 20,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
);
|
||||||
const assistantListMap = useMemo(
|
const assistantListMap = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
[EModelEndpoint.assistants]: listMap[EModelEndpoint.assistants]
|
[EModelEndpoint.assistants]: listMap[EModelEndpoint.assistants]
|
||||||
|
|
|
||||||
|
|
@ -451,7 +451,7 @@ export const revertAgentVersion = ({
|
||||||
* Get agent categories with counts for marketplace tabs
|
* Get agent categories with counts for marketplace tabs
|
||||||
*/
|
*/
|
||||||
export const getAgentCategories = (): Promise<t.TMarketplaceCategory[]> => {
|
export const getAgentCategories = (): Promise<t.TMarketplaceCategory[]> => {
|
||||||
return request.get(endpoints.agents({ path: 'marketplace/categories' }));
|
return request.get(endpoints.agents({ path: 'categories' }));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -467,7 +467,7 @@ export const getMarketplaceAgents = (params: {
|
||||||
}): Promise<a.AgentListResponse> => {
|
}): Promise<a.AgentListResponse> => {
|
||||||
return request.get(
|
return request.get(
|
||||||
endpoints.agents({
|
endpoints.agents({
|
||||||
path: 'marketplace',
|
// path: 'marketplace',
|
||||||
options: params,
|
options: params,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -286,11 +286,11 @@ export type AgentUpdateParams = {
|
||||||
|
|
||||||
export type AgentListParams = {
|
export type AgentListParams = {
|
||||||
limit?: number;
|
limit?: number;
|
||||||
before?: string | null;
|
requiredPermission: number;
|
||||||
after?: string | null;
|
category?: string;
|
||||||
order?: 'asc' | 'desc';
|
search?: string;
|
||||||
provider?: AgentProvider;
|
cursor?: string;
|
||||||
requiredPermission?: number;
|
promoted?: 0 | 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AgentListResponse = {
|
export type AgentListResponse = {
|
||||||
|
|
|
||||||
|
|
@ -182,14 +182,14 @@ export function createAgentCategoryMethods(mongoose: typeof import('mongoose'))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'it',
|
value: 'it',
|
||||||
label: 'Information Technology',
|
label: 'IT',
|
||||||
description: 'Agents for IT support, technical troubleshooting, and system administration',
|
description: 'Agents for IT support, technical troubleshooting, and system administration',
|
||||||
order: 4,
|
order: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'sales',
|
value: 'sales',
|
||||||
label: 'Sales & Marketing',
|
label: 'Sales',
|
||||||
description: 'Agents focused on sales processes, customer relations, and marketing',
|
description: 'Agents focused on sales processes, customer relations.',
|
||||||
order: 5,
|
order: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue