mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
💬 feat: assistant conversation starter (#3699)
* feat: initial UI convoStart
* fix: ConvoStarter UI
* fix: convoStarters bug
* feat: Add input field focus on conversation starters
* style: conversation starter UI update
* feat: apply fixes for starters
* style: update conversationStarters UI and fixed typo
* general UI update
* feat: Add onClick functionality to ConvoStarter component
* fix: quick fix test
* fix(AssistantSelect): remove object check
* fix: updateAssistant `conversation_starters` var
* chore: remove starter autofocus
* fix: no empty conversation starters, always show input, use Constants value for max count
* style: Update defaultTextPropsLabel styles, for a11y placeholder
* refactor: Update ConvoStarter component styles and class names for a11y and theme
* refactor: convostarter, move plus button to within persistent element
* fix: types
* chore: Update landing page assistant description styling with theming
* chore: assistant types
* refactor: documents routes
* refactor: optimize conversation starter mutations/queries
* refactor: Update listAllAssistants return type to Promise<Array<Assistant>>
* feat: edit existing starters
* feat(convo-starters): enhance ConvoStarter component and add animations
- Update ConvoStarter component styling for better visual appeal
- Implement fade-in animation for smoother appearance
- Add hover effect with background color change
- Improve text overflow handling with line-clamp and text-balance
- Ensure responsive design for various screen sizes
* feat(assistant): add conversation starters to assistant builder
- Add localization strings for conversation starters
- Update mobile.css with shake animation for max starters reached
- Enhance user experience with tooltips and dynamic input handling
* refactor: select specific fields for assistant documents fetch
* refactor: remove endpoint query key, fetch all assistant docs for now, add conversation_starters to v1 methods
* refactor: add document filters based on endpoint config
* fix: starters not applied during creation
* refactor: update AssistantSelect component to handle undefined lastSelectedModels
---------
Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
63b80c3067
commit
79f9cd5a4d
58 changed files with 602 additions and 214 deletions
|
|
@ -12,7 +12,7 @@ const Assistant = mongoose.model('assistant', assistantSchema);
|
||||||
* @param {string} searchParams.user - The user ID of the assistant's author.
|
* @param {string} searchParams.user - The user ID of the assistant's author.
|
||||||
* @param {Object} updateData - An object containing the properties to update.
|
* @param {Object} updateData - An object containing the properties to update.
|
||||||
* @param {mongoose.ClientSession} [session] - The transaction session to use (optional).
|
* @param {mongoose.ClientSession} [session] - The transaction session to use (optional).
|
||||||
* @returns {Promise<Object>} The updated or newly created assistant document as a plain object.
|
* @returns {Promise<AssistantDocument>} The updated or newly created assistant document as a plain object.
|
||||||
*/
|
*/
|
||||||
const updateAssistantDoc = async (searchParams, updateData, session = null) => {
|
const updateAssistantDoc = async (searchParams, updateData, session = null) => {
|
||||||
const options = { new: true, upsert: true, session };
|
const options = { new: true, upsert: true, session };
|
||||||
|
|
@ -25,7 +25,7 @@ const updateAssistantDoc = async (searchParams, updateData, session = null) => {
|
||||||
* @param {Object} searchParams - The search parameters to find the assistant to update.
|
* @param {Object} searchParams - The search parameters to find the assistant to update.
|
||||||
* @param {string} searchParams.assistant_id - The ID of the assistant to update.
|
* @param {string} searchParams.assistant_id - The ID of the assistant to update.
|
||||||
* @param {string} searchParams.user - The user ID of the assistant's author.
|
* @param {string} searchParams.user - The user ID of the assistant's author.
|
||||||
* @returns {Promise<Object|null>} The assistant document as a plain object, or null if not found.
|
* @returns {Promise<AssistantDocument|null>} The assistant document as a plain object, or null if not found.
|
||||||
*/
|
*/
|
||||||
const getAssistant = async (searchParams) => await Assistant.findOne(searchParams).lean();
|
const getAssistant = async (searchParams) => await Assistant.findOne(searchParams).lean();
|
||||||
|
|
||||||
|
|
@ -33,10 +33,17 @@ const getAssistant = async (searchParams) => await Assistant.findOne(searchParam
|
||||||
* Retrieves all assistants that match the given search parameters.
|
* Retrieves all assistants that match the given search parameters.
|
||||||
*
|
*
|
||||||
* @param {Object} searchParams - The search parameters to find matching assistants.
|
* @param {Object} searchParams - The search parameters to find matching assistants.
|
||||||
* @returns {Promise<Array<Object>>} A promise that resolves to an array of action documents as plain objects.
|
* @param {Object} [select] - Optional. Specifies which document fields to include or exclude.
|
||||||
|
* @returns {Promise<Array<AssistantDocument>>} A promise that resolves to an array of assistant documents as plain objects.
|
||||||
*/
|
*/
|
||||||
const getAssistants = async (searchParams) => {
|
const getAssistants = async (searchParams, select = null) => {
|
||||||
return await Assistant.find(searchParams).lean();
|
let query = Assistant.find(searchParams);
|
||||||
|
|
||||||
|
if (select) {
|
||||||
|
query = query.select(select);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query.lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ const assistantSchema = mongoose.Schema(
|
||||||
},
|
},
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
conversation_starters: {
|
||||||
|
type: [String],
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
access_level: {
|
access_level: {
|
||||||
type: Number,
|
type: Number,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const _listAssistants = async ({ req, res, version, query }) => {
|
||||||
* @param {object} params.res - The response object, used for initializing the client.
|
* @param {object} params.res - The response object, used for initializing the client.
|
||||||
* @param {string} params.version - The API version to use.
|
* @param {string} params.version - The API version to use.
|
||||||
* @param {Omit<AssistantListParams, 'endpoint'>} params.query - The query parameters to list assistants (e.g., limit, order).
|
* @param {Omit<AssistantListParams, 'endpoint'>} params.query - The query parameters to list assistants (e.g., limit, order).
|
||||||
* @returns {Promise<object>} A promise that resolves to the response from the `openai.beta.assistants.list` method call.
|
* @returns {Promise<Array<Assistant>>} A promise that resolves to the response from the `openai.beta.assistants.list` method call.
|
||||||
*/
|
*/
|
||||||
const listAllAssistants = async ({ req, res, version, query }) => {
|
const listAllAssistants = async ({ req, res, version, query }) => {
|
||||||
/** @type {{ openai: OpenAIClient }} */
|
/** @type {{ openai: OpenAIClient }} */
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ const createAssistant = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { openai } = await getOpenAIClient({ req, res });
|
const { openai } = await getOpenAIClient({ req, res });
|
||||||
|
|
||||||
const { tools = [], endpoint, ...assistantData } = req.body;
|
const { tools = [], endpoint, conversation_starters, ...assistantData } = req.body;
|
||||||
|
delete assistantData.conversation_starters;
|
||||||
|
|
||||||
assistantData.tools = tools
|
assistantData.tools = tools
|
||||||
.map((tool) => {
|
.map((tool) => {
|
||||||
if (typeof tool !== 'string') {
|
if (typeof tool !== 'string') {
|
||||||
|
|
@ -41,11 +43,22 @@ const createAssistant = async (req, res) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const assistant = await openai.beta.assistants.create(assistantData);
|
const assistant = await openai.beta.assistants.create(assistantData);
|
||||||
const promise = updateAssistantDoc({ assistant_id: assistant.id }, { user: req.user.id });
|
|
||||||
|
const createData = { user: req.user.id };
|
||||||
|
if (conversation_starters) {
|
||||||
|
createData.conversation_starters = conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = await updateAssistantDoc({ assistant_id: assistant.id }, createData);
|
||||||
|
|
||||||
if (azureModelIdentifier) {
|
if (azureModelIdentifier) {
|
||||||
assistant.model = azureModelIdentifier;
|
assistant.model = azureModelIdentifier;
|
||||||
}
|
}
|
||||||
await promise;
|
|
||||||
|
if (document.conversation_starters) {
|
||||||
|
assistant.conversation_starters = document.conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug('/assistants/', assistant);
|
logger.debug('/assistants/', assistant);
|
||||||
res.status(201).json(assistant);
|
res.status(201).json(assistant);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -88,7 +101,7 @@ const patchAssistant = async (req, res) => {
|
||||||
await validateAuthor({ req, openai });
|
await validateAuthor({ req, openai });
|
||||||
|
|
||||||
const assistant_id = req.params.id;
|
const assistant_id = req.params.id;
|
||||||
const { endpoint: _e, ...updateData } = req.body;
|
const { endpoint: _e, conversation_starters, ...updateData } = req.body;
|
||||||
updateData.tools = (updateData.tools ?? [])
|
updateData.tools = (updateData.tools ?? [])
|
||||||
.map((tool) => {
|
.map((tool) => {
|
||||||
if (typeof tool !== 'string') {
|
if (typeof tool !== 'string') {
|
||||||
|
|
@ -104,6 +117,15 @@ const patchAssistant = async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedAssistant = await openai.beta.assistants.update(assistant_id, updateData);
|
const updatedAssistant = await openai.beta.assistants.update(assistant_id, updateData);
|
||||||
|
|
||||||
|
if (conversation_starters !== undefined) {
|
||||||
|
const conversationStartersUpdate = await updateAssistantDoc(
|
||||||
|
{ assistant_id },
|
||||||
|
{ conversation_starters },
|
||||||
|
);
|
||||||
|
updatedAssistant.conversation_starters = conversationStartersUpdate.conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
res.json(updatedAssistant);
|
res.json(updatedAssistant);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[/assistants/:id] Error updating assistant', error);
|
logger.error('[/assistants/:id] Error updating assistant', error);
|
||||||
|
|
@ -153,6 +175,32 @@ const listAssistants = async (req, res) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter assistants based on configuration.
|
||||||
|
*
|
||||||
|
* @param {object} params - The parameters object.
|
||||||
|
* @param {string} params.userId - The user ID to filter private assistants.
|
||||||
|
* @param {AssistantDocument[]} params.assistants - The list of assistants to filter.
|
||||||
|
* @param {Partial<TAssistantEndpoint>} [params.assistantsConfig] - The assistant configuration.
|
||||||
|
* @returns {AssistantDocument[]} - The filtered list of assistants.
|
||||||
|
*/
|
||||||
|
function filterAssistantDocs({ documents, userId, assistantsConfig = {} }) {
|
||||||
|
const { supportedIds, excludedIds, privateAssistants } = assistantsConfig;
|
||||||
|
const removeUserId = (doc) => {
|
||||||
|
const { user: _u, ...document } = doc;
|
||||||
|
return document;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (privateAssistants) {
|
||||||
|
return documents.filter((doc) => userId === doc.user.toString()).map(removeUserId);
|
||||||
|
} else if (supportedIds?.length) {
|
||||||
|
return documents.filter((doc) => supportedIds.includes(doc.assistant_id)).map(removeUserId);
|
||||||
|
} else if (excludedIds?.length) {
|
||||||
|
return documents.filter((doc) => !excludedIds.includes(doc.assistant_id)).map(removeUserId);
|
||||||
|
}
|
||||||
|
return documents.map(removeUserId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the user's assistant documents (metadata saved to database).
|
* Returns a list of the user's assistant documents (metadata saved to database).
|
||||||
* @route GET /assistants/documents
|
* @route GET /assistants/documents
|
||||||
|
|
@ -160,7 +208,25 @@ const listAssistants = async (req, res) => {
|
||||||
*/
|
*/
|
||||||
const getAssistantDocuments = async (req, res) => {
|
const getAssistantDocuments = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
res.json(await getAssistants({ user: req.user.id }));
|
const endpoint = req.query;
|
||||||
|
const assistantsConfig = req.app.locals[endpoint];
|
||||||
|
const documents = await getAssistants(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
user: 1,
|
||||||
|
assistant_id: 1,
|
||||||
|
conversation_starters: 1,
|
||||||
|
createdAt: 1,
|
||||||
|
updatedAt: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const docs = filterAssistantDocs({
|
||||||
|
documents,
|
||||||
|
userId: req.user.id,
|
||||||
|
assistantsConfig,
|
||||||
|
});
|
||||||
|
res.json(docs);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[/assistants/documents] Error listing assistant documents', error);
|
logger.error('[/assistants/documents] Error listing assistant documents', error);
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,9 @@ const createAssistant = async (req, res) => {
|
||||||
/** @type {{ openai: OpenAIClient }} */
|
/** @type {{ openai: OpenAIClient }} */
|
||||||
const { openai } = await getOpenAIClient({ req, res });
|
const { openai } = await getOpenAIClient({ req, res });
|
||||||
|
|
||||||
const { tools = [], endpoint, ...assistantData } = req.body;
|
const { tools = [], endpoint, conversation_starters, ...assistantData } = req.body;
|
||||||
|
delete assistantData.conversation_starters;
|
||||||
|
|
||||||
assistantData.tools = tools
|
assistantData.tools = tools
|
||||||
.map((tool) => {
|
.map((tool) => {
|
||||||
if (typeof tool !== 'string') {
|
if (typeof tool !== 'string') {
|
||||||
|
|
@ -39,11 +41,22 @@ const createAssistant = async (req, res) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const assistant = await openai.beta.assistants.create(assistantData);
|
const assistant = await openai.beta.assistants.create(assistantData);
|
||||||
const promise = updateAssistantDoc({ assistant_id: assistant.id }, { user: req.user.id });
|
|
||||||
|
const createData = { user: req.user.id };
|
||||||
|
if (conversation_starters) {
|
||||||
|
createData.conversation_starters = conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = await updateAssistantDoc({ assistant_id: assistant.id }, createData);
|
||||||
|
|
||||||
if (azureModelIdentifier) {
|
if (azureModelIdentifier) {
|
||||||
assistant.model = azureModelIdentifier;
|
assistant.model = azureModelIdentifier;
|
||||||
}
|
}
|
||||||
await promise;
|
|
||||||
|
if (document.conversation_starters) {
|
||||||
|
assistant.conversation_starters = document.conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug('/assistants/', assistant);
|
logger.debug('/assistants/', assistant);
|
||||||
res.status(201).json(assistant);
|
res.status(201).json(assistant);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -64,6 +77,17 @@ const createAssistant = async (req, res) => {
|
||||||
const updateAssistant = async ({ req, openai, assistant_id, updateData }) => {
|
const updateAssistant = async ({ req, openai, assistant_id, updateData }) => {
|
||||||
await validateAuthor({ req, openai });
|
await validateAuthor({ req, openai });
|
||||||
const tools = [];
|
const tools = [];
|
||||||
|
let conversation_starters = null;
|
||||||
|
|
||||||
|
if (updateData?.conversation_starters) {
|
||||||
|
const conversationStartersUpdate = await updateAssistantDoc(
|
||||||
|
{ assistant_id: assistant_id },
|
||||||
|
{ conversation_starters: updateData.conversation_starters },
|
||||||
|
);
|
||||||
|
conversation_starters = conversationStartersUpdate.conversation_starters;
|
||||||
|
|
||||||
|
delete updateData.conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
let hasFileSearch = false;
|
let hasFileSearch = false;
|
||||||
for (const tool of updateData.tools ?? []) {
|
for (const tool of updateData.tools ?? []) {
|
||||||
|
|
@ -108,7 +132,13 @@ const updateAssistant = async ({ req, openai, assistant_id, updateData }) => {
|
||||||
updateData.model = openai.locals.azureOptions.azureOpenAIApiDeploymentName;
|
updateData.model = openai.locals.azureOptions.azureOpenAIApiDeploymentName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await openai.beta.assistants.update(assistant_id, updateData);
|
const assistant = await openai.beta.assistants.update(assistant_id, updateData);
|
||||||
|
|
||||||
|
if (conversation_starters) {
|
||||||
|
assistant.conversation_starters = conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
|
return assistant;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
13
api/server/routes/assistants/documents.js
Normal file
13
api/server/routes/assistants/documents.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
const express = require('express');
|
||||||
|
const controllers = require('~/server/controllers/assistants/v1');
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of the user's assistant documents (metadata saved to database).
|
||||||
|
* @route GET /assistants/documents
|
||||||
|
* @returns {AssistantDocument[]} 200 - success response - application/json
|
||||||
|
*/
|
||||||
|
router.get('/', controllers.getAssistantDocuments);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const multer = require('multer');
|
const multer = require('multer');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const controllers = require('~/server/controllers/assistants/v1');
|
const controllers = require('~/server/controllers/assistants/v1');
|
||||||
|
const documents = require('./documents');
|
||||||
const actions = require('./actions');
|
const actions = require('./actions');
|
||||||
const tools = require('./tools');
|
const tools = require('./tools');
|
||||||
|
|
||||||
|
|
@ -20,6 +21,13 @@ router.use('/actions', actions);
|
||||||
*/
|
*/
|
||||||
router.use('/tools', tools);
|
router.use('/tools', tools);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an assistant.
|
||||||
|
* @route GET /assistants/documents
|
||||||
|
* @returns {AssistantDocument[]} 200 - application/json
|
||||||
|
*/
|
||||||
|
router.use('/documents', documents);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an assistant.
|
* Create an assistant.
|
||||||
* @route POST /assistants
|
* @route POST /assistants
|
||||||
|
|
@ -61,13 +69,6 @@ router.delete('/:id', controllers.deleteAssistant);
|
||||||
*/
|
*/
|
||||||
router.get('/', controllers.listAssistants);
|
router.get('/', controllers.listAssistants);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of the user's assistant documents (metadata saved to database).
|
|
||||||
* @route GET /assistants/documents
|
|
||||||
* @returns {AssistantDocument[]} 200 - success response - application/json
|
|
||||||
*/
|
|
||||||
router.get('/documents', controllers.getAssistantDocuments);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads and updates an avatar for a specific assistant.
|
* Uploads and updates an avatar for a specific assistant.
|
||||||
* @route POST /avatar/:assistant_id
|
* @route POST /avatar/:assistant_id
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const multer = require('multer');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const v1 = require('~/server/controllers/assistants/v1');
|
const v1 = require('~/server/controllers/assistants/v1');
|
||||||
const v2 = require('~/server/controllers/assistants/v2');
|
const v2 = require('~/server/controllers/assistants/v2');
|
||||||
|
const documents = require('./documents');
|
||||||
const actions = require('./actions');
|
const actions = require('./actions');
|
||||||
const tools = require('./tools');
|
const tools = require('./tools');
|
||||||
|
|
||||||
|
|
@ -21,6 +22,13 @@ router.use('/actions', actions);
|
||||||
*/
|
*/
|
||||||
router.use('/tools', tools);
|
router.use('/tools', tools);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an assistant.
|
||||||
|
* @route GET /assistants/documents
|
||||||
|
* @returns {AssistantDocument[]} 200 - application/json
|
||||||
|
*/
|
||||||
|
router.use('/documents', documents);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an assistant.
|
* Create an assistant.
|
||||||
* @route POST /assistants
|
* @route POST /assistants
|
||||||
|
|
@ -62,13 +70,6 @@ router.delete('/:id', v1.deleteAssistant);
|
||||||
*/
|
*/
|
||||||
router.get('/', v1.listAssistants);
|
router.get('/', v1.listAssistants);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of the user's assistant documents (metadata saved to database).
|
|
||||||
* @route GET /assistants/documents
|
|
||||||
* @returns {AssistantDocument[]} 200 - success response - application/json
|
|
||||||
*/
|
|
||||||
router.get('/documents', v1.getAssistantDocuments);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads and updates an avatar for a specific assistant.
|
* Uploads and updates an avatar for a specific assistant.
|
||||||
* @route POST /avatar/:assistant_id
|
* @route POST /avatar/:assistant_id
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export type AssistantForm = {
|
||||||
name: string | null;
|
name: string | null;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
instructions: string | null;
|
instructions: string | null;
|
||||||
|
conversation_starters: string[];
|
||||||
model: string;
|
model: string;
|
||||||
functions: string[];
|
functions: string[];
|
||||||
} & Actions;
|
} & Actions;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import type {
|
||||||
TConversation,
|
TConversation,
|
||||||
TStartupConfig,
|
TStartupConfig,
|
||||||
EModelEndpoint,
|
EModelEndpoint,
|
||||||
|
ActionMetadata,
|
||||||
AssistantsEndpoint,
|
AssistantsEndpoint,
|
||||||
TMessageContentParts,
|
TMessageContentParts,
|
||||||
AuthorizationTypeEnum,
|
AuthorizationTypeEnum,
|
||||||
|
|
@ -146,9 +147,13 @@ export type ActionAuthForm = {
|
||||||
token_exchange_method: TokenExchangeMethodEnum;
|
token_exchange_method: TokenExchangeMethodEnum;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ActionWithNullableMetadata = Omit<Action, 'metadata'> & {
|
||||||
|
metadata: ActionMetadata | null;
|
||||||
|
};
|
||||||
|
|
||||||
export type AssistantPanelProps = {
|
export type AssistantPanelProps = {
|
||||||
index?: number;
|
index?: number;
|
||||||
action?: Action;
|
action?: ActionWithNullableMetadata;
|
||||||
actions?: Action[];
|
actions?: Action[];
|
||||||
assistant_id?: string;
|
assistant_id?: string;
|
||||||
activePanel?: string;
|
activePanel?: string;
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const DeleteBookmarkButton: FC<{
|
||||||
</Label>
|
</Label>
|
||||||
}
|
}
|
||||||
confirm={confirmDelete}
|
confirm={confirmDelete}
|
||||||
className="transition-color flex size-7 items-center justify-center rounded-lg duration-200 hover:bg-surface-hover"
|
className="transition-colors flex size-7 items-center justify-center rounded-lg duration-200 hover:bg-surface-hover"
|
||||||
icon={<TrashIcon className="size-4" />}
|
icon={<TrashIcon className="size-4" />}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const EditBookmarkButton: FC<{
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="transition-color flex size-7 items-center justify-center rounded-lg duration-200 hover:bg-surface-hover"
|
className="transition-colors flex size-7 items-center justify-center rounded-lg duration-200 hover:bg-surface-hover"
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
|
|
|
||||||
17
client/src/components/Chat/ConvoStarter.tsx
Normal file
17
client/src/components/Chat/ConvoStarter.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
interface ConvoStarterProps {
|
||||||
|
text: string;
|
||||||
|
onClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ConvoStarter({ text, onClick }: ConvoStarterProps) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={onClick}
|
||||||
|
className="relative flex w-40 cursor-pointer flex-col gap-2 rounded-2xl border border-border-medium px-3 pb-4 pt-3 text-start align-top text-[15px] shadow-[0_0_2px_0_rgba(0,0,0,0.05),0_4px_6px_0_rgba(0,0,0,0.02)] transition-colors duration-300 ease-in-out fade-in hover:bg-surface-tertiary"
|
||||||
|
>
|
||||||
|
<p className="break-word line-clamp-3 overflow-hidden text-balance break-all text-text-secondary">
|
||||||
|
{text}
|
||||||
|
</p>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -136,7 +136,7 @@ const ChatForm = ({ index = 0 }) => {
|
||||||
newConversation={generateConversation}
|
newConversation={generateConversation}
|
||||||
textAreaRef={textAreaRef}
|
textAreaRef={textAreaRef}
|
||||||
commandChar="+"
|
commandChar="+"
|
||||||
placeholder="com_ui_add"
|
placeholder="com_ui_add_model_preset"
|
||||||
includeAssistants={false}
|
includeAssistants={false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import { EModelEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
import { useMemo } from 'react';
|
||||||
|
import { EModelEndpoint, isAssistantsEndpoint, Constants } from 'librechat-data-provider';
|
||||||
import { useGetEndpointsQuery, useGetStartupConfig } from 'librechat-data-provider/react-query';
|
import { useGetEndpointsQuery, useGetStartupConfig } from 'librechat-data-provider/react-query';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
||||||
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
||||||
|
import { useGetAssistantDocsQuery } from '~/data-provider';
|
||||||
import ConvoIcon from '~/components/Endpoints/ConvoIcon';
|
import ConvoIcon from '~/components/Endpoints/ConvoIcon';
|
||||||
|
import { useLocalize, useSubmitMessage } from '~/hooks';
|
||||||
import { BirthdayIcon } from '~/components/svg';
|
import { BirthdayIcon } from '~/components/svg';
|
||||||
import { getIconEndpoint, cn } from '~/utils';
|
import { getIconEndpoint, cn } from '~/utils';
|
||||||
import { useLocalize } from '~/hooks';
|
import ConvoStarter from './ConvoStarter';
|
||||||
|
|
||||||
export default function Landing({ Header }: { Header?: ReactNode }) {
|
export default function Landing({ Header }: { Header?: ReactNode }) {
|
||||||
const { conversation } = useChatContext();
|
const { conversation } = useChatContext();
|
||||||
|
|
@ -29,21 +32,36 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
|
||||||
|
|
||||||
const iconURL = conversation?.iconURL;
|
const iconURL = conversation?.iconURL;
|
||||||
endpoint = getIconEndpoint({ endpointsConfig, iconURL, endpoint });
|
endpoint = getIconEndpoint({ endpointsConfig, iconURL, endpoint });
|
||||||
|
const { data: documentsMap = new Map() } = useGetAssistantDocsQuery(endpoint, {
|
||||||
|
select: (data) => new Map(data.map((dbA) => [dbA.assistant_id, dbA])),
|
||||||
|
});
|
||||||
|
|
||||||
const isAssistant = isAssistantsEndpoint(endpoint);
|
const isAssistant = isAssistantsEndpoint(endpoint);
|
||||||
const assistant = isAssistant ? assistantMap?.[endpoint][assistant_id ?? ''] : undefined;
|
const assistant = isAssistant ? assistantMap?.[endpoint][assistant_id ?? ''] : undefined;
|
||||||
const assistantName = assistant && assistant.name;
|
const assistantName = assistant?.name ?? '';
|
||||||
const assistantDesc = assistant && assistant.description;
|
const assistantDesc = assistant?.description ?? '';
|
||||||
const avatar = assistant && (assistant.metadata?.avatar as string);
|
const avatar = assistant?.metadata?.avatar ?? '';
|
||||||
|
const conversation_starters = useMemo(() => {
|
||||||
|
/* The user made updates, use client-side cache, */
|
||||||
|
if (assistant?.conversation_starters) {
|
||||||
|
return assistant.conversation_starters;
|
||||||
|
}
|
||||||
|
/* If none in cache, we use the latest assistant docs */
|
||||||
|
const assistantDocs = documentsMap.get(assistant_id ?? '');
|
||||||
|
return assistantDocs?.conversation_starters ?? [];
|
||||||
|
}, [documentsMap, assistant_id, assistant?.conversation_starters]);
|
||||||
|
|
||||||
const containerClassName =
|
const containerClassName =
|
||||||
'shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black';
|
'shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black';
|
||||||
|
|
||||||
|
const { submitMessage } = useSubmitMessage();
|
||||||
|
const sendConversationStarter = (text: string) => submitMessage({ text });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider delayDuration={50}>
|
<TooltipProvider delayDuration={50}>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<div className="relative h-full">
|
<div className="relative h-full">
|
||||||
<div className="absolute left-0 right-0">{Header && Header}</div>
|
<div className="absolute left-0 right-0">{Header != null ? Header : null}</div>
|
||||||
<div className="flex h-full flex-col items-center justify-center">
|
<div className="flex h-full flex-col items-center justify-center">
|
||||||
<div className={cn('relative h-12 w-12', assistantName && avatar ? 'mb-0' : 'mb-3')}>
|
<div className={cn('relative h-12 w-12', assistantName && avatar ? 'mb-0' : 'mb-3')}>
|
||||||
<ConvoIcon
|
<ConvoIcon
|
||||||
|
|
@ -55,7 +73,7 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
|
||||||
className="h-2/3 w-2/3"
|
className="h-2/3 w-2/3"
|
||||||
size={41}
|
size={41}
|
||||||
/>
|
/>
|
||||||
{!!startupConfig?.showBirthdayIcon && (
|
{startupConfig?.showBirthdayIcon === true ? (
|
||||||
<div>
|
<div>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
<BirthdayIcon className="absolute bottom-8 right-2.5" />
|
<BirthdayIcon className="absolute bottom-8 right-2.5" />
|
||||||
|
|
@ -64,14 +82,14 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
|
||||||
{localize('com_ui_happy_birthday')}
|
{localize('com_ui_happy_birthday')}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</div>
|
</div>
|
||||||
)}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
{assistantName ? (
|
{assistantName ? (
|
||||||
<div className="flex flex-col items-center gap-0 p-2">
|
<div className="flex flex-col items-center gap-0 p-2">
|
||||||
<div className="text-center text-2xl font-medium dark:text-white">
|
<div className="text-center text-2xl font-medium dark:text-white">
|
||||||
{assistantName}
|
{assistantName}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-token-text-secondary max-w-md text-center text-xl font-normal ">
|
<div className="max-w-md text-center text-sm font-normal text-text-primary ">
|
||||||
{assistantDesc ? assistantDesc : localize('com_nav_welcome_message')}
|
{assistantDesc ? assistantDesc : localize('com_nav_welcome_message')}
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="mt-1 flex items-center gap-1 text-token-text-tertiary">
|
{/* <div className="mt-1 flex items-center gap-1 text-token-text-tertiary">
|
||||||
|
|
@ -85,6 +103,18 @@ export default function Landing({ Header }: { Header?: ReactNode }) {
|
||||||
: conversation?.greeting ?? localize('com_nav_welcome_message')}
|
: conversation?.greeting ?? localize('com_nav_welcome_message')}
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
|
<div className="mt-8 flex flex-wrap justify-center gap-3 px-4">
|
||||||
|
{conversation_starters.length > 0 &&
|
||||||
|
conversation_starters
|
||||||
|
.slice(0, Constants.MAX_CONVO_STARTERS)
|
||||||
|
.map((text, index) => (
|
||||||
|
<ConvoStarter
|
||||||
|
key={index}
|
||||||
|
text={text}
|
||||||
|
onClick={() => sendConversationStarter(text)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon';
|
||||||
|
|
||||||
export default function PromptCard({ promptGroup }: { promptGroup: TPromptGroup }) {
|
export default function PromptCard({ promptGroup }: { promptGroup: TPromptGroup }) {
|
||||||
return (
|
return (
|
||||||
<div className="hover:bg-token-main-surface-secondary relative flex w-40 cursor-pointer flex-col gap-2 rounded-2xl border px-3 pb-4 pt-3 text-start align-top text-[15px] shadow-[0_0_2px_0_rgba(0,0,0,0.05),0_4px_6px_0_rgba(0,0,0,0.02)] transition transition-colors duration-300 ease-in-out fade-in hover:bg-slate-100 dark:border-gray-600 dark:hover:bg-gray-700">
|
<div className="hover:bg-token-main-surface-secondary relative flex w-40 cursor-pointer flex-col gap-2 rounded-2xl border px-3 pb-4 pt-3 text-start align-top text-[15px] shadow-[0_0_2px_0_rgba(0,0,0,0.05),0_4px_6px_0_rgba(0,0,0,0.02)] transition-colors duration-300 ease-in-out fade-in hover:bg-slate-100 dark:border-gray-600 dark:hover:bg-gray-700">
|
||||||
<div className="">
|
<div className="">
|
||||||
<CategoryIcon className="size-4" category={promptGroup.category || ''} />
|
<CategoryIcon className="size-4" category={promptGroup.category || ''} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import { EModelEndpoint, isAssistantsEndpoint } from 'librechat-data-provider';
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
|
||||||
import { TooltipProvider, Tooltip } from '~/components/ui';
|
|
||||||
import ConvoIcon from '~/components/Endpoints/ConvoIcon';
|
|
||||||
import { getIconEndpoint, cn } from '~/utils';
|
|
||||||
import Prompts from './Prompts';
|
|
||||||
|
|
||||||
export default function Landing({ Header }: { Header?: ReactNode }) {
|
|
||||||
const { conversation } = useChatContext();
|
|
||||||
const assistantMap = useAssistantsMapContext();
|
|
||||||
const { data: endpointsConfig } = useGetEndpointsQuery();
|
|
||||||
|
|
||||||
let { endpoint = '' } = conversation ?? {};
|
|
||||||
const { assistant_id = null } = conversation ?? {};
|
|
||||||
|
|
||||||
if (
|
|
||||||
endpoint === EModelEndpoint.chatGPTBrowser ||
|
|
||||||
endpoint === EModelEndpoint.azureOpenAI ||
|
|
||||||
endpoint === EModelEndpoint.gptPlugins
|
|
||||||
) {
|
|
||||||
endpoint = EModelEndpoint.openAI;
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconURL = conversation?.iconURL;
|
|
||||||
endpoint = getIconEndpoint({ endpointsConfig, iconURL, endpoint });
|
|
||||||
|
|
||||||
const isAssistant = isAssistantsEndpoint(endpoint);
|
|
||||||
const assistant = isAssistant && assistantMap?.[endpoint]?.[assistant_id ?? ''];
|
|
||||||
const assistantName = (assistant && assistant?.name) || '';
|
|
||||||
const avatar = (assistant && (assistant?.metadata?.avatar as string)) || '';
|
|
||||||
|
|
||||||
const containerClassName =
|
|
||||||
'shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TooltipProvider delayDuration={50}>
|
|
||||||
<Tooltip>
|
|
||||||
<div className="relative h-full">
|
|
||||||
<div className="absolute left-0 right-0">{Header && Header}</div>
|
|
||||||
<div className="flex h-full flex-col items-center justify-center">
|
|
||||||
<div className={cn('relative h-12 w-12', assistantName && avatar ? 'mb-0' : 'mb-3')}>
|
|
||||||
<ConvoIcon
|
|
||||||
conversation={conversation}
|
|
||||||
assistantMap={assistantMap}
|
|
||||||
endpointsConfig={endpointsConfig}
|
|
||||||
containerClassName={containerClassName}
|
|
||||||
context="landing"
|
|
||||||
className="h-2/3 w-2/3"
|
|
||||||
size={41}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="h-3/5">
|
|
||||||
<Prompts />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -149,10 +149,10 @@ export default function Conversation({
|
||||||
/>
|
/>
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
<button onClick={cancelRename}>
|
<button onClick={cancelRename}>
|
||||||
<X className="transition-color h-4 w-4 duration-200 ease-in-out hover:opacity-70" />
|
<X className="transition-colors h-4 w-4 duration-200 ease-in-out hover:opacity-70" />
|
||||||
</button>
|
</button>
|
||||||
<button onClick={onRename}>
|
<button onClick={onRename}>
|
||||||
<Check className="transition-color h-4 w-4 duration-200 ease-in-out hover:opacity-70" />
|
<Check className="transition-colors h-4 w-4 duration-200 ease-in-out hover:opacity-70" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import type {
|
||||||
ValidationResult,
|
ValidationResult,
|
||||||
AssistantsEndpoint,
|
AssistantsEndpoint,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import type { ActionAuthForm } from '~/common';
|
import type { ActionAuthForm, ActionWithNullableMetadata } from '~/common';
|
||||||
import type { Spec } from './ActionsTable';
|
import type { Spec } from './ActionsTable';
|
||||||
import { useAssistantsMapContext, useToastContext } from '~/Providers';
|
import { useAssistantsMapContext, useToastContext } from '~/Providers';
|
||||||
import { ActionsTable, columns } from './ActionsTable';
|
import { ActionsTable, columns } from './ActionsTable';
|
||||||
|
|
@ -37,7 +37,7 @@ export default function ActionsInput({
|
||||||
version,
|
version,
|
||||||
setAction,
|
setAction,
|
||||||
}: {
|
}: {
|
||||||
action?: Action;
|
action?: ActionWithNullableMetadata;
|
||||||
assistant_id?: string;
|
assistant_id?: string;
|
||||||
endpoint: AssistantsEndpoint;
|
endpoint: AssistantsEndpoint;
|
||||||
version: number | string;
|
version: number | string;
|
||||||
|
|
@ -62,12 +62,13 @@ export default function ActionsInput({
|
||||||
const [functions, setFunctions] = useState<FunctionTool[] | null>(null);
|
const [functions, setFunctions] = useState<FunctionTool[] | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!action?.metadata.raw_spec) {
|
const rawSpec = action?.metadata?.raw_spec ?? '';
|
||||||
|
if (!rawSpec) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setInputValue(action.metadata.raw_spec);
|
setInputValue(rawSpec);
|
||||||
debouncedValidation(action.metadata.raw_spec, handleResult);
|
debouncedValidation(rawSpec, handleResult);
|
||||||
}, [action?.metadata.raw_spec]);
|
}, [action?.metadata?.raw_spec]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!validationResult || !validationResult.status || !validationResult.spec) {
|
if (!validationResult || !validationResult.status || !validationResult.spec) {
|
||||||
|
|
@ -100,7 +101,8 @@ export default function ActionsInput({
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
showToast({
|
showToast({
|
||||||
message: (error as Error).message ?? localize('com_assistants_update_actions_error'),
|
message:
|
||||||
|
(error as Error | undefined)?.message ?? localize('com_assistants_update_actions_error'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -108,7 +110,8 @@ export default function ActionsInput({
|
||||||
|
|
||||||
const saveAction = handleSubmit((authFormData) => {
|
const saveAction = handleSubmit((authFormData) => {
|
||||||
console.log('authFormData', authFormData);
|
console.log('authFormData', authFormData);
|
||||||
if (!assistant_id) {
|
const currentAssistantId = assistant_id ?? '';
|
||||||
|
if (!currentAssistantId) {
|
||||||
// alert user?
|
// alert user?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +124,10 @@ export default function ActionsInput({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { metadata = {} } = action ?? {};
|
let { metadata } = action ?? {};
|
||||||
|
if (!metadata) {
|
||||||
|
metadata = {};
|
||||||
|
}
|
||||||
const action_id = action?.action_id;
|
const action_id = action?.action_id;
|
||||||
metadata.raw_spec = inputValue;
|
metadata.raw_spec = inputValue;
|
||||||
const parsedUrl = new URL(data[0].domain);
|
const parsedUrl = new URL(data[0].domain);
|
||||||
|
|
@ -177,10 +183,10 @@ export default function ActionsInput({
|
||||||
action_id,
|
action_id,
|
||||||
metadata,
|
metadata,
|
||||||
functions,
|
functions,
|
||||||
assistant_id,
|
assistant_id: currentAssistantId,
|
||||||
endpoint,
|
endpoint,
|
||||||
version,
|
version,
|
||||||
model: assistantMap?.[endpoint][assistant_id].model ?? '',
|
model: assistantMap?.[endpoint][currentAssistantId].model ?? '',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ export default function ActionsPanel({
|
||||||
},
|
},
|
||||||
onError(error) {
|
onError(error) {
|
||||||
showToast({
|
showToast({
|
||||||
message: (error as Error)?.message ?? localize('com_assistants_delete_actions_error'),
|
message:
|
||||||
|
(error as Error | undefined)?.message ?? localize('com_assistants_delete_actions_error'),
|
||||||
status: 'error',
|
status: 'error',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -127,7 +128,7 @@ export default function ActionsPanel({
|
||||||
<div className="absolute right-0 top-6">
|
<div className="absolute right-0 top-6">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!assistant_id || !action.action_id}
|
disabled={!(assistant_id ?? '') || !action.action_id}
|
||||||
className="btn btn-neutral border-token-border-light relative h-9 rounded-lg font-medium"
|
className="btn btn-neutral border-token-border-light relative h-9 rounded-lg font-medium"
|
||||||
>
|
>
|
||||||
<TrashIcon className="text-red-500" />
|
<TrashIcon className="text-red-500" />
|
||||||
|
|
@ -145,16 +146,17 @@ export default function ActionsPanel({
|
||||||
}
|
}
|
||||||
selection={{
|
selection={{
|
||||||
selectHandler: () => {
|
selectHandler: () => {
|
||||||
if (!assistant_id) {
|
const currentId = assistant_id ?? '';
|
||||||
|
if (!currentId) {
|
||||||
return showToast({
|
return showToast({
|
||||||
message: 'No assistant_id found, is the assistant created?',
|
message: 'No assistant_id found, is the assistant created?',
|
||||||
status: 'error',
|
status: 'error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
deleteAction.mutate({
|
deleteAction.mutate({
|
||||||
model: assistantMap[endpoint][assistant_id].model,
|
model: assistantMap?.[endpoint][currentId].model ?? '',
|
||||||
action_id: action.action_id,
|
action_id: action.action_id,
|
||||||
assistant_id,
|
assistant_id: currentId,
|
||||||
endpoint,
|
endpoint,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export default function AssistantAction({
|
||||||
{isHovering && (
|
{isHovering && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="transition-color flex h-9 w-9 min-w-9 items-center justify-center rounded-lg duration-200 hover:bg-gray-200 dark:hover:bg-gray-700"
|
className="transition-colors flex h-9 w-9 min-w-9 items-center justify-center rounded-lg duration-200 hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||||
>
|
>
|
||||||
<GearIcon className="icon-sm" />
|
<GearIcon className="icon-sm" />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import { Plus, X } from 'lucide-react';
|
||||||
|
import { Transition } from 'react-transition-group';
|
||||||
|
import { Constants } from 'librechat-data-provider';
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '~/components/ui';
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
|
||||||
|
interface AssistantConversationStartersProps {
|
||||||
|
field: {
|
||||||
|
value: string[];
|
||||||
|
onChange: (value: string[]) => void;
|
||||||
|
};
|
||||||
|
inputClass: string;
|
||||||
|
labelClass: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AssistantConversationStarters: React.FC<AssistantConversationStartersProps> = ({
|
||||||
|
field,
|
||||||
|
inputClass,
|
||||||
|
labelClass,
|
||||||
|
}) => {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
|
||||||
|
const nodeRef = useRef(null);
|
||||||
|
const [newStarter, setNewStarter] = useState('');
|
||||||
|
|
||||||
|
const handleAddStarter = () => {
|
||||||
|
if (newStarter.trim() && field.value.length < Constants.MAX_CONVO_STARTERS) {
|
||||||
|
const newValues = [newStarter, ...field.value];
|
||||||
|
field.onChange(newValues);
|
||||||
|
setNewStarter('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteStarter = (index: number) => {
|
||||||
|
const newValues = field.value.filter((_, i) => i !== index);
|
||||||
|
field.onChange(newValues);
|
||||||
|
};
|
||||||
|
const defaultStyle = {
|
||||||
|
transition: 'opacity 200ms ease-in-out',
|
||||||
|
opacity: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const triggerShake = (element: HTMLElement) => {
|
||||||
|
element.classList.remove('shake');
|
||||||
|
void element.offsetWidth;
|
||||||
|
element.classList.add('shake');
|
||||||
|
setTimeout(() => {
|
||||||
|
element.classList.remove('shake');
|
||||||
|
}, 200);
|
||||||
|
};
|
||||||
|
|
||||||
|
const transitionStyles = {
|
||||||
|
entering: { opacity: 1 },
|
||||||
|
entered: { opacity: 1 },
|
||||||
|
exiting: { opacity: 0 },
|
||||||
|
exited: { opacity: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasReachedMax = field.value.length >= Constants.MAX_CONVO_STARTERS;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<label className={labelClass} htmlFor="conversation_starters">
|
||||||
|
{localize('com_assistants_conversation_starters')}
|
||||||
|
</label>
|
||||||
|
<div className="mt-4 space-y-2">
|
||||||
|
{/* Persistent starter, used for creating only */}
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
ref={(el) => (inputRefs.current[0] = el)}
|
||||||
|
value={newStarter}
|
||||||
|
maxLength={64}
|
||||||
|
className={`${inputClass} pr-10`}
|
||||||
|
type="text"
|
||||||
|
placeholder={
|
||||||
|
hasReachedMax
|
||||||
|
? localize('com_assistants_max_starters_reached')
|
||||||
|
: localize('com_assistants_conversation_starters_placeholder')
|
||||||
|
}
|
||||||
|
onChange={(e) => setNewStarter(e.target.value)}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
if (hasReachedMax) {
|
||||||
|
triggerShake(e.currentTarget);
|
||||||
|
} else {
|
||||||
|
handleAddStarter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Transition
|
||||||
|
nodeRef={nodeRef}
|
||||||
|
in={field.value.length < Constants.MAX_CONVO_STARTERS}
|
||||||
|
timeout={200}
|
||||||
|
unmountOnExit
|
||||||
|
>
|
||||||
|
{(state: string) => (
|
||||||
|
<div
|
||||||
|
ref={nodeRef}
|
||||||
|
style={{
|
||||||
|
...defaultStyle,
|
||||||
|
...transitionStyles[state as keyof typeof transitionStyles],
|
||||||
|
transition: state === 'entering' ? 'none' : defaultStyle.transition,
|
||||||
|
}}
|
||||||
|
className="absolute right-1 top-1"
|
||||||
|
>
|
||||||
|
<TooltipProvider delayDuration={1000}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex size-7 items-center justify-center rounded-lg transition-colors duration-200 hover:bg-surface-hover"
|
||||||
|
onClick={handleAddStarter}
|
||||||
|
disabled={hasReachedMax}
|
||||||
|
>
|
||||||
|
<Plus className="size-4" />
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top" sideOffset={0}>
|
||||||
|
{hasReachedMax
|
||||||
|
? localize('com_assistants_max_starters_reached')
|
||||||
|
: localize('com_ui_add')}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
{field.value.map((starter, index) => (
|
||||||
|
<div key={index} className="relative">
|
||||||
|
<input
|
||||||
|
ref={(el) => (inputRefs.current[index + 1] = el)}
|
||||||
|
value={starter}
|
||||||
|
onChange={(e) => {
|
||||||
|
const newValue = [...field.value];
|
||||||
|
newValue[index] = e.target.value;
|
||||||
|
field.onChange(newValue);
|
||||||
|
}}
|
||||||
|
className={`${inputClass} pr-10`}
|
||||||
|
type="text"
|
||||||
|
maxLength={64}
|
||||||
|
/>
|
||||||
|
<TooltipProvider delayDuration={1000}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="absolute right-1 top-1 flex size-7 items-center justify-center rounded-lg transition-colors duration-200 hover:bg-surface-hover"
|
||||||
|
onClick={() => handleDeleteStarter(index)}
|
||||||
|
>
|
||||||
|
<X className="size-4" />
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top" sideOffset={0}>
|
||||||
|
{localize('com_ui_delete')}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AssistantConversationStarters;
|
||||||
|
|
@ -14,6 +14,7 @@ import type { FunctionTool, TConfig, TPlugin } from 'librechat-data-provider';
|
||||||
import type { AssistantForm, AssistantPanelProps } from '~/common';
|
import type { AssistantForm, AssistantPanelProps } from '~/common';
|
||||||
import { useCreateAssistantMutation, useUpdateAssistantMutation } from '~/data-provider';
|
import { useCreateAssistantMutation, useUpdateAssistantMutation } from '~/data-provider';
|
||||||
import { cn, cardStyle, defaultTextProps, removeFocusOutlines } from '~/utils';
|
import { cn, cardStyle, defaultTextProps, removeFocusOutlines } from '~/utils';
|
||||||
|
import AssistantConversationStarters from './AssistantConversationStarters';
|
||||||
import { useAssistantsMapContext, useToastContext } from '~/Providers';
|
import { useAssistantsMapContext, useToastContext } from '~/Providers';
|
||||||
import { useSelectAssistant, useLocalize } from '~/hooks';
|
import { useSelectAssistant, useLocalize } from '~/hooks';
|
||||||
import { ToolSelectDialog } from '~/components/Tools';
|
import { ToolSelectDialog } from '~/components/Tools';
|
||||||
|
|
@ -31,7 +32,7 @@ import { Panel } from '~/common';
|
||||||
const labelClass = 'mb-2 text-token-text-primary block font-medium';
|
const labelClass = 'mb-2 text-token-text-primary block font-medium';
|
||||||
const inputClass = cn(
|
const inputClass = cn(
|
||||||
defaultTextProps,
|
defaultTextProps,
|
||||||
'flex w-full px-3 py-2 dark:border-gray-800 dark:bg-gray-800',
|
'flex w-full px-3 py-2 dark:border-gray-800 dark:bg-gray-800 rounded-xl mb-2',
|
||||||
removeFocusOutlines,
|
removeFocusOutlines,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -106,6 +107,7 @@ export default function AssistantPanel({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const create = useCreateAssistantMutation({
|
const create = useCreateAssistantMutation({
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setCurrentAssistantId(data.id);
|
setCurrentAssistantId(data.id);
|
||||||
|
|
@ -139,7 +141,7 @@ export default function AssistantPanel({
|
||||||
return functionName;
|
return functionName;
|
||||||
} else {
|
} else {
|
||||||
const assistant = assistantMap?.[endpoint]?.[assistant_id];
|
const assistant = assistantMap?.[endpoint]?.[assistant_id];
|
||||||
const tool = assistant?.tools.find((tool) => tool.function?.name === functionName);
|
const tool = assistant?.tools?.find((tool) => tool.function?.name === functionName);
|
||||||
if (assistant && tool) {
|
if (assistant && tool) {
|
||||||
return tool;
|
return tool;
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +150,6 @@ export default function AssistantPanel({
|
||||||
return functionName;
|
return functionName;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
if (data.code_interpreter) {
|
if (data.code_interpreter) {
|
||||||
tools.push({ type: Tools.code_interpreter });
|
tools.push({ type: Tools.code_interpreter });
|
||||||
}
|
}
|
||||||
|
|
@ -163,6 +164,7 @@ export default function AssistantPanel({
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
instructions,
|
instructions,
|
||||||
|
conversation_starters: starters,
|
||||||
model,
|
model,
|
||||||
// file_ids, // TODO: add file handling here
|
// file_ids, // TODO: add file handling here
|
||||||
} = data;
|
} = data;
|
||||||
|
|
@ -174,6 +176,7 @@ export default function AssistantPanel({
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
instructions,
|
instructions,
|
||||||
|
conversation_starters: starters.filter((starter) => starter.trim() !== ''),
|
||||||
model,
|
model,
|
||||||
tools,
|
tools,
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
@ -186,6 +189,7 @@ export default function AssistantPanel({
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
instructions,
|
instructions,
|
||||||
|
conversation_starters: starters.filter((starter) => starter.trim() !== ''),
|
||||||
model,
|
model,
|
||||||
tools,
|
tools,
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
@ -239,12 +243,12 @@ export default function AssistantPanel({
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="h-auto bg-white px-4 pb-8 pt-3 dark:bg-transparent">
|
<div className="bg-surface-50 h-auto px-4 pb-8 pt-3 dark:bg-transparent">
|
||||||
{/* Avatar & Name */}
|
{/* Avatar & Name */}
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<AssistantAvatar
|
<AssistantAvatar
|
||||||
createMutation={create}
|
createMutation={create}
|
||||||
assistant_id={assistant_id ?? null}
|
assistant_id={assistant_id}
|
||||||
metadata={assistant['metadata'] ?? null}
|
metadata={assistant['metadata'] ?? null}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
version={version}
|
version={version}
|
||||||
|
|
@ -271,7 +275,7 @@ export default function AssistantPanel({
|
||||||
name="id"
|
name="id"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<p className="h-3 text-xs italic text-text-secondary">{field.value ?? ''}</p>
|
<p className="h-3 text-xs italic text-text-secondary">{field.value}</p>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -318,6 +322,23 @@ export default function AssistantPanel({
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Conversation Starters */}
|
||||||
|
<div className="relative mb-6">
|
||||||
|
{/* the label of conversation starters is in the component */}
|
||||||
|
<Controller
|
||||||
|
name="conversation_starters"
|
||||||
|
control={control}
|
||||||
|
defaultValue={[]}
|
||||||
|
render={({ field }) => (
|
||||||
|
<AssistantConversationStarters
|
||||||
|
field={field}
|
||||||
|
inputClass={inputClass}
|
||||||
|
labelClass={labelClass}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{/* Model */}
|
{/* Model */}
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<label className={labelClass} htmlFor="model">
|
<label className={labelClass} htmlFor="model">
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@ import {
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
import type { UseFormReset } from 'react-hook-form';
|
import type { UseFormReset } from 'react-hook-form';
|
||||||
import type { UseMutationResult } from '@tanstack/react-query';
|
import type { UseMutationResult } from '@tanstack/react-query';
|
||||||
import type { Assistant, AssistantCreateParams, AssistantsEndpoint } from 'librechat-data-provider';
|
import type {
|
||||||
|
Assistant,
|
||||||
|
AssistantCreateParams,
|
||||||
|
AssistantDocument,
|
||||||
|
AssistantsEndpoint,
|
||||||
|
} from 'librechat-data-provider';
|
||||||
import type {
|
import type {
|
||||||
Actions,
|
Actions,
|
||||||
ExtendedFile,
|
ExtendedFile,
|
||||||
|
|
@ -19,13 +24,20 @@ import type {
|
||||||
TAssistantOption,
|
TAssistantOption,
|
||||||
LastSelectedModels,
|
LastSelectedModels,
|
||||||
} from '~/common';
|
} from '~/common';
|
||||||
|
import { useListAssistantsQuery, useGetAssistantDocsQuery } from '~/data-provider';
|
||||||
import SelectDropDown from '~/components/ui/SelectDropDown';
|
import SelectDropDown from '~/components/ui/SelectDropDown';
|
||||||
import { useListAssistantsQuery } from '~/data-provider';
|
|
||||||
import { useLocalize, useLocalStorage } from '~/hooks';
|
import { useLocalize, useLocalStorage } from '~/hooks';
|
||||||
import { useFileMapContext } from '~/Providers';
|
import { useFileMapContext } from '~/Providers';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
const keys = new Set(['name', 'id', 'description', 'instructions', 'model']);
|
const keys = new Set([
|
||||||
|
'name',
|
||||||
|
'id',
|
||||||
|
'description',
|
||||||
|
'instructions',
|
||||||
|
'conversation_starters',
|
||||||
|
'model',
|
||||||
|
]);
|
||||||
|
|
||||||
export default function AssistantSelect({
|
export default function AssistantSelect({
|
||||||
reset,
|
reset,
|
||||||
|
|
@ -45,11 +57,18 @@ export default function AssistantSelect({
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
const fileMap = useFileMapContext();
|
const fileMap = useFileMapContext();
|
||||||
const lastSelectedAssistant = useRef<string | null>(null);
|
const lastSelectedAssistant = useRef<string | null>(null);
|
||||||
const [lastSelectedModels] = useLocalStorage<LastSelectedModels>(
|
const [lastSelectedModels] = useLocalStorage<LastSelectedModels | undefined>(
|
||||||
LocalStorageKeys.LAST_MODEL,
|
LocalStorageKeys.LAST_MODEL,
|
||||||
{} as LastSelectedModels,
|
{} as LastSelectedModels,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { data: documentsMap = new Map<string, AssistantDocument>() } = useGetAssistantDocsQuery(
|
||||||
|
endpoint,
|
||||||
|
{
|
||||||
|
select: (data) => new Map(data.map((dbA) => [dbA.assistant_id, dbA])),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const assistants = useListAssistantsQuery(endpoint, undefined, {
|
const assistants = useListAssistantsQuery(endpoint, undefined, {
|
||||||
select: (res) =>
|
select: (res) =>
|
||||||
res.data.map((_assistant) => {
|
res.data.map((_assistant) => {
|
||||||
|
|
@ -57,10 +76,10 @@ export default function AssistantSelect({
|
||||||
endpoint === EModelEndpoint.assistants ? FileSources.openai : FileSources.azure;
|
endpoint === EModelEndpoint.assistants ? FileSources.openai : FileSources.azure;
|
||||||
const assistant = {
|
const assistant = {
|
||||||
..._assistant,
|
..._assistant,
|
||||||
label: _assistant?.name ?? '',
|
label: _assistant.name ?? '',
|
||||||
value: _assistant.id,
|
value: _assistant.id,
|
||||||
files: _assistant?.file_ids ? ([] as Array<[string, ExtendedFile]>) : undefined,
|
files: _assistant.file_ids ? ([] as Array<[string, ExtendedFile]>) : undefined,
|
||||||
code_files: _assistant?.tool_resources?.code_interpreter?.file_ids
|
code_files: _assistant.tool_resources?.code_interpreter?.file_ids
|
||||||
? ([] as Array<[string, ExtendedFile]>)
|
? ([] as Array<[string, ExtendedFile]>)
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
|
|
@ -104,11 +123,17 @@ export default function AssistantSelect({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assistant.code_files && _assistant.tool_resources?.code_interpreter?.file_ids) {
|
if (assistant.code_files && _assistant.tool_resources?.code_interpreter?.file_ids) {
|
||||||
_assistant.tool_resources?.code_interpreter?.file_ids?.forEach((file_id) =>
|
_assistant.tool_resources.code_interpreter.file_ids.forEach((file_id) =>
|
||||||
handleFile(file_id, assistant.code_files),
|
handleFile(file_id, assistant.code_files),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const assistantDoc = documentsMap.get(_assistant.id);
|
||||||
|
/* If no user updates, use the latest assistant docs */
|
||||||
|
if (assistantDoc && !assistant.conversation_starters) {
|
||||||
|
assistant.conversation_starters = assistantDoc.conversation_starters;
|
||||||
|
}
|
||||||
|
|
||||||
return assistant;
|
return assistant;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
@ -128,8 +153,8 @@ export default function AssistantSelect({
|
||||||
|
|
||||||
const update = {
|
const update = {
|
||||||
...assistant,
|
...assistant,
|
||||||
label: assistant?.name ?? '',
|
label: assistant.name ?? '',
|
||||||
value: assistant?.id ?? '',
|
value: assistant.id ?? '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const actions: Actions = {
|
const actions: Actions = {
|
||||||
|
|
@ -138,9 +163,9 @@ export default function AssistantSelect({
|
||||||
[Capabilities.retrieval]: false,
|
[Capabilities.retrieval]: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
assistant?.tools
|
(assistant.tools ?? [])
|
||||||
?.filter((tool) => tool.type !== 'function' || isImageVisionTool(tool))
|
.filter((tool) => tool.type !== 'function' || isImageVisionTool(tool))
|
||||||
?.map((tool) => tool?.function?.name || tool.type)
|
.map((tool) => tool.function?.name || tool.type)
|
||||||
.forEach((tool) => {
|
.forEach((tool) => {
|
||||||
if (tool === Tools.file_search) {
|
if (tool === Tools.file_search) {
|
||||||
actions[Capabilities.retrieval] = true;
|
actions[Capabilities.retrieval] = true;
|
||||||
|
|
@ -148,10 +173,9 @@ export default function AssistantSelect({
|
||||||
actions[tool] = true;
|
actions[tool] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const functions =
|
const functions = (assistant.tools ?? [])
|
||||||
assistant?.tools
|
.filter((tool) => tool.type === 'function' && !isImageVisionTool(tool))
|
||||||
?.filter((tool) => tool.type === 'function' && !isImageVisionTool(tool))
|
.map((tool) => tool.function?.name ?? '');
|
||||||
?.map((tool) => tool.function?.name ?? '') ?? [];
|
|
||||||
|
|
||||||
const formValues: Partial<AssistantForm & Actions> = {
|
const formValues: Partial<AssistantForm & Actions> = {
|
||||||
functions,
|
functions,
|
||||||
|
|
@ -161,18 +185,26 @@ export default function AssistantSelect({
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.entries(assistant).forEach(([name, value]) => {
|
Object.entries(assistant).forEach(([name, value]) => {
|
||||||
if (typeof value === 'number') {
|
if (!keys.has(name)) {
|
||||||
return;
|
|
||||||
} else if (typeof value === 'object') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (keys.has(name)) {
|
|
||||||
|
if (
|
||||||
|
name === 'conversation_starters' &&
|
||||||
|
Array.isArray(value) &&
|
||||||
|
value.every((item) => typeof item === 'string')
|
||||||
|
) {
|
||||||
|
formValues[name] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value !== 'number' && typeof value !== 'object') {
|
||||||
formValues[name] = value;
|
formValues[name] = value;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reset(formValues);
|
reset(formValues);
|
||||||
setCurrentAssistantId(assistant?.id);
|
setCurrentAssistantId(assistant.id);
|
||||||
},
|
},
|
||||||
[assistants.data, reset, setCurrentAssistantId, createMutation, endpoint, lastSelectedModels],
|
[assistants.data, reset, setCurrentAssistantId, createMutation, endpoint, lastSelectedModels],
|
||||||
);
|
);
|
||||||
|
|
@ -184,7 +216,7 @@ export default function AssistantSelect({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedAssistant && assistants.data) {
|
if (selectedAssistant !== '' && selectedAssistant != null && assistants.data) {
|
||||||
timerId = setTimeout(() => {
|
timerId = setTimeout(() => {
|
||||||
lastSelectedAssistant.current = selectedAssistant;
|
lastSelectedAssistant.current = selectedAssistant;
|
||||||
onSelect(selectedAssistant);
|
onSelect(selectedAssistant);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ export default function AssistantTool({
|
||||||
<OGDialogTrigger asChild>
|
<OGDialogTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="transition-color flex h-9 w-9 min-w-9 items-center justify-center rounded-lg duration-200 hover:bg-gray-200 dark:hover:bg-gray-700"
|
className="transition-colors flex h-9 w-9 min-w-9 items-center justify-center rounded-lg duration-200 hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||||
>
|
>
|
||||||
<TrashIcon />
|
<TrashIcon />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -97,7 +97,7 @@ export default function AssistantTool({
|
||||||
selection={{
|
selection={{
|
||||||
selectHandler: () => removeTool(currentTool.pluginKey),
|
selectHandler: () => removeTool(currentTool.pluginKey),
|
||||||
selectClasses:
|
selectClasses:
|
||||||
'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-color duration-200 text-white',
|
'bg-red-700 dark:bg-red-600 hover:bg-red-800 dark:hover:bg-red-800 transition-colors duration-200 text-white',
|
||||||
selectText: localize('com_ui_delete'),
|
selectText: localize('com_ui_delete'),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,11 @@ function ToolItem({ tool, onAddTool, onRemoveTool, isInstalled }: ToolItemProps)
|
||||||
{!isInstalled ? (
|
{!isInstalled ? (
|
||||||
<button
|
<button
|
||||||
className="btn btn-primary relative"
|
className="btn btn-primary relative"
|
||||||
aria-label={`${localize('com_nav_tool_add')} ${tool.name}`}
|
aria-label={`${localize('com_ui_add')} ${tool.name}`}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-center gap-2">
|
<div className="flex w-full items-center justify-center gap-2">
|
||||||
{localize('com_nav_tool_add')}
|
{localize('com_ui_add')}
|
||||||
<PlusCircleIcon className="flex h-4 w-4 items-center stroke-2" />
|
<PlusCircleIcon className="flex h-4 w-4 items-center stroke-2" />
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -622,7 +622,7 @@ export const useUploadFileMutation = (
|
||||||
|
|
||||||
const update = {};
|
const update = {};
|
||||||
if (!tool_resource) {
|
if (!tool_resource) {
|
||||||
update['file_ids'] = [...assistant.file_ids, data.file_id];
|
update['file_ids'] = [...(assistant.file_ids ?? []), data.file_id];
|
||||||
}
|
}
|
||||||
if (tool_resource === EToolResources.code_interpreter) {
|
if (tool_resource === EToolResources.code_interpreter) {
|
||||||
const prevResources = assistant.tool_resources ?? {};
|
const prevResources = assistant.tool_resources ?? {};
|
||||||
|
|
@ -884,6 +884,24 @@ export const useUpdateAssistantMutation = (
|
||||||
return options?.onSuccess?.(updatedAssistant, variables, context);
|
return options?.onSuccess?.(updatedAssistant, variables, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queryClient.setQueryData<t.AssistantDocument[]>(
|
||||||
|
[QueryKeys.assistantDocs, variables.data.endpoint],
|
||||||
|
(prev) => {
|
||||||
|
if (!prev) {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
prev.map((doc) => {
|
||||||
|
if (doc.assistant_id === variables.assistant_id) {
|
||||||
|
return {
|
||||||
|
...doc,
|
||||||
|
conversation_starters: updatedAssistant.conversation_starters,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
queryClient.setQueryData<t.AssistantListResponse>(
|
queryClient.setQueryData<t.AssistantListResponse>(
|
||||||
[QueryKeys.assistants, variables.data.endpoint, defaultOrderQuery],
|
[QueryKeys.assistants, variables.data.endpoint, defaultOrderQuery],
|
||||||
{
|
{
|
||||||
|
|
@ -1070,7 +1088,7 @@ export const useDeleteAction = (
|
||||||
if (assistant.id === variables.assistant_id) {
|
if (assistant.id === variables.assistant_id) {
|
||||||
return {
|
return {
|
||||||
...assistant,
|
...assistant,
|
||||||
tools: assistant.tools.filter(
|
tools: (assistant.tools ?? []).filter(
|
||||||
(tool) => !tool.function?.name.includes(domain ?? ''),
|
(tool) => !tool.function?.name.includes(domain ?? ''),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -249,8 +249,8 @@ export const useListAssistantsQuery = <TData = AssistantListResponse>(
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]);
|
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]);
|
||||||
const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]);
|
const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]);
|
||||||
const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide;
|
const userProvidesKey = !!(endpointsConfig?.[endpoint]?.userProvide ?? false);
|
||||||
const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true;
|
const keyProvided = userProvidesKey ? !!(keyExpiry?.expiresAt ?? '') : true;
|
||||||
const enabled = !!endpointsConfig?.[endpoint] && keyProvided;
|
const enabled = !!endpointsConfig?.[endpoint] && keyProvided;
|
||||||
const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint];
|
const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint];
|
||||||
return useQuery<AssistantListResponse, unknown, TData>(
|
return useQuery<AssistantListResponse, unknown, TData>(
|
||||||
|
|
@ -368,22 +368,24 @@ export const useGetActionsQuery = <TData = Action[]>(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook for retrieving user's saved Assistant Documents (metadata saved to Database)
|
* Hook for retrieving user's saved Assistant Documents (metadata saved to Database)
|
||||||
*/
|
*/
|
||||||
export const useGetAssistantDocsQuery = (
|
export const useGetAssistantDocsQuery = <TData = AssistantDocument[]>(
|
||||||
endpoint: t.AssistantsEndpoint,
|
endpoint: t.AssistantsEndpoint | string,
|
||||||
config?: UseQueryOptions<AssistantDocument[]>,
|
config?: UseQueryOptions<AssistantDocument[], unknown, TData>,
|
||||||
): QueryObserverResult<AssistantDocument[], unknown> => {
|
): QueryObserverResult<TData> => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]);
|
const endpointsConfig = queryClient.getQueryData<TEndpointsConfig>([QueryKeys.endpoints]);
|
||||||
const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]);
|
const keyExpiry = queryClient.getQueryData<TCheckUserKeyResponse>([QueryKeys.name, endpoint]);
|
||||||
const userProvidesKey = !!endpointsConfig?.[endpoint]?.userProvide;
|
const userProvidesKey = !!(endpointsConfig?.[endpoint]?.userProvide ?? false);
|
||||||
const keyProvided = userProvidesKey ? !!keyExpiry?.expiresAt : true;
|
const keyProvided = userProvidesKey ? !!(keyExpiry?.expiresAt ?? '') : true;
|
||||||
const enabled = !!endpointsConfig?.[endpoint] && keyProvided;
|
const enabled = !!endpointsConfig?.[endpoint] && keyProvided;
|
||||||
const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint];
|
const version = endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint];
|
||||||
return useQuery<AssistantDocument[]>(
|
|
||||||
[QueryKeys.assistantDocs],
|
return useQuery<AssistantDocument[], unknown, TData>(
|
||||||
|
[QueryKeys.assistantDocs, endpoint],
|
||||||
() =>
|
() =>
|
||||||
dataService.getAssistantDocs({
|
dataService.getAssistantDocs({
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
|
||||||
|
|
@ -549,7 +549,7 @@ export default {
|
||||||
com_nav_change_picture: 'تغيير الصورة',
|
com_nav_change_picture: 'تغيير الصورة',
|
||||||
com_nav_plugin_install: 'تثبيت',
|
com_nav_plugin_install: 'تثبيت',
|
||||||
com_nav_plugin_uninstall: 'إلغاء تثبيت',
|
com_nav_plugin_uninstall: 'إلغاء تثبيت',
|
||||||
com_nav_tool_add: 'إضافة',
|
com_ui_add: 'إضافة',
|
||||||
com_nav_tool_remove: 'إزالة',
|
com_nav_tool_remove: 'إزالة',
|
||||||
com_nav_tool_dialog: 'أدوات المساعد',
|
com_nav_tool_dialog: 'أدوات المساعد',
|
||||||
com_nav_tool_dialog_description: 'يجب حفظ المساعد لإبقاء اختيارات الأدوات.',
|
com_nav_tool_dialog_description: 'يجب حفظ المساعد لإبقاء اختيارات الأدوات.',
|
||||||
|
|
@ -2594,7 +2594,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'إلغاء تثبيت',
|
translated: 'إلغاء تثبيت',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'إضافة',
|
translated: 'إضافة',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Loja de plugins',
|
com_nav_plugin_store: 'Loja de plugins',
|
||||||
com_nav_plugin_install: 'Instalar',
|
com_nav_plugin_install: 'Instalar',
|
||||||
com_nav_plugin_uninstall: 'Desinstalar',
|
com_nav_plugin_uninstall: 'Desinstalar',
|
||||||
com_nav_tool_add: 'Adicionar',
|
com_ui_add: 'Adicionar',
|
||||||
com_nav_tool_remove: 'Remover',
|
com_nav_tool_remove: 'Remover',
|
||||||
com_nav_tool_dialog: 'Ferramentas do Assistente',
|
com_nav_tool_dialog: 'Ferramentas do Assistente',
|
||||||
com_nav_tool_dialog_description:
|
com_nav_tool_dialog_description:
|
||||||
|
|
@ -2021,7 +2021,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'Desinstalar',
|
translated: 'Desinstalar',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'Adicionar',
|
translated: 'Adicionar',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ export default {
|
||||||
com_ui_fork_from_message: 'Wähle eine Abzweigungsoption',
|
com_ui_fork_from_message: 'Wähle eine Abzweigungsoption',
|
||||||
com_ui_mention:
|
com_ui_mention:
|
||||||
'Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln',
|
'Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln',
|
||||||
com_ui_add: 'Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen',
|
com_ui_add_model_preset: 'Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen',
|
||||||
com_ui_regenerate: 'Neu generieren',
|
com_ui_regenerate: 'Neu generieren',
|
||||||
com_ui_continue: 'Fortfahren',
|
com_ui_continue: 'Fortfahren',
|
||||||
com_ui_edit: 'Bearbeiten',
|
com_ui_edit: 'Bearbeiten',
|
||||||
|
|
@ -592,7 +592,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Plugin-Store',
|
com_nav_plugin_store: 'Plugin-Store',
|
||||||
com_nav_plugin_install: 'Installieren',
|
com_nav_plugin_install: 'Installieren',
|
||||||
com_nav_plugin_uninstall: 'Deinstallieren',
|
com_nav_plugin_uninstall: 'Deinstallieren',
|
||||||
com_nav_tool_add: 'Hinzufügen',
|
com_ui_add: 'Hinzufügen',
|
||||||
com_nav_tool_remove: 'Entfernen',
|
com_nav_tool_remove: 'Entfernen',
|
||||||
com_nav_tool_dialog: 'Assistenten-Werkzeuge',
|
com_nav_tool_dialog: 'Assistenten-Werkzeuge',
|
||||||
com_ui_misc: 'Sonstiges',
|
com_ui_misc: 'Sonstiges',
|
||||||
|
|
@ -2283,7 +2283,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'Deinstallieren',
|
translated: 'Deinstallieren',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'Hinzufügen',
|
translated: 'Hinzufügen',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ export default {
|
||||||
com_assistants_update_error: 'There was an error updating your assistant.',
|
com_assistants_update_error: 'There was an error updating your assistant.',
|
||||||
com_assistants_create_success: 'Successfully created',
|
com_assistants_create_success: 'Successfully created',
|
||||||
com_assistants_create_error: 'There was an error creating your assistant.',
|
com_assistants_create_error: 'There was an error creating your assistant.',
|
||||||
|
com_assistants_conversation_starters: 'Conversation Starters',
|
||||||
|
com_assistants_conversation_starters_placeholder: 'Enter a conversation starter',
|
||||||
com_ui_date_today: 'Today',
|
com_ui_date_today: 'Today',
|
||||||
com_ui_date_yesterday: 'Yesterday',
|
com_ui_date_yesterday: 'Yesterday',
|
||||||
com_ui_date_previous_7_days: 'Previous 7 days',
|
com_ui_date_previous_7_days: 'Previous 7 days',
|
||||||
|
|
@ -221,7 +223,8 @@ export default {
|
||||||
com_ui_fork_visible: 'Visible messages only',
|
com_ui_fork_visible: 'Visible messages only',
|
||||||
com_ui_fork_from_message: 'Select a fork option',
|
com_ui_fork_from_message: 'Select a fork option',
|
||||||
com_ui_mention: 'Mention an endpoint, assistant, or preset to quickly switch to it',
|
com_ui_mention: 'Mention an endpoint, assistant, or preset to quickly switch to it',
|
||||||
com_ui_add: 'Add a model or preset for an additional response',
|
com_ui_add_model_preset: 'Add a model or preset for an additional response',
|
||||||
|
com_assistants_max_starters_reached: 'Max number of conversation starters reached',
|
||||||
com_ui_regenerate: 'Regenerate',
|
com_ui_regenerate: 'Regenerate',
|
||||||
com_ui_continue: 'Continue',
|
com_ui_continue: 'Continue',
|
||||||
com_ui_edit: 'Edit',
|
com_ui_edit: 'Edit',
|
||||||
|
|
@ -603,7 +606,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Plugin store',
|
com_nav_plugin_store: 'Plugin store',
|
||||||
com_nav_plugin_install: 'Install',
|
com_nav_plugin_install: 'Install',
|
||||||
com_nav_plugin_uninstall: 'Uninstall',
|
com_nav_plugin_uninstall: 'Uninstall',
|
||||||
com_nav_tool_add: 'Add',
|
com_ui_add: 'Add',
|
||||||
com_nav_tool_remove: 'Remove',
|
com_nav_tool_remove: 'Remove',
|
||||||
com_nav_tool_dialog: 'Assistant Tools',
|
com_nav_tool_dialog: 'Assistant Tools',
|
||||||
com_ui_misc: 'Misc.',
|
com_ui_misc: 'Misc.',
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Tienda de plugins',
|
com_nav_plugin_store: 'Tienda de plugins',
|
||||||
com_nav_plugin_install: 'Instalar',
|
com_nav_plugin_install: 'Instalar',
|
||||||
com_nav_plugin_uninstall: 'Desinstalar',
|
com_nav_plugin_uninstall: 'Desinstalar',
|
||||||
com_nav_tool_add: 'Agregar',
|
com_ui_add: 'Agregar',
|
||||||
com_nav_tool_remove: 'Eliminar',
|
com_nav_tool_remove: 'Eliminar',
|
||||||
com_nav_tool_dialog: 'Herramientas del asistente',
|
com_nav_tool_dialog: 'Herramientas del asistente',
|
||||||
com_nav_tool_dialog_description:
|
com_nav_tool_dialog_description:
|
||||||
|
|
@ -2153,7 +2153,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'Desinstalar',
|
translated: 'Desinstalar',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'Agregar',
|
translated: 'Agregar',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ export default {
|
||||||
com_ui_fork_visible: 'Vain näkyvät viestit',
|
com_ui_fork_visible: 'Vain näkyvät viestit',
|
||||||
com_ui_fork_from_message: 'Valitse haarautustapa',
|
com_ui_fork_from_message: 'Valitse haarautustapa',
|
||||||
com_ui_mention: 'Mainitse päätepiste, Avustaja tai asetus vaihtaaksesi siihen pikana',
|
com_ui_mention: 'Mainitse päätepiste, Avustaja tai asetus vaihtaaksesi siihen pikana',
|
||||||
com_ui_add: 'Lisää malli tai esiasetus lisävastausta varten',
|
com_ui_add_model_preset: 'Lisää malli tai esiasetus lisävastausta varten',
|
||||||
com_ui_regenerate: 'Luo uudestaan',
|
com_ui_regenerate: 'Luo uudestaan',
|
||||||
com_ui_continue: 'Jatka',
|
com_ui_continue: 'Jatka',
|
||||||
com_ui_edit: 'Muokkaa',
|
com_ui_edit: 'Muokkaa',
|
||||||
|
|
@ -571,7 +571,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Lisäosakauppa',
|
com_nav_plugin_store: 'Lisäosakauppa',
|
||||||
com_nav_plugin_install: 'Asenna',
|
com_nav_plugin_install: 'Asenna',
|
||||||
com_nav_plugin_uninstall: 'Poista',
|
com_nav_plugin_uninstall: 'Poista',
|
||||||
com_nav_tool_add: 'Lisää',
|
com_ui_add: 'Lisää',
|
||||||
com_nav_tool_remove: 'Poista',
|
com_nav_tool_remove: 'Poista',
|
||||||
com_nav_tool_dialog: 'Avustajatyökalut',
|
com_nav_tool_dialog: 'Avustajatyökalut',
|
||||||
com_ui_misc: 'Muu',
|
com_ui_misc: 'Muu',
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ export default {
|
||||||
com_ui_date_december: 'Décembre',
|
com_ui_date_december: 'Décembre',
|
||||||
com_ui_nothing_found: 'Aucun résultat trouvé',
|
com_ui_nothing_found: 'Aucun résultat trouvé',
|
||||||
com_ui_go_to_conversation: 'Aller à la conversation',
|
com_ui_go_to_conversation: 'Aller à la conversation',
|
||||||
com_nav_tool_add: 'Ajouter',
|
com_ui_add: 'Ajouter',
|
||||||
com_nav_tool_remove: 'Supprimer',
|
com_nav_tool_remove: 'Supprimer',
|
||||||
com_nav_tool_dialog: 'Outils de l\'assistant',
|
com_nav_tool_dialog: 'Outils de l\'assistant',
|
||||||
com_nav_tool_dialog_description:
|
com_nav_tool_dialog_description:
|
||||||
|
|
@ -624,7 +624,7 @@ export default {
|
||||||
com_ui_upload_invalid_var:
|
com_ui_upload_invalid_var:
|
||||||
'Fichier non valide pour le téléchargement. L\'image ne doit pas dépasser {0} Mo',
|
'Fichier non valide pour le téléchargement. L\'image ne doit pas dépasser {0} Mo',
|
||||||
com_ui_read_aloud: 'Lire à haute voix',
|
com_ui_read_aloud: 'Lire à haute voix',
|
||||||
com_ui_add: 'Ajouter un modèle ou un préréglage pour une réponse supplémentaire',
|
com_ui_add_model_preset: 'Ajouter un modèle ou un préréglage pour une réponse supplémentaire',
|
||||||
com_ui_loading: 'Chargement...',
|
com_ui_loading: 'Chargement...',
|
||||||
com_ui_all_proper: 'Tout',
|
com_ui_all_proper: 'Tout',
|
||||||
com_ui_chat: 'Discussion',
|
com_ui_chat: 'Discussion',
|
||||||
|
|
@ -2208,7 +2208,7 @@ export const comparisons = {
|
||||||
english: 'Go to conversation',
|
english: 'Go to conversation',
|
||||||
translated: 'Aller à la conversation',
|
translated: 'Aller à la conversation',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'Ajouter',
|
translated: 'Ajouter',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -354,7 +354,7 @@ export default {
|
||||||
com_nav_plugin_store: 'חנות פלאגין',
|
com_nav_plugin_store: 'חנות פלאגין',
|
||||||
com_nav_plugin_install: 'התקן',
|
com_nav_plugin_install: 'התקן',
|
||||||
com_nav_plugin_uninstall: 'הסר התקנה',
|
com_nav_plugin_uninstall: 'הסר התקנה',
|
||||||
com_nav_tool_add: 'הוסף',
|
com_ui_add: 'הוסף',
|
||||||
com_nav_tool_remove: 'הסר',
|
com_nav_tool_remove: 'הסר',
|
||||||
com_nav_tool_dialog: 'כלי סייען',
|
com_nav_tool_dialog: 'כלי סייען',
|
||||||
com_nav_tool_dialog_description: 'יש לשמור את האסיסטנט כדי להמשיך בבחירת הכלים.',
|
com_nav_tool_dialog_description: 'יש לשמור את האסיסטנט כדי להמשיך בבחירת הכלים.',
|
||||||
|
|
@ -1728,7 +1728,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'הסר התקנה',
|
translated: 'הסר התקנה',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'הוסף',
|
translated: 'הוסף',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -483,7 +483,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Store plugin',
|
com_nav_plugin_store: 'Store plugin',
|
||||||
com_nav_plugin_install: 'Installa',
|
com_nav_plugin_install: 'Installa',
|
||||||
com_nav_plugin_uninstall: 'Disinstalla',
|
com_nav_plugin_uninstall: 'Disinstalla',
|
||||||
com_nav_tool_add: 'Aggiungi',
|
com_ui_add: 'Aggiungi',
|
||||||
com_nav_tool_remove: 'Rimuovi',
|
com_nav_tool_remove: 'Rimuovi',
|
||||||
com_nav_tool_dialog: 'Strumenti Assistente',
|
com_nav_tool_dialog: 'Strumenti Assistente',
|
||||||
com_nav_tool_dialog_description:
|
com_nav_tool_dialog_description:
|
||||||
|
|
@ -2326,7 +2326,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'Disinstalla',
|
translated: 'Disinstalla',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'Aggiungi',
|
translated: 'Aggiungi',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ export default {
|
||||||
com_nav_plugin_store: 'プラグインストア',
|
com_nav_plugin_store: 'プラグインストア',
|
||||||
com_nav_plugin_install: 'インストール',
|
com_nav_plugin_install: 'インストール',
|
||||||
com_nav_plugin_uninstall: 'アンインストール',
|
com_nav_plugin_uninstall: 'アンインストール',
|
||||||
com_nav_tool_add: '追加',
|
com_ui_add: '追加',
|
||||||
com_nav_tool_dialog: 'アシスタントツール',
|
com_nav_tool_dialog: 'アシスタントツール',
|
||||||
com_nav_tool_dialog_description:
|
com_nav_tool_dialog_description:
|
||||||
'ツールの選択を維持するには、アシスタントを保存する必要があります。',
|
'ツールの選択を維持するには、アシスタントを保存する必要があります。',
|
||||||
|
|
@ -2165,7 +2165,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'アンインストール',
|
translated: 'アンインストール',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: '追加',
|
translated: '追加',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -544,7 +544,7 @@ export default {
|
||||||
com_nav_change_picture: '프로필 사진 변경',
|
com_nav_change_picture: '프로필 사진 변경',
|
||||||
com_nav_plugin_install: '플러그인 설치',
|
com_nav_plugin_install: '플러그인 설치',
|
||||||
com_nav_plugin_uninstall: '플러그인 제거',
|
com_nav_plugin_uninstall: '플러그인 제거',
|
||||||
com_nav_tool_add: '추가',
|
com_ui_add: '추가',
|
||||||
com_nav_tool_remove: '제거',
|
com_nav_tool_remove: '제거',
|
||||||
com_nav_tool_dialog: '어시스턴트 도구',
|
com_nav_tool_dialog: '어시스턴트 도구',
|
||||||
com_nav_tool_dialog_description: 'Assistant를 저장해야 도구 선택이 유지됩니다.',
|
com_nav_tool_dialog_description: 'Assistant를 저장해야 도구 선택이 유지됩니다.',
|
||||||
|
|
@ -2595,7 +2595,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: '플러그인 제거',
|
translated: '플러그인 제거',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: '추가',
|
translated: '추가',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -567,7 +567,7 @@ export default {
|
||||||
com_nav_welcome_assistant: 'Выберите ассистента',
|
com_nav_welcome_assistant: 'Выберите ассистента',
|
||||||
com_nav_plugin_install: 'Установить',
|
com_nav_plugin_install: 'Установить',
|
||||||
com_nav_plugin_uninstall: 'Удалить',
|
com_nav_plugin_uninstall: 'Удалить',
|
||||||
com_nav_tool_add: 'Добавить',
|
com_ui_add: 'Добавить',
|
||||||
com_nav_tool_remove: 'Удалить',
|
com_nav_tool_remove: 'Удалить',
|
||||||
com_nav_tool_dialog: 'Инструменты ассистента',
|
com_nav_tool_dialog: 'Инструменты ассистента',
|
||||||
com_nav_tool_dialog_description:
|
com_nav_tool_dialog_description:
|
||||||
|
|
@ -2656,7 +2656,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: 'Удалить',
|
translated: 'Удалить',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: 'Добавить',
|
translated: 'Добавить',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -530,7 +530,7 @@ export default {
|
||||||
com_nav_plugin_store: 'Eklenti mağazası',
|
com_nav_plugin_store: 'Eklenti mağazası',
|
||||||
com_nav_plugin_install: 'Yükle',
|
com_nav_plugin_install: 'Yükle',
|
||||||
com_nav_plugin_uninstall: 'Kaldır',
|
com_nav_plugin_uninstall: 'Kaldır',
|
||||||
com_nav_tool_add: 'Ekle',
|
com_ui_add: 'Ekle',
|
||||||
com_nav_tool_remove: 'Kaldır',
|
com_nav_tool_remove: 'Kaldır',
|
||||||
com_nav_tool_dialog: 'Asistan Araçları',
|
com_nav_tool_dialog: 'Asistan Araçları',
|
||||||
com_nav_tool_dialog_description: 'Araç seçimlerinin kalıcı olması için asistan kaydedilmelidir.',
|
com_nav_tool_dialog_description: 'Araç seçimlerinin kalıcı olması için asistan kaydedilmelidir.',
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ export default {
|
||||||
com_nav_plugin_store: '插件商店',
|
com_nav_plugin_store: '插件商店',
|
||||||
com_nav_plugin_install: '安装',
|
com_nav_plugin_install: '安装',
|
||||||
com_nav_plugin_uninstall: '卸载',
|
com_nav_plugin_uninstall: '卸载',
|
||||||
com_nav_tool_add: '添加',
|
com_ui_add: '添加',
|
||||||
com_nav_tool_remove: '移除',
|
com_nav_tool_remove: '移除',
|
||||||
com_nav_tool_dialog: '助手工具',
|
com_nav_tool_dialog: '助手工具',
|
||||||
com_nav_tool_dialog_description: '必须保存助手才能保留工具选择。',
|
com_nav_tool_dialog_description: '必须保存助手才能保留工具选择。',
|
||||||
|
|
@ -2071,7 +2071,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: '卸载',
|
translated: '卸载',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: '添加',
|
translated: '添加',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -522,7 +522,7 @@ export default {
|
||||||
com_nav_change_picture: '更換圖片',
|
com_nav_change_picture: '更換圖片',
|
||||||
com_nav_plugin_install: '安裝',
|
com_nav_plugin_install: '安裝',
|
||||||
com_nav_plugin_uninstall: '解除安裝',
|
com_nav_plugin_uninstall: '解除安裝',
|
||||||
com_nav_tool_add: '新增',
|
com_ui_add: '新增',
|
||||||
com_nav_tool_remove: '移除',
|
com_nav_tool_remove: '移除',
|
||||||
com_nav_tool_dialog: 'AI 工具',
|
com_nav_tool_dialog: 'AI 工具',
|
||||||
com_nav_tool_dialog_description: '必須儲存 Assistant 才能保留工具選擇。',
|
com_nav_tool_dialog_description: '必須儲存 Assistant 才能保留工具選擇。',
|
||||||
|
|
@ -2563,7 +2563,7 @@ export const comparisons = {
|
||||||
english: 'Uninstall',
|
english: 'Uninstall',
|
||||||
translated: '解除安裝',
|
translated: '解除安裝',
|
||||||
},
|
},
|
||||||
com_nav_tool_add: {
|
com_ui_add: {
|
||||||
english: 'Add',
|
english: 'Add',
|
||||||
translated: '新增',
|
translated: '新增',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1355,7 +1355,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: Desinstalar
|
- **translated**: Desinstalar
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: Adicionar
|
- **translated**: Adicionar
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1379,7 +1379,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: Deinstallieren
|
- **translated**: Deinstallieren
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: Hinzufügen
|
- **translated**: Hinzufügen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1355,7 +1355,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: Desinstalar
|
- **translated**: Desinstalar
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: Agregar
|
- **translated**: Agregar
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1155,7 +1155,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: הסר התקנה
|
- **translated**: הסר התקנה
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: הוסף
|
- **translated**: הוסף
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1507,7 +1507,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: Disinstalla
|
- **translated**: Disinstalla
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: Aggiungi
|
- **translated**: Aggiungi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1407,7 +1407,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: アンインストール
|
- **translated**: アンインストール
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: 追加
|
- **translated**: 追加
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1359,7 +1359,7 @@ Write a prompt that is mindful of the nuances in the language with respect to it
|
||||||
- **english**: Uninstall
|
- **english**: Uninstall
|
||||||
- **translated**: 卸载
|
- **translated**: 卸载
|
||||||
|
|
||||||
- **com_nav_tool_add**:
|
- **com_ui_add**:
|
||||||
- **english**: Add
|
- **english**: Add
|
||||||
- **translated**: 添加
|
- **translated**: 添加
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -328,3 +328,13 @@
|
||||||
.sp-wrapper {
|
.sp-wrapper {
|
||||||
@apply flex h-full w-full grow flex-col justify-center;
|
@apply flex h-full w-full grow flex-col justify-center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes shake {
|
||||||
|
0%, 100% { transform: translateX(0); }
|
||||||
|
10%, 30%, 50%, 70%, 90% { transform: translateX(-3px); }
|
||||||
|
20%, 40%, 60%, 80% { transform: translateX(3px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.shake {
|
||||||
|
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1172,7 +1172,7 @@ button {
|
||||||
.btn-neutral {
|
.btn-neutral {
|
||||||
--tw-bg-opacity: 1;
|
--tw-bg-opacity: 1;
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
|
background-color: var(--surface-secondary);
|
||||||
border-color: rgba(0, 0, 0, 0.1);
|
border-color: rgba(0, 0, 0, 0.1);
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
color: rgba(64, 65, 79, var(--tw-text-opacity));
|
color: rgba(64, 65, 79, var(--tw-text-opacity));
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,13 @@ export const cardStyle =
|
||||||
'transition-colors rounded-md min-w-[75px] border font-normal bg-white hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-700 dark:bg-gray-800 text-black dark:text-gray-600 focus:outline-none data-[state=open]:bg-gray-50 dark:data-[state=open]:bg-gray-700';
|
'transition-colors rounded-md min-w-[75px] border font-normal bg-white hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-700 dark:bg-gray-800 text-black dark:text-gray-600 focus:outline-none data-[state=open]:bg-gray-50 dark:data-[state=open]:bg-gray-700';
|
||||||
|
|
||||||
export const defaultTextProps =
|
export const defaultTextProps =
|
||||||
'rounded-md border border-gray-200 focus:border-gray-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none focus-within:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:focus:bg-gray-600 dark:focus:border-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:outline-none';
|
'rounded-md border border-gray-200 focus:border-gray-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none focus-within:placeholder:text-text-primary focus:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-700 dark:border-gray-600 dark:focus:bg-gray-600 dark:focus:border-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:outline-none';
|
||||||
|
|
||||||
export const optionText =
|
export const optionText =
|
||||||
'p-0 shadow-none text-right pr-1 h-8 border-transparent hover:bg-gray-800/10 dark:hover:bg-white/10 dark:focus:bg-white/10 transition-colors';
|
'p-0 shadow-none text-right pr-1 h-8 border-transparent hover:bg-gray-800/10 dark:hover:bg-white/10 dark:focus:bg-white/10 transition-colors';
|
||||||
|
|
||||||
export const defaultTextPropsLabel =
|
export const defaultTextPropsLabel =
|
||||||
'rounded-md border border-gray-300 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.10)] outline-none focus-within:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-700 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-600 dark:focus:outline-none';
|
'rounded-md border border-gray-300 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.10)] outline-none focus-within:placeholder:text-text-primary focus:placeholder:text-text-primary placeholder:text-text-secondary focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:bg-gray-700 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-600 dark:focus:outline-none';
|
||||||
|
|
||||||
export function capitalizeFirstLetter(string: string) {
|
export function capitalizeFirstLetter(string: string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
|
|
||||||
1
package-lock.json
generated
1
package-lock.json
generated
|
|
@ -30357,6 +30357,7 @@
|
||||||
"version": "4.4.5",
|
"version": "4.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||||
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
|
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"dom-helpers": "^5.0.1",
|
"dom-helpers": "^5.0.1",
|
||||||
|
|
|
||||||
|
|
@ -972,6 +972,8 @@ export enum Constants {
|
||||||
DEFAULT_STREAM_RATE = 1,
|
DEFAULT_STREAM_RATE = 1,
|
||||||
/** Saved Tag */
|
/** Saved Tag */
|
||||||
SAVED_TAG = 'Saved',
|
SAVED_TAG = 'Saved',
|
||||||
|
/** Max number of Conversation starters for Agents/Assistants */
|
||||||
|
MAX_CONVO_STARTERS = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LocalStorageKeys {
|
export enum LocalStorageKeys {
|
||||||
|
|
|
||||||
|
|
@ -255,14 +255,18 @@ export function getAssistantDocs({
|
||||||
endpoint,
|
endpoint,
|
||||||
version,
|
version,
|
||||||
}: {
|
}: {
|
||||||
endpoint: s.AssistantsEndpoint;
|
endpoint: s.AssistantsEndpoint | string;
|
||||||
version: number | string;
|
version: number | string;
|
||||||
}): Promise<a.AssistantDocument[]> {
|
}): Promise<a.AssistantDocument[]> {
|
||||||
|
if (!s.isAssistantsEndpoint(endpoint)) {
|
||||||
|
return Promise.resolve([]);
|
||||||
|
}
|
||||||
return request.get(
|
return request.get(
|
||||||
endpoints.assistants({
|
endpoints.assistants({
|
||||||
path: 'documents',
|
path: 'documents',
|
||||||
version,
|
version,
|
||||||
endpoint,
|
options: { endpoint },
|
||||||
|
endpoint: endpoint as s.AssistantsEndpoint,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ export const defaultAssistantFormValues = {
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
instructions: '',
|
instructions: '',
|
||||||
|
conversation_starters: [],
|
||||||
model: '',
|
model: '',
|
||||||
functions: [],
|
functions: [],
|
||||||
code_interpreter: false,
|
code_interpreter: false,
|
||||||
|
|
|
||||||
|
|
@ -70,13 +70,14 @@ export type Assistant = {
|
||||||
id: string;
|
id: string;
|
||||||
created_at: number;
|
created_at: number;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
file_ids: string[];
|
file_ids?: string[];
|
||||||
instructions: string | null;
|
instructions: string | null;
|
||||||
|
conversation_starters?: string[];
|
||||||
metadata: Metadata | null;
|
metadata: Metadata | null;
|
||||||
model: string;
|
model: string;
|
||||||
name: string | null;
|
name: string | null;
|
||||||
object: string;
|
object: string;
|
||||||
tools: FunctionTool[];
|
tools?: FunctionTool[];
|
||||||
tool_resources?: ToolResources;
|
tool_resources?: ToolResources;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -87,6 +88,7 @@ export type AssistantCreateParams = {
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
file_ids?: string[];
|
file_ids?: string[];
|
||||||
instructions?: string | null;
|
instructions?: string | null;
|
||||||
|
conversation_starters?: string[];
|
||||||
metadata?: Metadata | null;
|
metadata?: Metadata | null;
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
tools?: Array<FunctionTool | string>;
|
tools?: Array<FunctionTool | string>;
|
||||||
|
|
@ -99,6 +101,7 @@ export type AssistantUpdateParams = {
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
file_ids?: string[];
|
file_ids?: string[];
|
||||||
instructions?: string | null;
|
instructions?: string | null;
|
||||||
|
conversation_starters?: string[] | null;
|
||||||
metadata?: Metadata | null;
|
metadata?: Metadata | null;
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
tools?: Array<FunctionTool | string>;
|
tools?: Array<FunctionTool | string>;
|
||||||
|
|
@ -392,6 +395,7 @@ export type AssistantAvatar = {
|
||||||
export type AssistantDocument = {
|
export type AssistantDocument = {
|
||||||
user: string;
|
user: string;
|
||||||
assistant_id: string;
|
assistant_id: string;
|
||||||
|
conversation_starters?: string[];
|
||||||
avatar?: AssistantAvatar;
|
avatar?: AssistantAvatar;
|
||||||
access_level?: number;
|
access_level?: number;
|
||||||
file_ids?: string[];
|
file_ids?: string[];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue