feat: add EN/ES/RO language selector for AI pitch generation
- db.py: add `language` column to ai_queue; migration; queue_ai() accepts language param and re-queues with ON CONFLICT UPDATE so changing language works - main.py: batch and single assess endpoints accept `language` from request body - enricher.py: ai_worker_loop reads language column, passes to _assess_one() - replicate_ai.py: assess_domain() and _build_prompt() accept language param; OUTPUT LANGUAGE section injected into prompt so Gemini writes pitch/email in the requested language (EN/ES/RO) - index.html: flag dropdown (🇪🇸/🇬🇧/🇷🇴) next to AI Assess button; aiLang state default ES; language sent in all batch assessment requests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -343,6 +343,11 @@ tr:hover td{background:rgba(255,255,255,.025)}
|
||||
<button class="btn bs" @click="enqueueSelected()" :disabled="selected.length===0">
|
||||
+ Enrich (<span x-text="selected.length"></span>)
|
||||
</button>
|
||||
<select x-model="aiLang" style="padding:4px 8px;border-radius:6px;border:1px solid var(--border);background:var(--card);color:var(--text);font-size:13px;cursor:pointer" title="Pitch language">
|
||||
<option value="ES">🇪🇸 ES</option>
|
||||
<option value="EN">🇬🇧 EN</option>
|
||||
<option value="RO">🇷🇴 RO</option>
|
||||
</select>
|
||||
<button class="btn bai" @click="aiAssessSelected()" :disabled="selected.length===0">
|
||||
🤖 AI Assess (<span x-text="selected.length"></span>)
|
||||
</button>
|
||||
@@ -550,7 +555,7 @@ function app() {
|
||||
tab: 'browse',
|
||||
stats: {}, indexSt: {ready:false,building:false,total:0},
|
||||
aiSt: {pending:0,running:0,done:0,failed:0,total:0},
|
||||
domains: [], selected: [],
|
||||
domains: [], selected: [], aiLang: 'ES',
|
||||
loading: false, page: 1, searchTotal: 0,
|
||||
f: {tld:'',keyword:'',min_score:0,cms:'',live_only:false,alpha_only:false,no_sld:false,kit_digital_only:false,limit:'100'},
|
||||
qst: {}, customDomains: '',
|
||||
@@ -633,9 +638,9 @@ function app() {
|
||||
|
||||
async aiAssessSelected() {
|
||||
if(!this.selected.length) return;
|
||||
const r = await fetch('/api/ai/assess/batch',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({domains:this.selected})});
|
||||
const r = await fetch('/api/ai/assess/batch',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({domains:this.selected,language:this.aiLang})});
|
||||
const d = await r.json();
|
||||
r.ok ? this.notify(`Queued ${d.queued} for AI assessment`,'info') : this.notify('Error: '+d.error,'error');
|
||||
r.ok ? this.notify(`Queued ${d.queued} for AI assessment [${this.aiLang}]`,'info') : this.notify('Error: '+d.error,'error');
|
||||
this.selected = [];
|
||||
},
|
||||
|
||||
@@ -644,9 +649,9 @@ function app() {
|
||||
const r = await fetch('/api/enriched?kit_digital=true&limit=500').then(r=>r.json());
|
||||
const domains = r.results.map(d=>d.domain);
|
||||
if(!domains.length) { this.notify('No Kit Digital domains enriched yet','info'); return; }
|
||||
const r2 = await fetch('/api/ai/assess/batch',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({domains})});
|
||||
const r2 = await fetch('/api/ai/assess/batch',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({domains,language:this.aiLang})});
|
||||
const d2 = await r2.json();
|
||||
this.notify(`Queued ${d2.queued} Kit Digital domains for AI assessment`,'info');
|
||||
this.notify(`Queued ${d2.queued} Kit Digital domains for AI assessment [${this.aiLang}]`,'info');
|
||||
},
|
||||
|
||||
async enqueueCustom() {
|
||||
|
||||
Reference in New Issue
Block a user