Trim page props and page the conversation's messages
Bot and workspace lists in page props leave out instructions, memory and workspace context, and carry the last message as a short preview. The header avatar's edit form loads the bot's instructions when it opens. The conversation renders its latest 30 messages and loads older ones as the thread scrolls to its top. Also: the composer shows a placeholder until its editor loads, and `bun start` no longer builds first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import userAuth from "@/src/functions/backend/auth/user-auth";
|
||||
import grabUserBot from "@/src/functions/backend/db/bots/grab-user-bot";
|
||||
import { BotIdRequestSchema } from "@/src/schemas/bot-schema";
|
||||
import AppError from "@/src/utils/app-error";
|
||||
import parseWithSchema from "@/src/utils/parse-with-schema";
|
||||
import canManageCrew from "@/src/utils/rbac/can-manage-crew";
|
||||
import safeErrorMessage from "@/src/utils/safe-error-message";
|
||||
import type {
|
||||
APIResponseObject,
|
||||
BunextAPIRouteHandler,
|
||||
} from "@moduletrace/bunext/types";
|
||||
|
||||
/**
|
||||
* A bot's core instructions, for its edit form in the conversation, which
|
||||
* loads them when it opens (page props leave them out). For super admins
|
||||
* and admins; only the super admin reaches the coordinator.
|
||||
*/
|
||||
export const handler: BunextAPIRouteHandler<
|
||||
APIResponseObject<{ system_prompt: string }>
|
||||
> = async ({ req, body }) => {
|
||||
try {
|
||||
if (req.method != "POST") {
|
||||
throw new AppError(`Method not allowed`);
|
||||
}
|
||||
|
||||
const { user, user_types } = await userAuth({ req });
|
||||
|
||||
if (!user?.logged_in_status || !user.id) {
|
||||
return { success: false, msg: `Unauthorized`, logoutUser: true };
|
||||
}
|
||||
|
||||
if (!canManageCrew({ user_types })) {
|
||||
throw new AppError(`Only an admin can edit a bot.`);
|
||||
}
|
||||
|
||||
const { bot_id } = parseWithSchema({ schema: BotIdRequestSchema, data: body });
|
||||
const bot = await grabUserBot({ bot_id, user_id: user.id });
|
||||
|
||||
if (!bot?.id) {
|
||||
throw new AppError(`Bot not found.`);
|
||||
}
|
||||
|
||||
return { success: true, singleRes: { system_prompt: bot.system_prompt || "" } };
|
||||
} catch (error: unknown) {
|
||||
return { success: false, msg: safeErrorMessage({ error }) };
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
import userAuth from "@/src/functions/backend/auth/user-auth";
|
||||
import grabUserBotSession from "@/src/functions/backend/db/bot-sessions/grab-user-bot-session";
|
||||
import grabBotMessages from "@/src/functions/backend/db/bots/grab-bot-messages";
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import { OlderBotMessagesRequestSchema } from "@/src/schemas/bot-schema";
|
||||
import type { OlderBotMessagesData } from "@/src/types";
|
||||
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";
|
||||
|
||||
/**
|
||||
* The messages before `before_id` in one of the session user's own
|
||||
* sessions, `AppData.ConversationOlderMessages` at a time, for the thread
|
||||
* scrolled to its top.
|
||||
*/
|
||||
export const handler: BunextAPIRouteHandler<
|
||||
APIResponseObject<OlderBotMessagesData>
|
||||
> = async ({ req, body }) => {
|
||||
try {
|
||||
if (req.method != "POST") {
|
||||
throw new AppError(`Method not allowed`);
|
||||
}
|
||||
|
||||
const { user } = await userAuth({ req });
|
||||
|
||||
if (!user?.logged_in_status || !user.id) {
|
||||
return { success: false, msg: `Unauthorized`, logoutUser: true };
|
||||
}
|
||||
|
||||
const { session_id, before_id } = parseWithSchema({
|
||||
schema: OlderBotMessagesRequestSchema,
|
||||
data: body,
|
||||
});
|
||||
|
||||
const session = await grabUserBotSession({ session_id, user_id: user.id });
|
||||
|
||||
if (!session?.id) {
|
||||
throw new AppError(`Session not found.`);
|
||||
}
|
||||
|
||||
const messages = await grabBotMessages({
|
||||
session_id: session.id,
|
||||
before_id,
|
||||
limit: AppData.ConversationOlderMessages + 1,
|
||||
user_id: user.id,
|
||||
});
|
||||
const has_more = messages.length > AppData.ConversationOlderMessages;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
singleRes: { messages: has_more ? messages.slice(1) : messages, has_more },
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
return { success: false, msg: safeErrorMessage({ error }) };
|
||||
}
|
||||
};
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
APIResponseObject,
|
||||
BunextAPIRouteHandler,
|
||||
} from "@moduletrace/bunext/types";
|
||||
import railBots from "@/src/utils/rail-bots";
|
||||
|
||||
/**
|
||||
* The crew's workers that aren't in a workspace yet, for the workspace
|
||||
@@ -48,9 +49,11 @@ export const handler: BunextAPIRouteHandler<APIResponseObject<BotWithLastMessage
|
||||
|
||||
return {
|
||||
success: true,
|
||||
payload: bots.filter(
|
||||
(bot) => bot.kind != "coordinator" && !members.some((member) => member.id == bot.id),
|
||||
),
|
||||
payload: railBots({
|
||||
bots: bots.filter(
|
||||
(bot) => bot.kind != "coordinator" && !members.some((member) => member.id == bot.id),
|
||||
),
|
||||
}),
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
return { success: false, msg: safeErrorMessage({ error }) };
|
||||
|
||||
Reference in New Issue
Block a user