Let crew managers edit a bot's workspace instructions where they work with it
A bot's instructions and memory for one workspace were only reachable
from the workspace's settings. The editor is now shared and also opens
from the conversation menu in that workspace ("Instructions here",
loaded on open through api/admin/workspaces/workspace-bot) and from the
workspace rows on the bot's settings page.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { useState } from "react";
|
||||
import Form from "@moduletrace/twui/form/Form";
|
||||
import CodeEditor from "@/src/components/general/code-editor";
|
||||
import type { WorkspaceBot } from "@/src/types";
|
||||
import postAdminApi from "@/src/layouts/bots/(functions)/post-admin-api";
|
||||
import AddFormActions from "@/src/layouts/bots/(partials)/add-form-actions";
|
||||
|
||||
type Props = {
|
||||
workspace_id: number;
|
||||
bot_id: number;
|
||||
bot_name?: string | null;
|
||||
/**
|
||||
* What the bot has for this workspace now.
|
||||
*/
|
||||
system_prompt?: string | null;
|
||||
memory?: string | null;
|
||||
onCancel: () => void;
|
||||
/**
|
||||
* After the save, with the workspace's crew as it is now.
|
||||
*/
|
||||
onSaved: (bots: WorkspaceBot[]) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* The form for what one bot has for a workspace alone: its instructions
|
||||
* there, on top of its own, and its memory there
|
||||
* (`api/admin/workspaces/update-bot`, crew managers). It asks first.
|
||||
*/
|
||||
export default function WorkspaceBotForm({
|
||||
workspace_id,
|
||||
bot_id,
|
||||
bot_name,
|
||||
system_prompt: initial_prompt,
|
||||
memory: initial_memory,
|
||||
onCancel,
|
||||
onSaved,
|
||||
}: Props) {
|
||||
const [system_prompt, setSystemPrompt] = useState(initial_prompt || "");
|
||||
const [memory, setMemory] = useState(initial_memory || "");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string>();
|
||||
|
||||
const submit = async () => {
|
||||
if (loading) return;
|
||||
if (!window.confirm(`Save ${bot_name || "this bot"}'s instructions and memory here?`)) return;
|
||||
|
||||
setLoading(true);
|
||||
setError(undefined);
|
||||
|
||||
const res = await postAdminApi<WorkspaceBot>({
|
||||
path: "workspaces/update-bot",
|
||||
body: { workspace_id, bot_id, system_prompt, memory },
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
|
||||
if (!res.success) {
|
||||
setError(res.msg || "Couldn't save.");
|
||||
return;
|
||||
}
|
||||
|
||||
onSaved(res.payload || []);
|
||||
};
|
||||
|
||||
return (
|
||||
<Form className="w-full gap-4! items-stretch pt-4" onSubmit={submit}>
|
||||
<CodeEditor
|
||||
mode="markdown"
|
||||
className="h-44"
|
||||
title="Instructions here"
|
||||
content={system_prompt}
|
||||
placeholder="In this workspace, write for the marketing team: short, plain, no jargon."
|
||||
onChange={(value) => setSystemPrompt(value)}
|
||||
/>
|
||||
<CodeEditor
|
||||
mode="markdown"
|
||||
className="h-32"
|
||||
title="Memory here"
|
||||
content={memory}
|
||||
info="What it must remember in this workspace."
|
||||
onChange={(value) => setMemory(value)}
|
||||
/>
|
||||
<AddFormActions submit_label="Save" loading={loading} error={error} onCancel={onCancel} />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { WorkspaceBot } from "@/src/types";
|
||||
import AddModalShell from "@/src/layouts/bots/(partials)/add-modal-shell";
|
||||
import WorkspaceBotForm from "./workspace-bot-form";
|
||||
|
||||
type Props = {
|
||||
workspace_id: number;
|
||||
workspace_name?: string | null;
|
||||
bot_id: number;
|
||||
bot_name?: string | null;
|
||||
/**
|
||||
* What the bot has for this workspace now.
|
||||
*/
|
||||
system_prompt?: string | null;
|
||||
memory?: string | null;
|
||||
onClose: () => void;
|
||||
onSaved: (bots: WorkspaceBot[]) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* What one bot has for this workspace alone: instructions on top of its
|
||||
* own, and its memory here. The bot rewrites both as it learns; the
|
||||
* coordinator can set the instructions too. Opened from the workspace's
|
||||
* settings and from the bot's.
|
||||
*/
|
||||
export default function WorkspaceBotModal({
|
||||
workspace_id,
|
||||
workspace_name,
|
||||
bot_id,
|
||||
bot_name,
|
||||
system_prompt,
|
||||
memory,
|
||||
onClose,
|
||||
onSaved,
|
||||
}: Props) {
|
||||
const name = bot_name || "This bot";
|
||||
|
||||
return (
|
||||
<AddModalShell
|
||||
open
|
||||
setOpen={(open) => !open && onClose()}
|
||||
title={`${name} in ${workspace_name || "this workspace"}`}
|
||||
description={`${name} keeps its own instructions and memory everywhere. These apply only here, and it updates them itself as it learns how this workspace works.`}
|
||||
>
|
||||
<WorkspaceBotForm
|
||||
workspace_id={workspace_id}
|
||||
bot_id={bot_id}
|
||||
bot_name={bot_name}
|
||||
system_prompt={system_prompt}
|
||||
memory={memory}
|
||||
onCancel={onClose}
|
||||
onSaved={(bots) => {
|
||||
onSaved(bots);
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
</AddModalShell>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user