feat(CC-054): smart AnythingLLM routing by country/type (RO/DE/FR/UK/EU)

This commit is contained in:
admin-valentin 2026-08-01 19:00:28 +00:00
parent 1570e69b2d
commit 2e7e0c85ea

View file

@ -1,6 +1,6 @@
import { BadGatewayException, Injectable } from '@nestjs/common';
const TIMEOUT_MS = 10_000;
const TIMEOUT_MS = 15_000;
async function jsonFetch<T>(url: string, opts: RequestInit = {}): Promise<T> {
const ctrl = new AbortController();
@ -21,25 +21,38 @@ async function jsonFetch<T>(url: string, opts: RequestInit = {}): Promise<T> {
}
}
/**
* Mapare țară workspace AnythingLLM.
* Fiecare workspace conține corpusul legal/fiscal al jurisdicției respective.
*/
const COUNTRY_WORKSPACE: Record<string, string> = {
RO: 'agent-juridic-romania',
DE: 'national-germania',
'DE-fiscal': 'fiscal-germania',
'RO-fiscal': 'fiscal-romania',
FR: 'national-franta',
'FR-fiscal': 'fiscal-franta',
UK: 'national-uk',
'UK-fiscal': 'fiscal-uk',
EU: 'agent-juridic-romania', // fallback general
};
@Injectable()
export class ExternalDataService {
/** ceo-os-legislation-api: vector search over imported legislation corpus */
/** ceo-os-legislation-api: RAG vector search direct în corpus legislativ */
private readonly legislationUrl =
process.env.LEGISLATION_API_URL ?? 'http://91.98.39.120:9404';
/** AnythingLLM: AI-interpreted legislation answers via agent workspace */
private readonly anythingLlmUrl =
process.env.ANYTHINGLLM_URL ?? 'http://152.53.112.35:3010';
process.env.ANYTHINGLLM_URL ??
'http://anythingllm-n3n3xi75sj0xkh3oey17n962.91.98.39.120.sslip.io';
private readonly anythingLlmKey =
process.env.ANYTHINGLLM_API_KEY ?? '';
private readonly legislationWorkspace =
process.env.ANYTHINGLLM_LEGISLATION_WORKSPACE ?? 'legislation';
/**
* Raw vector search: returns matching legislation sections (fast, no AI).
* The 'scenario' field must be a full situation description, not just a keyword.
* Vector search în corpusul legislativ returnează secțiuni text brut.
* 'scenario' trebuie fie o descriere completă a situației (nu keyword).
*/
async searchLegislation(scenario: string, country?: string, topK = 8) {
return jsonFetch(`${this.legislationUrl}/search_legislation`, {
@ -49,22 +62,34 @@ export class ExternalDataService {
}
/**
* AI-interpreted legislation answer via AnythingLLM agent workspace.
* Returns a conversational answer grounded in the legislation corpus.
* Răspuns AI interpretat via agent AnythingLLM.
* Rutare automată pe workspace-ul potrivit după țară și tip.
*/
async askLegislationAgent(message: string, sessionId?: string) {
async askLegislationAgent(
message: string,
country = 'RO',
type: 'general' | 'fiscal' | 'national' = 'general',
sessionId?: string,
) {
if (!this.anythingLlmKey) {
throw new BadGatewayException('ANYTHINGLLM_API_KEY not configured');
}
const key = type === 'fiscal' ? `${country}-fiscal` : country;
const workspace =
COUNTRY_WORKSPACE[key] ??
COUNTRY_WORKSPACE[country] ??
'agent-juridic-romania';
return jsonFetch(
`${this.anythingLlmUrl}/api/v1/workspace/${this.legislationWorkspace}/chat`,
`${this.anythingLlmUrl}/api/v1/workspace/${workspace}/chat`,
{
method: 'POST',
headers: { Authorization: `Bearer ${this.anythingLlmKey}` },
body: JSON.stringify({
message,
mode: 'chat',
sessionId: sessionId ?? 'ceo-os-legislation',
sessionId: sessionId ?? `ceo-os-${country}-${Date.now()}`,
attachments: [],
}),
},