- {shouldShowDynamicInput ? (
+ {shouldShowMetaInputs ? (
)}
- {isDynamicInput && inputs != undefined && (
+ {isMetaInputs && inputs != undefined && (
}
- {isDynamicInput && currentInputMeta?.inputs?.type !== undefined ? (
- {
async function getHistory() {
@@ -29,7 +29,7 @@ export default function WorkspaceChat({ loading, workspace }) {
// TODO: add conditional if dynamic input is enabled in the workspace by default is false
// Append metadata to the chat history
- if (isDynamicInput) {
+ if (isMetaInputs) {
chatHistory = chatHistory.map((message) => {
if (message.role === "assistant") {
const { remainingText, metaData } = extractMetaData(
@@ -85,7 +85,7 @@ export default function WorkspaceChat({ loading, workspace }) {
diff --git a/server/endpoints/workspaceMetaResponse.js b/server/endpoints/workspaceMetaResponse.js
new file mode 100644
index 00000000..0f9e0ab4
--- /dev/null
+++ b/server/endpoints/workspaceMetaResponse.js
@@ -0,0 +1,294 @@
+const { multiUserMode, userFromSession } = require("../utils/http");
+const { validatedRequest } = require("../utils/middleware/validatedRequest");
+const { Telemetry } = require("../models/telemetry");
+const {
+ flexUserRoleValid,
+ ROLES,
+} = require("../utils/middleware/multiUserProtected");
+const { EventLogs } = require("../models/eventLogs");
+const { WorkspaceMetaResponse } = require("../models/workspaceMetaResponse");
+const { validWorkspaceSlug } = require("../utils/middleware/validWorkspace");
+
+function workspaceMetaResponse(app) {
+ if (!app) return;
+
+ app.patch(
+ "/workspace/:slug/metaResponse/toggle",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const user = await userFromSession(request, response);
+ const workspace = response.locals.workspace;
+ const metaResponse = workspace.metaResponse;
+ // If metaResponse settings are not found, create them
+ if (!workspace.metaResponse && !workspace.metaResponseSettings) {
+ metaResponseDefaultSettings.inputs.config.systemPrompt.openAiPrompt =
+ workspace.openAiPrompt || "";
+ await WorkspaceMetaResponse.update(
+ workspace.id,
+ JSON.stringify(metaResponseDefaultSettings)
+ );
+ await Telemetry.sendTelemetry(
+ "workspace_meta_response_enabled",
+ {
+ multiUserMode: multiUserMode(response),
+ LLMSelection: process.env.LLM_PROVIDER || "openai",
+ Embedder: process.env.EMBEDDING_ENGINE || "inherit",
+ VectorDbSelection: process.env.VECTOR_DB || "pinecone",
+ },
+ user?.id
+ );
+
+ await EventLogs.logEvent(
+ "workspace_meta_response_enabled",
+ {
+ workspaceName: workspace?.name || "Unknown Workspace",
+ },
+ user?.id
+ );
+ }
+ await WorkspaceMetaResponse.toggleMetaResponse(workspace.id, !metaResponse);
+ response.sendStatus(200).end();
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.get(
+ "/workspace/:slug/metaResponse/status",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ response.status(200).json({ status: workspace.metaResponse });
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.get(
+ "/workspace/:slug/metaResponse/settings",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ if (!settings) {
+ response.status(200).json(metaResponseDefaultSettings);
+ return;
+ }
+ response.status(200).json(settings);
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.patch(
+ "/workspace/:slug/metaResponse/settings",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const data = request.body;
+ const result = await WorkspaceMetaResponse.update(workspace.id, JSON.stringify(data));
+ response.status(200).json(JSON.parse(result.metaResponseSettings));
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.get(
+ "/workspace/:slug/metaResponse/inputs/settings",
+
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ response.status(200).json(settings.inputs);
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.patch(
+ "/workspace/:slug/metaResponse/inputs/settings",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const data = request.body;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ settings.inputs = data;
+ const result = await WorkspaceMetaResponse.update(
+ workspace.id,
+ JSON.stringify(settings)
+ );
+ response.status(200).json(JSON.parse(result.metaResponseSettings).inputs);
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.patch(
+ "/workspace/:slug/metaResponse/inputs/toggle",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ settings.inputs.isEnabled = !settings.inputs.isEnabled;
+ const result = await WorkspaceMetaResponse.update(
+ workspace.id,
+ JSON.stringify(settings)
+ );
+ response.sendStatus(200).end();
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.get(
+ "/workspace/:slug/metaResponse/sentiments/settings",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ response.status(200).json(settings.sentiments);
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.patch(
+ "/workspace/:slug/metaResponse/sentiments/settings",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const data = request.body;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ settings.sentiments = data;
+ const result = await WorkspaceMetaResponse.update(
+ workspace.id,
+ JSON.stringify(settings)
+ );
+ response.status(200).json(JSON.parse(result.metaResponseSettings).sentiments);
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+
+ app.patch(
+ "/workspace/:slug/metaResponse/sentiments/toggle",
+ [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
+ async (request, response) => {
+ try {
+ const workspace = response.locals.workspace;
+ const settings = JSON.parse(workspace.metaResponseSettings);
+ settings.sentiments.isEnabled = !settings.sentiments.isEnabled;
+ const result = await WorkspaceMetaResponse.update(
+ workspace.id,
+ JSON.stringify(settings)
+ );
+ response.sendStatus(200).end();
+ } catch (e) {
+ console.log(e.message, e);
+ response.sendStatus(500).end();
+ }
+ }
+ );
+}
+
+const metaResponseDefaultSettings = {
+ inputs: {
+ isEnabled: false,
+ config: {
+ systemPrompt: {
+ isEnabled: false,
+ content: "",
+ openAiPrompt: "",
+ overrideSystemPrompt: false,
+ suggestionsList: [
+ {
+ title: "",
+ content: "",
+ },
+ ],
+ canEdit: ["admin", "manager"],
+ },
+ promptSchema: {
+ content: "",
+ suggestionsList: [
+ {
+ title: "",
+ content: "",
+ },
+ ],
+ overrideWorkspacePrompt: false,
+ canEdit: ["admin", "manager"],
+ },
+ components: {
+ dropDownMenu: {
+ isEnabled: false,
+ options: [],
+
+ },
+ optionsList: {
+ isEnabled: false,
+ options: [],
+ },
+ optionsButtons: {
+ isEnabled: false,
+ options: [],
+ },
+ multiSelectCheckboxes: {
+ isEnabled: false,
+ options: [],
+ },
+ },
+ },
+ permissions: ["user"],
+ },
+ sentiments: {
+ isEnabled: false,
+ config: {
+ sentimentAnalysis: {
+ isEnabled: false,
+
+ scoreThreshold: 0.5,
+ },
+ },
+ permissions: ["user"],
+ },
+ avatars: {
+ isEnabled: false,
+ config: {
+ avatarType: "circle",
+ avatarSize: "medium",
+ avatarName: "user",
+ },
+ permissions: ["user"],
+ },
+};
+
+module.exports = { workspaceMetaResponse };
diff --git a/server/index.js b/server/index.js
index ca09cc92..f177d48c 100644
--- a/server/index.js
+++ b/server/index.js
@@ -20,6 +20,7 @@ const { developerEndpoints } = require("./endpoints/api");
const { extensionEndpoints } = require("./endpoints/extensions");
const { bootHTTP, bootSSL } = require("./utils/boot");
const { workspaceThreadEndpoints } = require("./endpoints/workspaceThreads");
+const { workspaceMetaResponse } = require("./endpoints/workspaceMetaResponse");
const app = express();
const apiRouter = express.Router();
const FILE_LIMIT = "3GB";
@@ -39,6 +40,7 @@ systemEndpoints(apiRouter);
extensionEndpoints(apiRouter);
workspaceEndpoints(apiRouter);
workspaceThreadEndpoints(apiRouter);
+workspaceMetaResponse(apiRouter);
chatEndpoints(apiRouter);
adminEndpoints(apiRouter);
inviteEndpoints(apiRouter);
diff --git a/server/models/workspaceMetaResponse.js b/server/models/workspaceMetaResponse.js
new file mode 100644
index 00000000..923f7e4f
--- /dev/null
+++ b/server/models/workspaceMetaResponse.js
@@ -0,0 +1,69 @@
+const prisma = require("../utils/prisma");
+
+const WorkspaceMetaResponse = {
+ writable: ["name"],
+
+ update: async function (workspaceId, data) {
+ try {
+ const result = await prisma.workspaces.update({
+ where: {
+ id: workspaceId,
+ },
+ data: {
+ metaResponseSettings: data,
+ },
+ });
+ return {
+ metaResponseSettings: result.metaResponseSettings,
+ message: null
+ };
+ } catch (error) {
+ console.error(error.message);
+ return { workspace: null, message: error.message };
+ }
+ },
+
+ get: async function (clause = {}) {
+ try {
+ const thread = await prisma.workspaces.findFirst({
+ where: clause,
+ });
+
+ return thread || null;
+ } catch (error) {
+ console.error(error.message);
+ return null;
+ }
+ },
+
+ where: async function (clause = {}, limit = null, orderBy = null) {
+ try {
+ const results = await prisma.workspaces.findMany({
+ where: clause,
+ ...(limit !== null ? { take: limit } : {}),
+ ...(orderBy !== null ? { orderBy } : {}),
+ });
+ return results;
+ } catch (error) {
+ console.error(error.message);
+ return [];
+ }
+ },
+
+ toggleMetaResponse: async function (workspaceId, status) {
+ try {
+ const result = await prisma.workspaces.update({
+ where: { id: workspaceId },
+ data: {
+ metaResponse: status,
+ },
+ });
+ return { result, message: null };
+ } catch (error) {
+ console.error(error.message);
+ return { workspace: null, message: error.message };
+ }
+ }
+};
+
+module.exports = { WorkspaceMetaResponse };
diff --git a/server/prisma/migrations/20240316221455_init/migration.sql b/server/prisma/migrations/20240316221455_init/migration.sql
new file mode 100644
index 00000000..9e504f36
--- /dev/null
+++ b/server/prisma/migrations/20240316221455_init/migration.sql
@@ -0,0 +1,3 @@
+-- AlterTable
+ALTER TABLE "workspaces" ADD COLUMN "metaResponse" BOOLEAN DEFAULT false;
+ALTER TABLE "workspaces" ADD COLUMN "metaResponseSettings" TEXT;
diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma
index e6121e29..d595dfeb 100644
--- a/server/prisma/schema.prisma
+++ b/server/prisma/schema.prisma
@@ -100,7 +100,9 @@ model workspaces {
chatModel String?
topN Int? @default(4)
chatMode String? @default("chat")
- pfpFilename String?
+ pfpFilename String?
+ metaResponse Boolean? @default(false)
+ metaResponseSettings String?
workspace_users workspace_users[]
documents workspace_documents[]
workspace_suggested_messages workspace_suggested_messages[]