Edit the prompt appendix as markdown, bump twui

The install-wide appendix now uses the shared CodeEditor (AceEditor,
markdown mode) instead of a plain textarea, discarding by remounting the
editor with the saved text. The storage quota field moves to the twui
0.1.6 number input, so the dependency is bumped with it.
This commit is contained in:
2026-10-22 11:23:36 +01:00
parent 16f1e7904a
commit 080f8e9abc
4 changed files with 35 additions and 17 deletions
@@ -21,7 +21,11 @@ export default function StorageQuotaForm({ storage }: Props) {
const [dirty, setDirty] = useState(false);
const [value, setValue] = useState(String(storage?.quota_mb ?? ""));
const [loading, setLoading] = useState(false);
const [status, setStatus] = useState<{ msg?: string; error?: boolean; success?: boolean }>();
const [status, setStatus] = useState<{
msg?: string;
error?: boolean;
success?: boolean;
}>();
const save = async () => {
setLoading(true);
@@ -35,14 +39,20 @@ export default function StorageQuotaForm({ storage }: Props) {
setLoading(false);
if (!res?.success || !res.singleRes) {
setStatus({ error: true, msg: res?.msg || `Couldn't save the quota.` });
setStatus({
error: true,
msg: res?.msg || `Couldn't save the quota.`,
});
return;
}
setOverview(res.singleRes);
setValue(String(res.singleRes.quota_mb));
setDirty(false);
setStatus({ success: true, msg: `Saved: ${res.singleRes.quota_mb} MB per folder.` });
setStatus({
success: true,
msg: `Saved: ${res.singleRes.quota_mb} MB per folder.`,
});
};
return (
@@ -58,13 +68,16 @@ export default function StorageQuotaForm({ storage }: Props) {
label="Megabytes per folder"
type="number"
min={0}
step={1}
value={value}
step={8}
numberText
rawNumber
defaultValue={value}
onChange={(event) => {
setValue(event.target.value);
setDirty(true);
setStatus(undefined);
}}
suffix={`MB`}
info="A bot's own folder and each workspace's folder each get this much. A write past it is refused, so the bot clears space first."
/>
{overview ? (
@@ -2,9 +2,9 @@ import { useState } from "react";
import fetchApi from "@moduletrace/twui/utils/fetch/fetchApi";
import type { APIResponseObject } from "@moduletrace/bunext/types";
import Form from "@moduletrace/twui/form/Form";
import Textarea from "@moduletrace/twui/form/Textarea";
import Span from "@moduletrace/twui/layout/Span";
import Stack from "@moduletrace/twui/layout/Stack";
import CodeEditor from "@/src/components/general/code-editor";
import { AppData } from "@/src/data/app-data";
import type { SystemPromptAppendOverview } from "@/src/functions/backend/db/app-settings/grab-system-prompt-append";
import SettingsSaveBar from "../../(partials)/settings-save-bar";
@@ -21,6 +21,11 @@ export default function SystemPromptAppendForm({ appendix }: Props) {
const [overview, setOverview] = useState(appendix || undefined);
const [dirty, setDirty] = useState(false);
const [value, setValue] = useState(appendix?.text ?? "");
/**
* The editor only reads `content` when it mounts, so a discard remounts
* it with the saved text.
*/
const [editor_key, setEditorKey] = useState(0);
const [loading, setLoading] = useState(false);
const [status, setStatus] = useState<{ msg?: string; error?: boolean; success?: boolean }>();
@@ -60,16 +65,15 @@ export default function SystemPromptAppendForm({ appendix }: Props) {
className="w-full gap-3! items-stretch"
>
<Stack className="w-full gap-1! items-stretch">
<Textarea
id="system-prompt-append"
label="Appendix"
<CodeEditor
key={`appendix-${editor_key}`}
mode="markdown"
className="h-52"
title="Appendix"
showLabel
rows={6}
placeholder={"Never invent sources.\nAlways say which computer a task ran on."}
value={value}
onChange={(event) => {
setValue(event.target.value);
content={value}
onChange={(next) => {
setValue(next);
setDirty(true);
setStatus(undefined);
}}
@@ -86,6 +90,7 @@ export default function SystemPromptAppendForm({ appendix }: Props) {
save_label="Save appendix"
onDiscard={() => {
setValue(overview?.text ?? "");
setEditorKey((prev) => prev + 1);
setDirty(false);
setStatus(undefined);
}}