File size: 2,169 Bytes
f39e265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9d8bbd6
f39e265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Langfuse tracing.

Tracing is strictly optional: if the Langfuse keys are absent or the service is
unreachable, the app logs a warning and keeps working untraced. Observability
must never be able to take the application down.
"""

import logging

from config import get_settings

logger = logging.getLogger(__name__)

_handler = None
_initialised = False


def _init():
    global _handler, _initialised
    if _initialised:
        return
    _initialised = True

    settings = get_settings(require_api_key=False)
    if not settings.tracing_enabled:
        logger.info("Langfuse tracing disabled (LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY not set).")
        return

    try:
        from langfuse import Langfuse
        from langfuse.langchain import CallbackHandler

        Langfuse(
            public_key=settings.langfuse_public_key,
            secret_key=settings.langfuse_secret_key,
            host=settings.langfuse_host,
        )
        _handler = CallbackHandler()
        logger.info("Langfuse tracing enabled (%s).", settings.langfuse_host)
    except Exception as exc:
        logger.warning("Langfuse tracing unavailable, continuing without it: %s", exc)


def get_callbacks():
    """Callback list for LangChain/LangGraph config. Empty when tracing is off."""
    _init()
    return [_handler] if _handler else []


def build_run_config(thread_id, job_description):
    """Runnable config: checkpoint thread plus Langfuse trace metadata."""
    return {
        "configurable": {"thread_id": thread_id},
        "callbacks": get_callbacks(),
        "run_name": "job_chat_qa",
        "metadata": {
            "langfuse_session_id": thread_id,
            "langfuse_tags": ["job-chat", "with-jd" if job_description else "no-jd"],
            "jd_loaded": bool(job_description),
            "jd_words": len(job_description.split()) if job_description else 0,
        },
    }


def flush():
    """Flush pending traces before shutdown."""
    if not _handler:
        return
    try:
        from langfuse import get_client

        get_client().flush()
    except Exception as exc:
        logger.warning("Langfuse flush failed: %s", exc)