system prompt client global and project

This commit is contained in:
Storme-bit
2026-04-19 02:57:11 -07:00
parent a0154e15e6
commit fa3b0859f0
4 changed files with 144 additions and 44 deletions
@@ -6,6 +6,7 @@ export default function ProjectModal({ project, mode, onSave, onDelete, onClose
const [name, setName] = useState(project?.name ?? '');
const [description, setDescription] = useState(project?.description ?? '');
const [colour, setColour] = useState(project?.colour ?? COLOURS[0]);
const [systemPrompt, setSystemPrompt] = useState(project?.system_prompt ?? '');
const inputRef = useRef(null);
useEffect(() => {
@@ -15,13 +16,20 @@ export default function ProjectModal({ project, mode, onSave, onDelete, onClose
function handleSubmit() {
const trimmed = name.trim();
if (!trimmed) return;
onSave({ name: trimmed, description: description.trim() || null, colour, icon: null, isolated: 1 });
onSave({
name: trimmed,
description: description.trim() || null,
colour,
icon: null,
isolated: 1,
system_prompt: systemPrompt.trim() || null,
});
onClose();
}
function handleKeyDown(e) {
if (e.key === 'Enter' && mode !== 'confirm-delete') handleSubmit();
if (e.key === 'Escape') onClose();
// Don't submit on Enter — textarea fields make Enter ambiguous
}
return (
@@ -35,7 +43,8 @@ export default function ProjectModal({ project, mode, onSave, onDelete, onClose
background: 'var(--bg-surface)',
border: '1px solid var(--border)',
borderRadius: 'var(--radius-lg)',
padding: '24px', width: '380px',
padding: '24px', width: '420px',
maxHeight: '90vh', overflowY: 'auto',
display: 'flex', flexDirection: 'column', gap: '16px',
}}>
{mode === 'confirm-delete' ? (
@@ -122,6 +131,32 @@ export default function ProjectModal({ project, mode, onSave, onDelete, onClose
</div>
</div>
{/* System Prompt */}
<div className="flex-col" style={{ gap: '6px' }}>
<label className="label-upper">
System Prompt <span style={{ opacity: 0.5 }}>(optional)</span>
</label>
<p className="text-xs text-muted" style={{ marginTop: '-2px' }}>
Overrides the global system prompt for conversations in this project.
Leave blank to use the global default.
</p>
<textarea
value={systemPrompt}
onChange={e => setSystemPrompt(e.target.value)}
placeholder="You are a helpful assistant specialised in..."
rows={4}
style={{
background: 'var(--bg-elevated)', border: '1px solid var(--border)',
borderRadius: 'var(--radius-md)', padding: '8px 12px',
color: 'var(--text-primary)', fontSize: '13px', outline: 'none',
width: '100%', resize: 'vertical', fontFamily: 'inherit',
lineHeight: '1.6',
}}
onFocus={e => e.target.style.borderColor = 'var(--accent)'}
onBlur={e => e.target.style.borderColor = 'var(--border)'}
/>
</div>
<div className="flex" style={{ gap: '8px', justifyContent: 'flex-end' }}>
<button className="btn-reset text-base text-muted"
onClick={onClose}