feat(frontend): embed prompt dynamic variables section
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Braces,
|
||||
Bot,
|
||||
Brain,
|
||||
Database,
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
import { DebugDrawer } from "@/components/assistant-editor/debug-preview";
|
||||
import {
|
||||
DynamicVariableEditorHint,
|
||||
DynamicVariablesDialog,
|
||||
DynamicVariablesSection,
|
||||
} from "@/components/assistant-editor/dynamic-variables";
|
||||
import {
|
||||
AssistantIdentity,
|
||||
@@ -43,6 +44,7 @@ const promptSections = [
|
||||
{ id: "models", label: "模型与语音" },
|
||||
{ id: "capabilities", label: "知识与工具" },
|
||||
{ id: "interaction", label: "交互策略" },
|
||||
{ id: "variables", label: "动态变量" },
|
||||
] as const;
|
||||
|
||||
type PromptSectionId = (typeof promptSections)[number]["id"];
|
||||
@@ -50,7 +52,6 @@ type PromptSectionId = (typeof promptSections)[number]["id"];
|
||||
type PromptEditorProps = {
|
||||
assistantId: string | null;
|
||||
form: AssistantForm;
|
||||
dynamicVariablesOpen: boolean;
|
||||
dynamicVariableDefinitions: Record<string, DynamicVariableDefinition>;
|
||||
saving: boolean;
|
||||
dirty: boolean;
|
||||
@@ -64,7 +65,6 @@ type PromptEditorProps = {
|
||||
tools: Tool[];
|
||||
onBack: () => void;
|
||||
onSave: () => void;
|
||||
setDynamicVariablesOpen: (open: boolean) => void;
|
||||
updateForm: <K extends keyof AssistantForm>(
|
||||
key: K,
|
||||
value: AssistantForm[K],
|
||||
@@ -76,7 +76,6 @@ type PromptEditorProps = {
|
||||
export function PromptEditor({
|
||||
assistantId,
|
||||
form,
|
||||
dynamicVariablesOpen,
|
||||
dynamicVariableDefinitions,
|
||||
saving,
|
||||
dirty,
|
||||
@@ -90,7 +89,6 @@ export function PromptEditor({
|
||||
tools,
|
||||
onBack,
|
||||
onSave,
|
||||
setDynamicVariablesOpen,
|
||||
updateForm,
|
||||
handlePromptVisionEnabledChange,
|
||||
handlePromptModelChange,
|
||||
@@ -102,6 +100,7 @@ export function PromptEditor({
|
||||
models: null,
|
||||
capabilities: null,
|
||||
interaction: null,
|
||||
variables: null,
|
||||
});
|
||||
const selectedAnchorRef = useRef<PromptSectionId | null>(null);
|
||||
const [activeSection, setActiveSection] =
|
||||
@@ -217,7 +216,7 @@ export function PromptEditor({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="-mt-6 flex h-full flex-col gap-4">
|
||||
<div className="-mt-6 flex h-full flex-col gap-4 overflow-hidden bg-background">
|
||||
<div className="flex shrink-0 items-center justify-between gap-6 border-b border-hairline pb-3 pt-1">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<EditorBackButton onClick={onBack} />
|
||||
@@ -249,25 +248,13 @@ export function PromptEditor({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DynamicVariablesDialog
|
||||
open={dynamicVariablesOpen}
|
||||
onOpenChange={setDynamicVariablesOpen}
|
||||
definitions={dynamicVariableDefinitions}
|
||||
onChange={(dynamicVariableDefinitions) =>
|
||||
updateForm(
|
||||
"dynamicVariableDefinitions",
|
||||
dynamicVariableDefinitions,
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="flex min-h-0 flex-1 gap-4">
|
||||
<div className="flex min-h-0 min-w-0 flex-1 flex-col gap-3">
|
||||
<nav
|
||||
aria-label="提示词配置分区"
|
||||
className="shrink-0 overflow-x-auto"
|
||||
className="shrink-0 overflow-x-auto overscroll-none"
|
||||
>
|
||||
<div className="grid min-w-[22rem] grid-cols-4 border-b border-hairline">
|
||||
<div className="grid min-w-[28rem] grid-cols-5 border-b border-hairline">
|
||||
{promptSections.map((section) => {
|
||||
const active = activeSection === section.id;
|
||||
|
||||
@@ -293,7 +280,7 @@ export function PromptEditor({
|
||||
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
className="scrollbar-subtle min-h-0 min-w-0 flex-1 space-y-3 overflow-y-auto pr-1"
|
||||
className="scrollbar-subtle min-h-0 min-w-0 flex-1 space-y-3 overflow-y-auto overscroll-none bg-background pr-1"
|
||||
>
|
||||
<section
|
||||
ref={(element) => {
|
||||
@@ -314,7 +301,7 @@ export function PromptEditor({
|
||||
/>
|
||||
<DynamicVariableEditorHint
|
||||
count={Object.keys(dynamicVariableDefinitions).length}
|
||||
onOpen={() => setDynamicVariablesOpen(true)}
|
||||
onOpen={() => scrollToSection("variables")}
|
||||
/>
|
||||
</SectionCard>
|
||||
|
||||
@@ -330,7 +317,7 @@ export function PromptEditor({
|
||||
/>
|
||||
<DynamicVariableEditorHint
|
||||
count={Object.keys(dynamicVariableDefinitions).length}
|
||||
onOpen={() => setDynamicVariablesOpen(true)}
|
||||
onOpen={() => scrollToSection("variables")}
|
||||
/>
|
||||
{form.runtimeMode === "pipeline" && (
|
||||
<div className="mt-4 space-y-3 border-t border-hairline pt-4">
|
||||
@@ -550,6 +537,29 @@ export function PromptEditor({
|
||||
)}
|
||||
</SectionCard>
|
||||
</section>
|
||||
|
||||
<section
|
||||
ref={(element) => {
|
||||
sectionRefs.current.variables = element;
|
||||
}}
|
||||
className="scroll-mt-3 space-y-3"
|
||||
>
|
||||
<SectionCard
|
||||
icon={<Braces size={15} />}
|
||||
title="动态变量"
|
||||
description="编辑提示词和开场白中引用的自定义变量"
|
||||
>
|
||||
<DynamicVariablesSection
|
||||
definitions={dynamicVariableDefinitions}
|
||||
onChange={(dynamicVariableDefinitions) =>
|
||||
updateForm(
|
||||
"dynamicVariableDefinitions",
|
||||
dynamicVariableDefinitions,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</SectionCard>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user