diff --git a/front/lib/api/assistant/agent.ts b/front/lib/api/assistant/agent.ts index 1affa9194b946..801df06170f7a 100644 --- a/front/lib/api/assistant/agent.ts +++ b/front/lib/api/assistant/agent.ts @@ -1,35 +1,14 @@ -import { Op, Transaction } from "sequelize"; - import { cloneBaseConfig, DustProdActionRegistry, } from "@app/lib/actions/registry"; import { runAction } from "@app/lib/actions/server"; -import { _getAgentConfigurationType } from "@app/lib/api/assistant/agent_utils"; import { Authenticator } from "@app/lib/auth"; -import { front_sequelize } from "@app/lib/databases"; -import { DataSource, Workspace } from "@app/lib/models"; -import { - AgentDataSourceConfiguration, - AgentRetrievalConfiguration, -} from "@app/lib/models/assistant/actions/retrieval"; -import { - AgentConfiguration, - AgentGenerationConfiguration, -} from "@app/lib/models/assistant/agent"; import { Err, Ok, Result } from "@app/lib/result"; import { generateModelSId } from "@app/lib/utils"; import { - AgentDataSourceConfigurationType, - isTemplatedQuery, - isTimeFrame, -} from "@app/types/assistant/actions/retrieval"; -import { - AgentActionConfigurationType, AgentActionSpecification, - AgentConfigurationStatus, AgentConfigurationType, - AgentGenerationConfigurationType, } from "@app/types/assistant/agent"; import { AgentActionType, @@ -43,276 +22,6 @@ import { } from "./actions/retrieval"; import { renderConversationForModel } from "./conversation"; -/** - * Get an agent configuration from its name - */ -export async function getAgentConfiguration(auth: Authenticator, name: string) { - const owner = auth.workspace(); - if (!owner) { - return; - } - const agent = await AgentConfiguration.findOne({ - where: { - name: name, - workspaceId: owner.id, - }, - }); - const agentGeneration = await AgentGenerationConfiguration.findOne({ - where: { - agentId: agent?.id, - }, - }); - const agentAction = await AgentRetrievalConfiguration.findOne({ - where: { - agentId: agent?.id, - }, - }); - const agentDataSources = agentAction?.id - ? await AgentDataSourceConfiguration.findAll({ - where: { - retrievalConfigurationId: agentAction?.id, - }, - }) - : []; - - if (!agent) { - return; - } - return await _getAgentConfigurationType({ - agent: agent, - generation: agentGeneration, - action: agentAction, - dataSources: agentDataSources, - }); -} - -/** - * Create a new Agent - */ -export async function createAgentConfiguration( - auth: Authenticator, - { - name, - pictureUrl, - action, - generation, - }: { - name: string; - pictureUrl?: string; - action?: AgentActionConfigurationType; - generation?: AgentGenerationConfigurationType; - } -): Promise { - const owner = auth.workspace(); - if (!owner) { - return; - } - - return await front_sequelize.transaction(async (t) => { - let agentConfigRow: AgentConfiguration | null = null; - let agentGenerationConfigRow: AgentGenerationConfiguration | null = null; - let agentActionConfigRow: AgentRetrievalConfiguration | null = null; - let agentDataSourcesConfigRows: AgentDataSourceConfiguration[] = []; - - // Create AgentConfiguration - agentConfigRow = await AgentConfiguration.create( - { - sId: generateModelSId(), - status: "active", - name: name, - pictureUrl: pictureUrl ?? null, - scope: "workspace", - workspaceId: owner.id, - }, - { transaction: t } - ); - - // Create AgentGenerationConfiguration - if (generation) { - agentGenerationConfigRow = await AgentGenerationConfiguration.create( - { - prompt: generation.prompt, - modelProvider: generation.model.providerId, - modelId: generation.model.modelId, - agentId: agentConfigRow.id, - }, - { transaction: t } - ); - } - - // Create AgentRetrievalConfiguration & AgentDataSourceConfiguration - if (action) { - const query = action.query; - const timeframe = action.relativeTimeFrame; - agentActionConfigRow = await AgentRetrievalConfiguration.create( - { - query: isTemplatedQuery(query) ? "templated" : query, - queryTemplate: isTemplatedQuery(query) ? query.template : null, - relativeTimeFrame: isTimeFrame(timeframe) ? "custom" : timeframe, - relativeTimeFrameDuration: isTimeFrame(timeframe) - ? timeframe.duration - : null, - relativeTimeFrameUnit: isTimeFrame(timeframe) ? timeframe.unit : null, - topK: action.topK, - agentId: agentConfigRow.id, - }, - { transaction: t } - ); - agentDataSourcesConfigRows = await _createAgentDataSourcesConfigData( - t, - action.dataSources, - agentActionConfigRow.id - ); - } - - return await _getAgentConfigurationType({ - agent: agentConfigRow, - action: agentActionConfigRow, - generation: agentGenerationConfigRow, - dataSources: agentDataSourcesConfigRows, - }); - }); -} - -/** - * Create the AgentDataSourceConfiguration rows in database. - * - * Knowing that a datasource is uniquely identified by its name and its workspaceId - * We need to fetch the dataSources from the database from that. - * We obvisously need to do as few queries as possible. - */ -async function _createAgentDataSourcesConfigData( - t: Transaction, - dataSourcesConfig: AgentDataSourceConfigurationType[], - agentActionId: number -): Promise { - // dsConfig contains this format: - // [ - // { workspaceSId: s1o1u1p, dataSourceName: "managed-notion", filter: { tags: null, parents: null } }, - // { workspaceSId: s1o1u1p, dataSourceName: "managed-slack", filter: { tags: null, parents: null } }, - // { workspaceSId: i2n2o2u, dataSourceName: "managed-notion", filter: { tags: null, parents: null } }, - // ] - - // First we get the list of workspaces because we need the mapping between workspaceSId and workspaceId - const workspaces = await Workspace.findAll({ - where: { - sId: dataSourcesConfig.map((dsConfig) => dsConfig.workspaceSId), - }, - attributes: ["id", "sId"], - }); - - // Now will want to group the datasource names by workspaceId to do only one query per workspace. - // We want this: - // [ - // { workspaceId: 1, dataSourceNames: [""managed-notion", "managed-slack"] }, - // { workspaceId: 2, dataSourceNames: ["managed-notion"] } - // ] - type _DsNamesPerWorkspaceIdType = { - workspaceId: number; - dataSourceNames: string[]; - }; - const dsNamesPerWorkspaceId = dataSourcesConfig.reduce( - ( - acc: _DsNamesPerWorkspaceIdType[], - curr: AgentDataSourceConfigurationType - ) => { - // First we need to get the workspaceId from the workspaceSId - const workspace = workspaces.find((w) => w.sId === curr.workspaceSId); - if (!workspace) { - throw new Error("Workspace not found"); - } - - // Find an existing entry for this workspaceId - const existingEntry: _DsNamesPerWorkspaceIdType | undefined = acc.find( - (entry: _DsNamesPerWorkspaceIdType) => - entry.workspaceId === workspace.id - ); - if (existingEntry) { - // Append dataSourceName to existing entry - existingEntry.dataSourceNames.push(curr.dataSourceName); - } else { - // Add a new entry for this workspaceId - acc.push({ - workspaceId: workspace.id, - dataSourceNames: [curr.dataSourceName], - }); - } - return acc; - }, - [] - ); - - // Then we get do one findAllQuery per workspaceId, in a Promise.all - const getDataSourcesQueries = dsNamesPerWorkspaceId.map( - ({ workspaceId, dataSourceNames }) => { - return DataSource.findAll({ - where: { - workspaceId, - name: { - [Op.in]: dataSourceNames, - }, - }, - }); - } - ); - const results = await Promise.all(getDataSourcesQueries); - const dataSources = results.flat(); - - const agentDataSourcesConfigRows: AgentDataSourceConfiguration[] = - await Promise.all( - dataSourcesConfig.map(async (dsConfig) => { - const dataSource = dataSources.find( - (ds) => - ds.name === dsConfig.dataSourceName && - ds.workspaceId === - workspaces.find((w) => w.sId === dsConfig.workspaceSId)?.id - ); - if (!dataSource) { - throw new Error("DataSource not found"); - } - return AgentDataSourceConfiguration.create( - { - dataSourceId: dataSource.id, - tagsIn: dsConfig.filter.tags?.in, - tagsNotIn: dsConfig.filter.tags?.not, - parentsIn: dsConfig.filter.parents?.in, - parentsNotIn: dsConfig.filter.parents?.not, - retrievalConfigurationId: agentActionId, - }, - { transaction: t } - ); - }) - ); - return agentDataSourcesConfigRows; -} - -export async function updateAgentConfiguration( - auth: Authenticator, - configurationId: string, - { - name, - pictureUrl, - status, - action, - generation, - }: { - name: string; - pictureUrl?: string; - status: AgentConfigurationStatus; - action?: AgentActionConfigurationType; - generation?: AgentGenerationConfigurationType; - } -): Promise { - return { - sId: generateModelSId(), - name, - pictureUrl: pictureUrl ?? null, - status, - action: action ?? null, - generation: generation ?? null, - }; -} - /** * Action Inputs generation. */ diff --git a/front/lib/api/assistant/agent/agent_create.ts b/front/lib/api/assistant/agent/agent_create.ts new file mode 100644 index 0000000000000..962e2442df202 --- /dev/null +++ b/front/lib/api/assistant/agent/agent_create.ts @@ -0,0 +1,280 @@ +import { Op, Transaction } from "sequelize"; + +import { + _buildAgentActionConfigurationTypeFromModel, + _buildAgentConfigurationTypeFromModel, + _buildAgentGenerationConfigurationTypeFromModel, +} from "@app/lib/api/assistant/agent/agent_get"; +import { Authenticator } from "@app/lib/auth"; +import { front_sequelize } from "@app/lib/databases"; +import { DataSource, Workspace } from "@app/lib/models"; +import { + AgentDataSourceConfiguration, + AgentRetrievalConfiguration, +} from "@app/lib/models/assistant/actions/retrieval"; +import { + AgentConfiguration, + AgentGenerationConfiguration, +} from "@app/lib/models/assistant/agent"; +import { generateModelSId } from "@app/lib/utils"; +import { + AgentDataSourceConfigurationType, + isTemplatedQuery, + isTimeFrame, + RetrievalDataSourcesConfiguration, + RetrievalQuery, + RetrievalTimeframe, +} from "@app/types/assistant/actions/retrieval"; +import { + AgentActionConfigurationType, + AgentConfigurationType, + AgentGenerationConfigurationType, +} from "@app/types/assistant/agent"; + +/** + * Create Agent Configuration + */ +export async function createAgentConfiguration( + auth: Authenticator, + { + name, + pictureUrl, + }: { + name: string; + pictureUrl: string; + } +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error("Cannot create AgentConfiguration without workspace"); + } + + const agentConfig = await AgentConfiguration.create({ + sId: generateModelSId(), + status: "active", + name: name, + pictureUrl: pictureUrl ?? null, + scope: "workspace", + workspaceId: owner.id, + }); + + return _buildAgentConfigurationTypeFromModel({ + agent: agentConfig, + }); +} + +/** + * Create Agent Generation Configuration + */ +export async function createAgentGenerationConfiguration( + auth: Authenticator, + agentSid: string, + { + prompt, + modelProvider, + modelId, + }: { + prompt: string; + modelProvider: string; + modelId: string; + } +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error( + "Cannot create AgentGenerationConfiguration: Workspace not found" + ); + } + + const agentConfig = await AgentConfiguration.findOne({ + where: { + sId: agentSid, + }, + }); + if (!agentConfig) { + throw new Error( + "Cannot create AgentGenerationConfiguration: Agent not found" + ); + } + + const generation = await AgentGenerationConfiguration.create({ + prompt: prompt, + modelProvider: modelProvider, + modelId: modelId, + agentId: agentConfig.id, + }); + + return _buildAgentGenerationConfigurationTypeFromModel(generation); +} + +/** + * Create Agent Action Configuration (Retrieval) + */ +export async function createAgentActionRetrievalConfiguration( + auth: Authenticator, + agentSid: string, + { + query, + timeframe, + topK, + dataSources, + }: { + query: RetrievalQuery; + timeframe: RetrievalTimeframe; + topK: number; + dataSources: RetrievalDataSourcesConfiguration; + } +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error( + "Cannot create AgentActionConfiguration: Workspace not found" + ); + } + + const agentConfig = await AgentConfiguration.findOne({ + where: { + sId: agentSid, + }, + }); + if (!agentConfig) { + throw new Error("Cannot create AgentActionConfiguration: Agent not found"); + } + return await front_sequelize.transaction(async (t) => { + const agentActionConfigRow = await AgentRetrievalConfiguration.create( + { + query: isTemplatedQuery(query) ? "templated" : query, + queryTemplate: isTemplatedQuery(query) ? query.template : null, + relativeTimeFrame: isTimeFrame(timeframe) ? "custom" : timeframe, + relativeTimeFrameDuration: isTimeFrame(timeframe) + ? timeframe.duration + : null, + relativeTimeFrameUnit: isTimeFrame(timeframe) ? timeframe.unit : null, + topK: topK, + agentId: agentConfig.id, + }, + { transaction: t } + ); + const agentDataSourcesConfigRows = await _createAgentDataSourcesConfigData( + t, + dataSources, + agentActionConfigRow.id + ); + return await _buildAgentActionConfigurationTypeFromModel( + agentActionConfigRow, + agentDataSourcesConfigRows + ); + }); +} + +/** + * Create the AgentDataSourceConfiguration rows in database. + * + * Knowing that a datasource is uniquely identified by its name and its workspaceId + * We need to fetch the dataSources from the database from that. + * We obvisously need to do as few queries as possible. + */ +export async function _createAgentDataSourcesConfigData( + t: Transaction, + dataSourcesConfig: AgentDataSourceConfigurationType[], + agentActionId: number +): Promise { + // dsConfig contains this format: + // [ + // { workspaceSId: s1o1u1p, dataSourceName: "managed-notion", filter: { tags: null, parents: null } }, + // { workspaceSId: s1o1u1p, dataSourceName: "managed-slack", filter: { tags: null, parents: null } }, + // { workspaceSId: i2n2o2u, dataSourceName: "managed-notion", filter: { tags: null, parents: null } }, + // ] + + // First we get the list of workspaces because we need the mapping between workspaceSId and workspaceId + const workspaces = await Workspace.findAll({ + where: { + sId: dataSourcesConfig.map((dsConfig) => dsConfig.workspaceSId), + }, + attributes: ["id", "sId"], + }); + + // Now will want to group the datasource names by workspaceId to do only one query per workspace. + // We want this: + // [ + // { workspaceId: 1, dataSourceNames: [""managed-notion", "managed-slack"] }, + // { workspaceId: 2, dataSourceNames: ["managed-notion"] } + // ] + type _DsNamesPerWorkspaceIdType = { + workspaceId: number; + dataSourceNames: string[]; + }; + const dsNamesPerWorkspaceId = dataSourcesConfig.reduce( + ( + acc: _DsNamesPerWorkspaceIdType[], + curr: AgentDataSourceConfigurationType + ) => { + // First we need to get the workspaceId from the workspaceSId + const workspace = workspaces.find((w) => w.sId === curr.workspaceSId); + if (!workspace) { + throw new Error("Workspace not found"); + } + + // Find an existing entry for this workspaceId + const existingEntry: _DsNamesPerWorkspaceIdType | undefined = acc.find( + (entry: _DsNamesPerWorkspaceIdType) => + entry.workspaceId === workspace.id + ); + if (existingEntry) { + // Append dataSourceName to existing entry + existingEntry.dataSourceNames.push(curr.dataSourceName); + } else { + // Add a new entry for this workspaceId + acc.push({ + workspaceId: workspace.id, + dataSourceNames: [curr.dataSourceName], + }); + } + return acc; + }, + [] + ); + + // Then we get do one findAllQuery per workspaceId, in a Promise.all + const getDataSourcesQueries = dsNamesPerWorkspaceId.map( + ({ workspaceId, dataSourceNames }) => { + return DataSource.findAll({ + where: { + workspaceId, + name: { + [Op.in]: dataSourceNames, + }, + }, + }); + } + ); + const results = await Promise.all(getDataSourcesQueries); + const dataSources = results.flat(); + + const agentDataSourcesConfigRows: AgentDataSourceConfiguration[] = + await Promise.all( + dataSourcesConfig.map(async (dsConfig) => { + const dataSource = dataSources.find( + (ds) => + ds.name === dsConfig.dataSourceName && + ds.workspaceId === + workspaces.find((w) => w.sId === dsConfig.workspaceSId)?.id + ); + if (!dataSource) { + throw new Error("DataSource not found"); + } + return AgentDataSourceConfiguration.create( + { + dataSourceId: dataSource.id, + tagsIn: dsConfig.filter.tags?.in, + tagsNotIn: dsConfig.filter.tags?.not, + parentsIn: dsConfig.filter.parents?.in, + parentsNotIn: dsConfig.filter.parents?.not, + retrievalConfigurationId: agentActionId, + }, + { transaction: t } + ); + }) + ); + return agentDataSourcesConfigRows; +} diff --git a/front/lib/api/assistant/agent_utils.ts b/front/lib/api/assistant/agent/agent_get.ts similarity index 70% rename from front/lib/api/assistant/agent_utils.ts rename to front/lib/api/assistant/agent/agent_get.ts index bd30750d26dad..f91b6c7aa0b4c 100644 --- a/front/lib/api/assistant/agent_utils.ts +++ b/front/lib/api/assistant/agent/agent_get.ts @@ -1,5 +1,6 @@ import { Op } from "sequelize"; +import { Authenticator } from "@app/lib/auth"; import { DataSource, Workspace } from "@app/lib/models"; import { AgentDataSourceConfiguration, @@ -18,40 +19,98 @@ import { AgentActionConfigurationType, AgentConfigurationType, AgentGenerationConfigurationType, + AgentType as AgentType, } from "@app/types/assistant/agent"; +/** + * Get an agent full configuration from its name + */ +export async function getAgent( + auth: Authenticator, + sId: string +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error("Cannot find Agent: no workspace"); + } + const agent = await AgentConfiguration.findOne({ + where: { + sId: sId, + workspaceId: owner.id, + }, + }); + if (!agent) { + throw new Error("Cannot find Agent: no workspace"); + } + const agentGeneration = await AgentGenerationConfiguration.findOne({ + where: { + agentId: agent.id, + }, + }); + const agentAction = await AgentRetrievalConfiguration.findOne({ + where: { + agentId: agent.id, + }, + }); + const agentDataSources = agentAction?.id + ? await AgentDataSourceConfiguration.findAll({ + where: { + retrievalConfigurationId: agentAction?.id, + }, + }) + : []; + + return { + agent: await _buildAgentConfigurationTypeFromModel({ agent }), + action: agentAction + ? await _buildAgentActionConfigurationTypeFromModel( + agentAction, + agentDataSources || [] + ) + : null, + generation: agentGeneration + ? _buildAgentGenerationConfigurationTypeFromModel(agentGeneration) + : null, + }; +} + /** * Builds the agent configuration type from the model */ -export async function _getAgentConfigurationType({ +export async function _buildAgentConfigurationTypeFromModel({ agent, - action, - generation, - dataSources, }: { agent: AgentConfiguration; - action: AgentRetrievalConfiguration | null; - generation: AgentGenerationConfiguration | null; - dataSources: AgentDataSourceConfiguration[] | null; }): Promise { return { + id: agent.id, sId: agent.sId, name: agent.name, pictureUrl: agent.pictureUrl, status: agent.status, - action: action - ? await _buildAgentActionConfigurationType(action, dataSources || []) - : null, - generation: generation - ? _buildAgentGenerationConfigurationType(generation) - : null, + }; +} + +/** + * Builds the agent generation configuration type from the model + */ +export function _buildAgentGenerationConfigurationTypeFromModel( + generation: AgentGenerationConfiguration +): AgentGenerationConfigurationType { + return { + id: generation.id, + prompt: generation.prompt, + model: { + providerId: generation.modelProvider, + modelId: generation.modelId, + }, }; } /** * Builds the agent action configuration type from the model */ -export async function _buildAgentActionConfigurationType( +export async function _buildAgentActionConfigurationTypeFromModel( action: AgentRetrievalConfiguration, dataSourcesConfig: AgentDataSourceConfiguration[] ): Promise { @@ -134,18 +193,3 @@ export async function _buildAgentActionConfigurationType( dataSources: retrievalDataSourcesConfig, }; } - -/** - * Builds the agent generation configuration type from the model - */ -export function _buildAgentGenerationConfigurationType( - generation: AgentGenerationConfiguration -): AgentGenerationConfigurationType { - return { - prompt: generation.prompt, - model: { - providerId: generation.modelProvider, - modelId: generation.modelId, - }, - }; -} diff --git a/front/lib/api/assistant/agent/agent_update.ts b/front/lib/api/assistant/agent/agent_update.ts new file mode 100644 index 0000000000000..2b9eb20b98e8a --- /dev/null +++ b/front/lib/api/assistant/agent/agent_update.ts @@ -0,0 +1,208 @@ +import { + _buildAgentActionConfigurationTypeFromModel, + _buildAgentConfigurationTypeFromModel, + _buildAgentGenerationConfigurationTypeFromModel, +} from "@app/lib/api/assistant/agent/agent_get"; +import { Authenticator } from "@app/lib/auth"; +import { front_sequelize } from "@app/lib/databases"; +import { + AgentConfiguration, + AgentDataSourceConfiguration, + AgentGenerationConfiguration, + AgentRetrievalConfiguration, +} from "@app/lib/models"; +import { + isTemplatedQuery, + isTimeFrame, + RetrievalConfigurationType, + RetrievalDataSourcesConfiguration, + RetrievalQuery, + RetrievalTimeframe, +} from "@app/types/assistant/actions/retrieval"; +import { + AgentConfigurationStatus, + AgentConfigurationType, + AgentGenerationConfigurationType, +} from "@app/types/assistant/agent"; + +import { _createAgentDataSourcesConfigData } from "./agent_create"; + +/** + * Update Agent Configuration + */ +export async function updateAgentConfiguration( + auth: Authenticator, + agentSid: string, + { + name, + pictureUrl, + status, + }: { + name: string; + pictureUrl: string; + status: AgentConfigurationStatus; + } +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error( + "Cannot create AgentGenerationConfiguration: Workspace not found" + ); + } + + const agentConfig = await AgentConfiguration.findOne({ + where: { + sId: agentSid, + }, + }); + if (!agentConfig) { + throw new Error( + "Cannot create AgentGenerationConfiguration: Agent not found" + ); + } + + const updatedAgent = await agentConfig.update({ + name: name, + pictureUrl: pictureUrl, + status: status, + }); + + return _buildAgentConfigurationTypeFromModel({ + agent: updatedAgent, + }); +} + +/** + * Update Agent Generation Configuration + */ +export async function updateAgentGenerationConfiguration( + auth: Authenticator, + agentSid: string, + { + prompt, + modelProvider, + modelId, + }: { + prompt: string; + modelProvider: string; + modelId: string; + } +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error( + "Cannot create AgentGenerationConfiguration: Workspace not found" + ); + } + + const agentConfig = await AgentConfiguration.findOne({ + where: { + sId: agentSid, + }, + }); + if (!agentConfig) { + throw new Error( + "Cannot create AgentGenerationConfiguration: Agent not found" + ); + } + + const generation = await AgentGenerationConfiguration.findOne({ + where: { + agentId: agentConfig.id, + }, + }); + if (!generation) { + throw new Error( + "Cannot update AgentGenerationConfiguration: Config not found" + ); + } + + const updatedGeneration = await generation.update({ + prompt: prompt, + modelProvider: modelProvider, + modelId: modelId, + }); + + return _buildAgentGenerationConfigurationTypeFromModel(updatedGeneration); +} + +/** + * Update Agent Generation Configuration + */ +export async function updateAgentActionRetrievalConfiguration( + auth: Authenticator, + agentSid: string, + { + query, + timeframe, + topK, + dataSources, + }: { + query: RetrievalQuery; + timeframe: RetrievalTimeframe; + topK: number; + dataSources: RetrievalDataSourcesConfiguration; + } +): Promise { + const owner = auth.workspace(); + if (!owner) { + throw new Error( + "Cannot create AgentActionConfiguration: Workspace not found" + ); + } + + const agentConfig = await AgentConfiguration.findOne({ + where: { + sId: agentSid, + }, + }); + if (!agentConfig) { + throw new Error("Cannot create AgentActionConfiguration: Agent not found"); + } + + const action = await AgentRetrievalConfiguration.findOne({ + where: { + agentId: agentConfig.id, + }, + }); + if (!action) { + throw new Error("Cannot update AgentActionConfiguration: Config not found"); + } + + // Updating both the Action and datasources in a single transaction + // So that we update both or none + return await front_sequelize.transaction(async (t) => { + // Update Action + const updatedAction = await action.update( + { + query: isTemplatedQuery(query) ? "templated" : query, + queryTemplate: isTemplatedQuery(query) ? query.template : null, + relativeTimeFrame: isTimeFrame(timeframe) ? "custom" : timeframe, + relativeTimeFrameDuration: isTimeFrame(timeframe) + ? timeframe.duration + : null, + relativeTimeFrameUnit: isTimeFrame(timeframe) ? timeframe.unit : null, + topK: topK, + agentId: agentConfig.id, + }, + { transaction: t } + ); + + // Update datasources: we drop and create them all + await AgentDataSourceConfiguration.destroy({ + where: { + retrievalConfigurationId: action.id, + }, + }); + const agentDataSourcesConfigRows = await _createAgentDataSourcesConfigData( + t, + dataSources, + action.id + ); + + return _buildAgentActionConfigurationTypeFromModel( + updatedAction, + agentDataSourcesConfigRows + ); + }); +} diff --git a/front/types/assistant/agent.ts b/front/types/assistant/agent.ts index 457320076e1a1..7d30c620779a7 100644 --- a/front/types/assistant/agent.ts +++ b/front/types/assistant/agent.ts @@ -1,3 +1,4 @@ +import { ModelId } from "@app/lib/databases"; import { RetrievalConfigurationType } from "@app/types/assistant/actions/retrieval"; /** @@ -29,7 +30,9 @@ export type AgentActionConfigurationType = RetrievalConfigurationType; // ] // } // ``` + export type AgentActionSpecification = { + id: ModelId; name: string; description: string; inputs: { @@ -44,6 +47,7 @@ export type AgentActionSpecification = { */ export type AgentGenerationConfigurationType = { + id: ModelId; prompt: string; model: { providerId: string; @@ -59,16 +63,18 @@ export type AgentConfigurationStatus = "active" | "archived"; export type AgentConfigurationScope = "global" | "workspace"; export type AgentConfigurationType = { + id: ModelId; sId: string; status: AgentConfigurationStatus; - name: string; pictureUrl: string | null; +}; +export type AgentType = { + agent: AgentConfigurationType; // If undefined, no action performed, otherwise the action is // performed (potentially NoOp eg autoSkip above). action: AgentActionConfigurationType | null; - // If undefined, no text generation. generation: AgentGenerationConfigurationType | null; };