From 3eed9821446475729d6a346f05160e2691babefe Mon Sep 17 00:00:00 2001 From: Philippe Rolet Date: Fri, 19 Jan 2024 12:31:55 +0100 Subject: [PATCH] [Ahuna] Allow moving an assistant back to private (#3306) * [Ahuna] Allow moving an assistant back to private Fixes #3270 API route to change scope of an assistant allows private, with associated logic (see issue) * cleaning * fixes + actually leave the agent in users' lists --- front/lib/api/assistant/configuration.ts | 10 --- front/lib/api/assistant/user_relation.ts | 2 +- .../agent_configurations/[aId]/scope.ts | 65 +++++++++++++++---- .../w/[wId]/members/me/agent_list_status.ts | 4 +- 4 files changed, 54 insertions(+), 27 deletions(-) diff --git a/front/lib/api/assistant/configuration.ts b/front/lib/api/assistant/configuration.ts index e42e78de686e..41d4c0756172 100644 --- a/front/lib/api/assistant/configuration.ts +++ b/front/lib/api/assistant/configuration.ts @@ -668,16 +668,6 @@ export async function createAgentConfiguration( if (userRelation) { listStatusOverride = userRelation.listStatusOverride; } - - // At time of writing, private agents can only be created from scratch. An existing agent - // that is not already private cannot be updated back to private. - if ( - existing && - scope === "private" && - existing.scope !== "private" - ) { - throw new Error("Published agents cannot go back to private."); - } } await AgentConfiguration.update( diff --git a/front/lib/api/assistant/user_relation.ts b/front/lib/api/assistant/user_relation.ts index d3408a41257c..b0ebb9f839f6 100644 --- a/front/lib/api/assistant/user_relation.ts +++ b/front/lib/api/assistant/user_relation.ts @@ -68,7 +68,7 @@ export async function getAgentUserListStatus({ ); } -export async function setAgentUserListstatus({ +export async function setAgentUserListStatus({ auth, agentId, listStatus, diff --git a/front/pages/api/w/[wId]/assistant/agent_configurations/[aId]/scope.ts b/front/pages/api/w/[wId]/assistant/agent_configurations/[aId]/scope.ts index 3dd67ea11782..28fdbb081c7a 100644 --- a/front/pages/api/w/[wId]/assistant/agent_configurations/[aId]/scope.ts +++ b/front/pages/api/w/[wId]/assistant/agent_configurations/[aId]/scope.ts @@ -4,12 +4,11 @@ import * as t from "io-ts"; import * as reporter from "io-ts-reporters"; import type { NextApiRequest, NextApiResponse } from "next"; -import { - getAgentConfiguration, - setAgentScope, -} from "@app/lib/api/assistant/configuration"; +import { getAgentConfiguration } from "@app/lib/api/assistant/configuration"; +import { setAgentUserListStatus } from "@app/lib/api/assistant/user_relation"; import { Authenticator, getSession } from "@app/lib/auth"; import { apiError, withLogging } from "@app/logger/withlogging"; +import { createOrUpgradeAgentConfiguration } from "@app/pages/api/w/[wId]/assistant/agent_configurations"; async function handler( req: NextApiRequest, @@ -86,25 +85,63 @@ async function handler( }, }); } + if ( assistant.scope !== "private" && bodyValidation.right.scope === "private" ) { - return apiError(req, res, { - status_code: 400, - api_error: { - type: "invalid_request_error", - message: "Non-private assistants cannot be set back to private.", - }, + // switching an assistant back to private: the caller must be a user + if (!auth.user()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "app_auth_error", + message: + "An assistant can only be set to private by an existing user of the workspace.", + }, + }); + } + + if (assistant.scope === "workspace" && !auth.isBuilder()) { + return apiError(req, res, { + status_code: 404, + api_error: { + type: "app_auth_error", + message: "Only builders can modify workspace assistants.", + }, + }); + } + + // ensure the assistant is not in the list of the user otherwise + // switching it back to private will make it disappear + const setRes = await setAgentUserListStatus({ + auth, + agentId: assistant.sId, + listStatus: "in-list", }); + + if (setRes.isErr()) { + return apiError(req, res, { + status_code: 500, + api_error: { + type: "internal_server_error", + message: setRes.error.message, + }, + }); + } } - const result = await setAgentScope( + const result = await createOrUpgradeAgentConfiguration( auth, - assistant.sId, - bodyValidation.right.scope + { + assistant: { + ...assistant, + scope: bodyValidation.right.scope, + status: assistant.status as "active" | "archived", // type adjustment + }, + }, + assistant.sId ); - if (result.isErr()) { return apiError(req, res, { status_code: 500, diff --git a/front/pages/api/w/[wId]/members/me/agent_list_status.ts b/front/pages/api/w/[wId]/members/me/agent_list_status.ts index 0c204ab0c3ec..1a04d9708550 100644 --- a/front/pages/api/w/[wId]/members/me/agent_list_status.ts +++ b/front/pages/api/w/[wId]/members/me/agent_list_status.ts @@ -5,7 +5,7 @@ import * as reporter from "io-ts-reporters"; import type { NextApiRequest, NextApiResponse } from "next"; import { getAgentConfiguration } from "@app/lib/api/assistant/configuration"; -import { setAgentUserListstatus } from "@app/lib/api/assistant/user_relation"; +import { setAgentUserListStatus } from "@app/lib/api/assistant/user_relation"; import { Authenticator, getSession } from "@app/lib/auth"; import { apiError, withLogging } from "@app/logger/withlogging"; @@ -96,7 +96,7 @@ async function handler( }); } - const result = await setAgentUserListstatus({ + const result = await setAgentUserListStatus({ auth, agentId, listStatus,