Spaces:
Sleeping
Sleeping
| 'use client'; | |
| import { useEffect, useMemo, useRef, useState } from 'react'; | |
| import { Modal } from 'antd'; | |
| import type { CreateRoleReq } from '@/service/role'; | |
| import { useLoadInfoStore } from '@/store/useLoadInfoStore'; | |
| interface CreateRoleModalProps { | |
| open: boolean; | |
| onClose: () => void; | |
| onSubmit: (data: CreateRoleReq) => Promise<void>; | |
| loading?: boolean; | |
| } | |
| export default function CreateRoleModal({ | |
| open, | |
| onClose, | |
| onSubmit, | |
| loading = false | |
| }: CreateRoleModalProps) { | |
| const [l0Enabled, setL0Enabled] = useState(true); | |
| const [name, setName] = useState(''); | |
| const [description, setDescription] = useState(''); | |
| const promptChangeRef = useRef<boolean>(false); | |
| const loadInfo = useLoadInfoStore((state) => state.loadInfo); | |
| const userName = useMemo(() => { | |
| return loadInfo?.name || 'user'; | |
| }, [loadInfo]); | |
| const originPrompt = useMemo(() => { | |
| return `You are ${userName}'s 'Second Me,' a personalized AI created by ${userName}. You act as ${userName}'s representative, engaging with others on ${userName}'s behalf. | |
| Currently, you are interacting with an external user in the role of an ${name || '{{role}}'}. | |
| Your responsibility is ${description || '{{responsibility}}'}.`; | |
| }, [userName, name, description]); | |
| const [systemPrompt, setSystemPrompt] = useState(originPrompt); | |
| useEffect(() => { | |
| if (!promptChangeRef.current) { | |
| setSystemPrompt(originPrompt); | |
| } | |
| }, [originPrompt]); | |
| const init = () => { | |
| setName(''); | |
| setDescription(''); | |
| setSystemPrompt(originPrompt); | |
| setL0Enabled(true); | |
| promptChangeRef.current = false; | |
| }; | |
| useEffect(() => { | |
| if (!open) { | |
| init(); | |
| } | |
| }, [open]); | |
| const handleSubmit = async () => { | |
| await onSubmit({ | |
| name, | |
| description, | |
| system_prompt: systemPrompt, | |
| icon: '', | |
| enable_l0_retrieval: l0Enabled | |
| }); | |
| }; | |
| return ( | |
| <Modal | |
| cancelButtonProps={{ disabled: loading }} | |
| cancelText="Cancel" | |
| centered | |
| destroyOnClose | |
| okButtonProps={{ loading }} | |
| okText="Create" | |
| onCancel={onClose} | |
| onOk={handleSubmit} | |
| open={open} | |
| title="Create Role" | |
| > | |
| <div className="space-y-4"> | |
| <div> | |
| <label className="block text-sm font-medium text-gray-700 mb-1">Role Name</label> | |
| <input | |
| className="w-full px-3 py-2 border rounded-lg" | |
| onChange={(e) => setName(e.target.value)} | |
| placeholder="e.g., Historical Figure, Professional Expert, etc." | |
| type="text" | |
| value={name} | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-sm font-medium text-gray-700 mb-1">Role Description</label> | |
| <textarea | |
| className="w-full px-3 py-2 border rounded-lg" | |
| onChange={(e) => setDescription(e.target.value)} | |
| placeholder="Describe the role's personality, background, and expertise..." | |
| rows={3} | |
| value={description} | |
| /> | |
| </div> | |
| <div> | |
| <label className="block text-sm font-medium text-gray-700 mb-1"> | |
| System Prompt{' '} | |
| <span className="text-gray-500 text-xs"> | |
| (make sure to replace role & responsility) | |
| </span> | |
| </label> | |
| <textarea | |
| className="w-full px-3 py-2 border rounded-lg" | |
| onChange={(e) => { | |
| setSystemPrompt(e.target.value); | |
| promptChangeRef.current = true; | |
| }} | |
| placeholder="Enter the system prompt that defines how this role should behave..." | |
| rows={10} | |
| value={systemPrompt} | |
| /> | |
| </div> | |
| <div className="space-y-4"> | |
| <div className="flex items-center justify-between"> | |
| <div> | |
| <label className="font-medium">Memory Retrieval</label> | |
| <p className="text-sm text-gray-500">Direct and factual responses</p> | |
| </div> | |
| <button | |
| className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${l0Enabled ? 'bg-blue-600' : 'bg-gray-200'}`} | |
| onClick={() => { | |
| setL0Enabled((prev) => !prev); | |
| }} | |
| > | |
| <span | |
| className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${l0Enabled ? 'translate-x-[25px]' : 'translate-x-1'}`} | |
| /> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </Modal> | |
| ); | |
| } | |