Append install-wide instructions to every bot's prompt
Settings > General gains a prompt appendix the super admin sets once: markdown every bot runs with, right after its own core instructions. - The text lives in app_settings (bot_system_prompt_append, read through grabSystemPromptAppend, cached like every app setting), so it changes without a deploy and applies to every bot on the next run. - composeBotPrompt takes an appendix and pushes it as # Install-wide instructions directly after system_prompt, before the workspace block and memory, so the bot's own more specific rules still win. grabBotPrompt feeds it in, so chat replies, tasks, scheduled runs and the coordinator all get it with no call site touched. - api/admin/settings/system-prompt-append saves it (super admin only, capped at AppData.PromptMaxLength, empty clears it) and is audit logged under system. - The section and its form are hidden from everyone but the super admin, save in place with a character count and no reload, and say what an empty text does.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import grabSuperAdminUser from "@/src/functions/backend/backups/grab-super-admin-user";
|
||||
import {
|
||||
grabSystemPromptAppendOverview,
|
||||
type SystemPromptAppendOverview,
|
||||
} from "@/src/functions/backend/db/app-settings/grab-system-prompt-append";
|
||||
import saveAppSetting from "@/src/functions/backend/db/app-settings/save-app-setting";
|
||||
import logEvent, { grabRequestIP } from "@/src/functions/backend/logger";
|
||||
import { BotSystemPromptAppendSettingKey } from "@/src/dict/bot-dict";
|
||||
import { SaveSystemPromptAppendRequestSchema } from "@/src/schemas/bot-schema";
|
||||
import AppError from "@/src/utils/app-error";
|
||||
import parseWithSchema from "@/src/utils/parse-with-schema";
|
||||
import safeErrorMessage from "@/src/utils/safe-error-message";
|
||||
import type { APIResponseObject, BunextAPIRouteHandler } from "@moduletrace/bunext/types";
|
||||
|
||||
/**
|
||||
* Super admin only: the install-wide text every bot gets right after its
|
||||
* own core instructions. An empty text removes it.
|
||||
*/
|
||||
export const handler: BunextAPIRouteHandler<APIResponseObject<SystemPromptAppendOverview>> = async ({
|
||||
req,
|
||||
body,
|
||||
}) => {
|
||||
try {
|
||||
if (req.method != "POST") throw new AppError(`Method not allowed`);
|
||||
|
||||
const user = await grabSuperAdminUser({ req });
|
||||
|
||||
if (!user?.id) throw new AppError(`Only a super admin can change the prompt appendix.`);
|
||||
|
||||
const { text } = parseWithSchema({
|
||||
schema: SaveSystemPromptAppendRequestSchema,
|
||||
data: body,
|
||||
});
|
||||
|
||||
await saveAppSetting({
|
||||
key: BotSystemPromptAppendSettingKey,
|
||||
value: text || null,
|
||||
});
|
||||
|
||||
await logEvent({
|
||||
title: "Bot prompt appendix changed",
|
||||
category: "system",
|
||||
user_id: user.id,
|
||||
plain_text: text
|
||||
? `User #${user.id} set the install-wide bot prompt appendix (${text.length} characters).`
|
||||
: `User #${user.id} removed the install-wide bot prompt appendix.`,
|
||||
metadata: { characters: text.length },
|
||||
ip_address: grabRequestIP(req),
|
||||
});
|
||||
|
||||
return { success: true, singleRes: await grabSystemPromptAppendOverview() };
|
||||
} catch (error: unknown) {
|
||||
return { success: false, msg: safeErrorMessage({ error }) };
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user