Finish the mobile performance pass

- Cache the model catalog once per user and each conversation's setting
  separately; clear both on logout and after model saves
- Compress hashed assets asynchronously with a byte budget and set Vary
- Memoize message parsing and throttle selection reads
- Debounce draft writes to localStorage
- Keep the composer editor on the page and focused, as before
- Add a bundle budget check and run it in CI
- Show a loading block while sessions load and a workspace avatar in the
  mobile conversation header
This commit is contained in:
2026-10-20 14:37:11 +01:00
parent c1a94fc9a5
commit 4f7e0a6bf0
38 changed files with 1320 additions and 334 deletions
+7 -6
View File
@@ -1,8 +1,8 @@
import userAuth from "@/src/functions/backend/auth/user-auth";
import grabUserConversation from "@/src/functions/backend/db/bot-sessions/grab-user-conversation";
import grabConversationHarnessOverview from "@/src/functions/backend/db/harness/grab-conversation-harness-overview";
import grabConversationHarnessSettings from "@/src/functions/backend/db/harness/grab-conversation-harness-settings";
import { BotConversationRequestSchema } from "@/src/schemas/bot-schema";
import type { BotHarnessOverviewPayload } from "@/src/types";
import type { BotHarnessSettingsPayload } from "@/src/types";
import AppError from "@/src/utils/app-error";
import parseWithSchema from "@/src/utils/parse-with-schema";
import canManageCrew from "@/src/utils/rbac/can-manage-crew";
@@ -14,12 +14,13 @@ import type {
} from "@moduletrace/bunext/types";
/**
* What a conversation's models modal edits, loaded when it opens: the
* What a conversation's models form edits, loaded when it opens: the
* coordinator's defaults (super admins), or a worker's or the workspace's
* models (super admins and admins).
* models (super admins and admins). The install-wide catalog comes from
* `api/admin/harness/catalog`, so it is cached once rather than per bot.
*/
export const handler: BunextAPIRouteHandler<
APIResponseObject<BotHarnessOverviewPayload>
APIResponseObject<BotHarnessSettingsPayload>
> = async ({ req, body }) => {
try {
if (req.method != "POST") {
@@ -50,7 +51,7 @@ export const handler: BunextAPIRouteHandler<
return {
success: true,
singleRes: await grabConversationHarnessOverview({
singleRes: await grabConversationHarnessSettings({
bot: conversation.bot,
workspace_id: scope,
}),