feat: CIS number in embeddings, tenancy dropdown in consult, text filter for exact CIS search

- Chunk findings CSV: includes CIS Recommendation number, Section, Status in document header
- Consult embeddings: tenancy dropdown (OCI config selector) for filtered search
- CIS number detection: regex extracts "cis X.Y" from query → TEXT LIKE filter for exact match
- Dynamic top_k: 10 per table when CIS filter active (vs 3 default), 15 global results
- Vector search text_filter: combined vector similarity + TEXT LIKE for precise results
- Purged 121174 legacy docs without tenancy metadata from all CIS tables
- Re-embedded 4364 docs across 7 tables with full CIS metadata
- GPT-5.2 for consult (was GPT-4.1), max_tokens 8000
This commit is contained in:
nogueiraguh
2026-03-24 22:12:15 -03:00
parent a2a9fda6c7
commit c6b7cd75a9
3 changed files with 94 additions and 34 deletions

View File

@@ -88,10 +88,11 @@ export const embeddingsApi = {
}) as unknown as Promise<PurgeResult>,
/** Consult embeddings with a question */
consult: (query: string, tableName?: string, topK = 10) =>
consult: (query: string, tableName?: string, topK = 10, ociConfigId?: string) =>
client.post('/embeddings/consult', {
query,
table_name: tableName || '',
top_k: topK,
oci_config_id: ociConfigId || '',
}) as unknown as Promise<ConsultResult>,
};

View File

@@ -39,10 +39,11 @@ function renderMarkdown(text: string): string {
/* ── Main ── */
export default function EmbConsultPage() {
const { t } = useI18n();
const { adbCfg } = useAppStore();
const { adbCfg, ociCfg } = useAppStore();
// Config selectors
const [selTable, setSelTable] = useState('');
const [selOci, setSelOci] = useState(ociCfg.length > 0 ? ociCfg[0].id : '');
const [topK, setTopK] = useState(10);
// Chat
@@ -101,7 +102,7 @@ export default function EmbConsultPage() {
setLoading(true);
try {
const d = await embeddingsApi.consult(q, selTable || undefined, topK);
const d = await embeddingsApi.consult(q, selTable || undefined, topK, selOci || undefined);
let answer = d.answer || t('ec.noAnswer');
const assistantMsg: ChatMessage = {
@@ -162,6 +163,20 @@ export default function EmbConsultPage() {
{/* Config bar */}
<div className="flex gap-3 flex-wrap flex-shrink-0">
<div className="min-w-[160px]">
<label className="block text-[.68rem] font-semibold mb-1" style={{ color: 'var(--t4)' }}>Tenancy</label>
<select
value={selOci}
onChange={(e) => setSelOci(e.target.value)}
className="w-full px-3 py-1.5 rounded-lg text-[.76rem] outline-none"
style={{ background: 'var(--bg1)', border: '1px solid var(--bd)', color: 'var(--t1)' }}
>
<option value="">Todas</option>
{ociCfg.map((c) => (
<option key={c.id} value={c.id}>{c.tenancy_name}</option>
))}
</select>
</div>
<div className="flex-1 min-w-[180px]">
<label className="block text-[.68rem] font-semibold mb-1" style={{ color: 'var(--t4)' }}>{t('ec.tableOptional')}</label>
<select