File size: 3,147 Bytes
01543cd
333cede
 
 
01543cd
333cede
 
 
 
 
01543cd
333cede
 
 
01543cd
333cede
 
01543cd
 
 
333cede
 
 
 
 
 
01543cd
333cede
01543cd
333cede
01543cd
 
 
 
 
333cede
 
01543cd
333cede
 
01543cd
333cede
 
01543cd
 
333cede
 
 
 
01543cd
333cede
 
01543cd
333cede
 
 
01543cd
333cede
 
 
01543cd
333cede
01543cd
333cede
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
01543cd
333cede
01543cd
333cede
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""Load and process FAQ data from a JSON file."""
import json
import logging
from pathlib import Path
from typing import Any

logger = logging.getLogger(__name__)


class FAQEntry:
    """Representation of a single FAQ entry."""

    def __init__(self, formulation: str, theme: str, response: str) -> None:
        """

        Initialize an FAQ entry.



        Args:

            formulation: The FAQ question text.

            theme: The FAQ theme or category.

            response: The associated response.

        """
        self.formulation: str = formulation
        self.theme: str = theme
        self.response: str = response


def load_faq_data(json_path: str) -> list[FAQEntry]:
    """

    Load FAQ data from a JSON file.



    The JSON payload is expected to contain an "intents" array. For each intent

    with enabled=True, a FAQEntry is created from:

    - formulation: the utterances list

    - theme: the intent_key

    - response: the response text



    Args:

        json_path: Path to the JSON file containing FAQ intents.



    Returns:

        A list of FAQEntry objects with formulation, theme, and response.



    Raises:

        FileNotFoundError: If the JSON file does not exist.

        ValueError: If the JSON is empty or malformed.

    """
    path = Path(json_path)

    if not path.exists():
        raise FileNotFoundError(f"File not found: {json_path}")

    try:
        logger.info(f"Loading FAQ data from JSON: {json_path}")
        with path.open("r", encoding="utf-8") as handle:
            payload: dict[str, Any] = json.load(handle)
    except json.JSONDecodeError as exc:
        raise ValueError(f"Invalid JSON payload: {exc}") from exc

    intents = payload.get("intents")
    if not isinstance(intents, list):
        raise ValueError("The JSON payload does not contain a valid 'intents' list")

    faq_entries: list[FAQEntry] = []
    for intent in intents:
        if not isinstance(intent, dict):
            continue

        enabled = intent.get("enabled", False)
        if not enabled:
            continue

        utterances = intent.get("utterances")
        if not isinstance(utterances, list) or not utterances:
            continue

        intent_key = intent.get("intent_key")
        response = intent.get("response")
        if not isinstance(intent_key, str) or not intent_key.strip():
            continue
        if not isinstance(response, str) or not response.strip():
            continue

        for formulation in utterances:
            if not isinstance(formulation, str) or not formulation.strip():
                continue

            faq_entries.append(
                FAQEntry(
                    formulation=formulation.strip(),
                    theme=intent_key.strip(),
                    response=response.strip(),
                )
            )

    if not faq_entries:
        raise ValueError("No valid FAQ entries were found in the JSON payload")

    logger.info(f"✓ {len(faq_entries)} FAQ entries loaded successfully from JSON")
    return faq_entries