Download source/src/PromptBuilder.tsx from CladeTeam/ouroboros: direct link, hf CLI and curl.
- Browser
- Download file 4.18 kB
-
https://huggingface.co/spaces/CladeTeam/ouroboros/resolve/main/source/src/PromptBuilder.tsx
- Command line
-
hf download hf://spaces/CladeTeam/ouroboros/source/src/PromptBuilder.tsx
-
curl -L -o PromptBuilder.tsx https://huggingface.co/spaces/CladeTeam/ouroboros/resolve/main/source/src/PromptBuilder.tsx
4.18 kB
| import {useState} from 'react'; | |
| import presetData from './promptPresets.json'; | |
| const presets=presetData.map(p=>({...p,fields:Object.fromEntries(Object.entries(p.fields).filter((entry):entry is [string,string]=>typeof entry[1]==='string'))})); | |
| export const FIELDS=['similarity','function','subunit','catalytic activity','pathway','cofactor','tissue specificity','domain','subcellular location','PTM','miscellaneous','induction','disruption phenotype','activity regulation','developmental stage','sequence caution','caution','biophysicochemical properties','disease','alternative products','online information','biotechnology','polymorphism','mass spectrometry','allergen','toxic dose','RNA editing','pharmaceutical','interaction']; | |
| const hints:Record<string,string>={similarity:'e.g. Belongs to the MurCDEF family.',function:'e.g. Cell wall formation.',subunit:'e.g. Homodimer.','catalytic activity':'Describe the reaction catalyzed by the protein.',cofactor:'e.g. Binds 1 zinc ion.',pathway:'e.g. Peptidoglycan biosynthesis.','subcellular location':'e.g. Cytoplasm.'}; | |
| export const assemblePrompt=(fields:Record<string,string>)=>FIELDS.map(f=>(fields[f]||'').trim()).filter(Boolean).join(''); | |
| export function PromptBuilder({fields,setFields,onApply,busy,input}:{fields:Record<string,string>;setFields:(f:Record<string,string>)=>void;onApply:(text:string)=>void;busy:boolean;input:string}){ | |
| const [extra,setExtra]=useState('catalytic activity'); | |
| const shown=FIELDS.filter(f=>f==='similarity'||f==='function'||f in fields); | |
| const available=FIELDS.filter(f=>!shown.includes(f)); | |
| const selected=available.includes(extra)?extra:available[0]||''; | |
| const assembled=assemblePrompt(fields); | |
| const preset=presets.find(p=>assemblePrompt(p.fields as Record<string,string>)===assembled); | |
| const choose=(p:typeof presets[number])=>{const next={...p.fields} as Record<string,string>;setFields(next);onApply(assemblePrompt(next));}; | |
| return <div className="prompt-builder"> | |
| <div className="builder-heading"><span className="micro">BUILD YOUR PROMPT</span><span className="builder-optional">Start from annotations or an example</span></div> | |
| <div className="preset-choices" role="group" aria-label="Annotation examples">{presets.map(p=><button key={p.id} disabled={busy} aria-pressed={preset?.id===p.id} onClick={()=>choose(p)}>{p.title}<span>↗</span></button>)}</div> | |
| <div className="preset-caption"><span>{preset?`Original demo example · ${preset.id}`:'Editable examples from the original demo'}</span><button className="text-button" disabled={busy} onClick={()=>{const options=presets.filter(p=>p.id!==preset?.id);choose(options[Math.floor(Math.random()*options.length)]);}}>Surprise me ↻</button></div> | |
| <div className="annotation-fields">{shown.map(f=><div className="annotation-field" key={f}><div><label htmlFor={'annotation-'+f}>{f}</label>{!['similarity','function'].includes(f)&&<button disabled={busy} aria-label={'Remove '+f} onClick={()=>{const next={...fields};delete next[f];setFields(next);}}>×</button>}</div><textarea id={'annotation-'+f} rows={f==='function'?3:2} value={fields[f]||''} disabled={busy} onChange={e=>setFields({...fields,[f]:e.target.value})} placeholder={hints[f]||`Add ${f} information…`}/></div>)}</div> | |
| <div className="annotation-actions">{available.length>0&&<div className="annotation-add"><label className="sr-only" htmlFor="annotation-key">Annotation type</label><select id="annotation-key" value={selected} disabled={busy} onChange={e=>setExtra(e.target.value)}>{available.map(f=><option key={f}>{f}</option>)}</select><button className="small-button" disabled={busy} onClick={()=>setFields({...fields,[selected]:''})}>+ Add field</button></div>}<button className="text-button" disabled={busy||!Object.keys(fields).length} onClick={()=>setFields({})}>Clear fields</button></div> | |
| <div className="builder-apply"><span aria-live="polite">{!assembled?'Fill any fields you need.':assembled===input?'These annotations are in the prompt below.':'Build the prompt to use your edited annotations.'}</span><button className="small-button" disabled={busy||!assembled} onClick={()=>onApply(assembled)}>Build prompt ↓</button></div> | |
| </div>; | |
| } | |