File size: 1,790 Bytes
8b3905d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
LangGraph multi-agent orchestration for SentinelAI.

Compiles a small state machine that mirrors enrich → detect → correlate stages.
"""

from __future__ import annotations

from typing import Any

try:
    from langgraph.graph import END, StateGraph
except ImportError:  # pragma: no cover
    StateGraph = None  # type: ignore[misc, assignment]
    END = None  # type: ignore[misc, assignment]


def build_soc_graph(handlers: dict[str, Any]):
    """handlers: optional async callables enrich/detect/correlate receiving mutable state dict."""

    if StateGraph is None or END is None:
        return None

    graph = StateGraph(dict)

    async def enrich_node(state: dict[str, Any]) -> dict[str, Any]:
        fn = handlers.get("enrich")
        if fn:
            await fn(state)
        notes = list(state.get("notes", []))
        notes.append("enrich_complete")
        return {**state, "notes": notes}

    async def detect_node(state: dict[str, Any]) -> dict[str, Any]:
        fn = handlers.get("detect")
        if fn:
            await fn(state)
        notes = list(state.get("notes", []))
        notes.append("detect_complete")
        return {**state, "notes": notes}

    async def correlate_node(state: dict[str, Any]) -> dict[str, Any]:
        fn = handlers.get("correlate")
        if fn:
            await fn(state)
        notes = list(state.get("notes", []))
        notes.append("correlate_complete")
        return {**state, "notes": notes}

    graph.add_node("enrich", enrich_node)
    graph.add_node("detect", detect_node)
    graph.add_node("correlate", correlate_node)
    graph.set_entry_point("enrich")
    graph.add_edge("enrich", "detect")
    graph.add_edge("detect", "correlate")
    graph.add_edge("correlate", END)
    return graph.compile()