{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Hawksight-AI/semantica/blob/main/cookbook/use_cases/supply_chain/01_Supply_Chain_Data_Integration.ipynb)\n",
        "\n",
        "# Supply Chain Data Integration - Multi-Source Ingestion & Relationship Mapping\n",
        "\n",
        "## Overview\n",
        "\n",
        "This notebook demonstrates **supply chain data integration** using Semantica with focus on **multi-source ingestion**, **relationship mapping**, and **logistics tracking**. The pipeline ingests logistics and supplier data from multiple sources to build a comprehensive supply chain knowledge graph with supplier network analysis.\n",
        "\n",
        "### Key Features\n",
        "\n",
        "- **Multi-Source Ingestion**: Ingests data from multiple logistics and supplier sources (RSS, web APIs, files)\n",
        "- **Relationship Mapping**: Maps supplier relationships and logistics routes using relation extraction\n",
        "- **Logistics Tracking**: Tracks products, routes, locations, and warehouses\n",
        "- **Supplier Network Analysis**: Analyzes supplier centrality and community clusters\n",
        "- **Seed Data Integration**: Uses supplier foundation data for entity resolution\n",
        "- **KG Construction**: Builds comprehensive supply chain knowledge graphs\n",
        "\n",
        "### Learning Objectives\n",
        "\n",
        "- Understand how to ingest data from multiple sources for supply chain integration\n",
        "- Learn to map complex supplier relationships and logistics routes\n",
        "- Master supplier network analysis using centrality and community detection\n",
        "- Explore relationship extraction for supply chain entities\n",
        "- Practice multi-source data integration and deduplication\n",
        "- Analyze supplier networks and logistics connections\n",
        "\n",
        "### Pipeline Flow\n",
        "\n",
        "```mermaid\n",
        "graph TD\n",
        "    A[Multi-Source Ingestion] --> B[Seed Data Loading]\n",
        "    A --> C[Document Parsing]\n",
        "    B --> D[Text Processing]\n",
        "    C --> D\n",
        "    D --> E[Entity Extraction]\n",
        "    E --> F[Relationship Extraction]\n",
        "    F --> G[Deduplication]\n",
        "    G --> H[KG Construction]\n",
        "    H --> I[Embedding Generation]\n",
        "    I --> J[Vector Store]\n",
        "    H --> K[Network Analysis]\n",
        "    H --> L[Community Detection]\n",
        "    J --> M[GraphRAG Queries]\n",
        "    K --> N[Visualization]\n",
        "    L --> N\n",
        "    H --> O[Export]\n",
        "```\n",
        "\n",
        "\n",
        "---\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Note: you may need to restart the kernel to use updated packages.\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "WARNING: Ignoring invalid distribution ~gno (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~lotly (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~ython-socketio (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~gno (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~lotly (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~ython-socketio (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~gno (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~lotly (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
            "WARNING: Ignoring invalid distribution ~ython-socketio (c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n"
          ]
        }
      ],
      "source": [
        "%pip install -qU semantica networkx matplotlib plotly pandas faiss-cpu beautifulsoup4 groq sentence-transformers scikit-learn\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Configuration & Setup\n",
        "\n",
        "Configure API keys and set up constants for the supply chain data integration pipeline.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "\n",
        "os.environ[\"GROQ_API_KEY\"] = os.getenv(\"GROQ_API_KEY\", \"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\")\n",
        "\n",
        "# Configuration constants\n",
        "EMBEDDING_DIMENSION = 384\n",
        "EMBEDDING_MODEL = \"sentence-transformers/all-MiniLM-L6-v2\"\n",
        "CHUNK_SIZE = 1000\n",
        "CHUNK_OVERLAP = 200\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Multi-Source Data Ingestion\n",
        "\n",
        "Ingest supply chain data from multiple sources including RSS feeds, web APIs, and local files. This section emphasizes multi-source ingestion capabilities.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Ingesting from 7 RSS feed sources...\n",
            "🧠 Semantica is ingesting: File: supply_chain.txt 🔄📥 (0.0s) | 🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.supplychaindive.com/rss ❌📥 (1.6s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch feed https://www.supplychaindive.com/rss: 404 Client Error: Not Found for url: https://www.supplychaindive.com/rss\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [1/7] Supply Chain Dive: Failed - Failed to fetch feed: 404 Client Error: Not Found \n",
            "🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.supplychaindive.com/rss ❌📥 (1.6s) | 🧠 Semantica is ingesting: 403 Client Error: Forbidden for url: https://www.logisticsmgmt.com/rss ❌📥 (1.4s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch feed https://www.logisticsmgmt.com/rss: 403 Client Error: Forbidden for url: https://www.logisticsmgmt.com/rss\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [2/7] Logistics Management: Failed - Failed to fetch feed: 403 Client Error: Forbidden \n",
            "🧠 Semantica is ingesting: 403 Client Error: Forbidden for url: https://www.logisticsmgmt.com/rss ❌📥 (1.4s) | 🧠 Semantica is ingesting: 403 Client Error: Forbidden for url: https://www.scmr.com/rss ❌📥 (1.3s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch feed https://www.scmr.com/rss: 403 Client Error: Forbidden for url: https://www.scmr.com/rss\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [3/7] SCMR: Failed - Failed to fetch feed: 403 Client Error: Forbidden \n",
            "🧠 Semantica is ingesting: 403 Client Error: Forbidden for url: https://www.scmr.com/rss ❌📥 (1.3s) | 🧠 Semantica is ingesting: Ingested 30 items |███████████████| 100.0% ✅📥  [4/7] DC Velocity: 30 documents\n",
            "🧠 Semantica is ingesting: Ingested 30 items |███████████████| 100.0% ✅📥 | 🧠 Semantica is ingesting: 403 Client Error: Forbidden for url: https://www.inboundlogistics.com/rss ❌📥 (0.9s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch feed https://www.inboundlogistics.com/rss: 403 Client Error: Forbidden for url: https://www.inboundlogistics.com/rss\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [5/7] Inbound Logistics: Failed - Failed to fetch feed: 403 Client Error: Forbidden \n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to parse feed: not well-formed (invalid token): line 53, column 49\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is ingesting: 403 Client Error: Forbidden for url: https://www.inboundlogistics.com/rss ❌📥 (0.9s) | 🧠 Semantica is ingesting: Failed to parse feed: not well-formed (invalid token): line 53, column 49 ❌📥 (1.7s)  [6/7] Supply Chain Brain: Failed - Failed to parse feed: not well-formed (invalid tok\n",
            "🧠 Semantica is ingesting: Failed to parse feed: not well-formed (invalid token): line 53, column 49 ❌📥 (1.7s) | 🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.mhlnews.com/rss ❌📥 (1.1s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch feed https://www.mhlnews.com/rss: 404 Client Error: Not Found for url: https://www.mhlnews.com/rss\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [7/7] MHL News: Failed - Failed to fetch feed: 404 Client Error: Not Found \n",
            "\n",
            "Ingesting from 4 web sources...\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "URL https://www.supplychaindive.com/news blocked by robots.txt\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.mhlnews.com/rss ❌📥 (1.1s) | 🧠 Semantica is ingesting: URL blocked by robots.txt: https://www.supplychaindive.com/news ❌📥 (0.2s)  [1/4] Supply Chain Dive News: Failed - URL blocked by robots.txt: https://www.supplychain\n",
            "🧠 Semantica is ingesting: URL blocked by robots.txt: https://www.supplychaindive.com/news ❌📥 (0.2s) | 🧠 Semantica is ingesting: Ingested https://www.logisticsmgmt.com/news (200) |███████████████| 100.0% ✅📥  [2/4] Logistics Management News: 1 document\n",
            "🧠 Semantica is ingesting: Ingested https://www.logisticsmgmt.com/news (200) |███████████████| 100.0% ✅📥 | 🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.scmr.com/articles ❌📥 (3.6s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch URL https://www.scmr.com/articles: 404 Client Error: Not Found for url: https://www.scmr.com/articles\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [3/4] SCMR Articles: Failed - Failed to fetch URL: 404 Client Error: Not Found f\n",
            "🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.scmr.com/articles ❌📥 (3.6s) | 🧠 Semantica is ingesting: 404 Client Error: Not Found for url: https://www.dcvelocity.com/articles ❌📥 (1.5s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Failed to fetch URL https://www.dcvelocity.com/articles: 404 Client Error: Not Found for url: https://www.dcvelocity.com/articles\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "  [4/4] DC Velocity Articles: Failed - Failed to fetch URL: 404 Client Error: Not Found f\n",
            "\n",
            "Ingested 31 documents from multiple sources\n"
          ]
        }
      ],
      "source": [
        "from semantica.ingest import FeedIngestor, WebIngestor, FileIngestor\n",
        "import os\n",
        "\n",
        "os.makedirs(\"data\", exist_ok=True)\n",
        "\n",
        "documents = []\n",
        "\n",
        "# Ingest from logistics RSS feeds\n",
        "logistics_feeds = [\n",
        "    (\"Supply Chain Dive\", \"https://www.supplychaindive.com/rss\"),\n",
        "    (\"Logistics Management\", \"https://www.logisticsmgmt.com/rss\"),\n",
        "    (\"SCMR\", \"https://www.scmr.com/rss\"),\n",
        "    (\"DC Velocity\", \"https://www.dcvelocity.com/rss\"),\n",
        "    (\"Inbound Logistics\", \"https://www.inboundlogistics.com/rss\"),\n",
        "    (\"Supply Chain Brain\", \"https://www.supplychainbrain.com/rss\"),\n",
        "    (\"MHL News\", \"https://www.mhlnews.com/rss\")\n",
        "]\n",
        "\n",
        "feed_ingestor = FeedIngestor()\n",
        "print(f\"Ingesting from {len(logistics_feeds)} RSS feed sources...\")\n",
        "for i, (feed_name, feed_url) in enumerate(logistics_feeds, 1):\n",
        "    try:\n",
        "        feed_data = feed_ingestor.ingest_feed(feed_url, validate=False)\n",
        "        feed_count = 0\n",
        "        for item in feed_data.items:\n",
        "            if not item.content:\n",
        "                item.content = item.description or item.title or \"\"\n",
        "            if item.content:\n",
        "                if not hasattr(item, 'metadata'):\n",
        "                    item.metadata = {}\n",
        "                item.metadata['source'] = feed_name\n",
        "                documents.append(item)\n",
        "                feed_count += 1\n",
        "        if feed_count > 0:\n",
        "            print(f\"  [{i}/{len(logistics_feeds)}] {feed_name}: {feed_count} documents\")\n",
        "    except Exception as e:\n",
        "        print(f\"  [{i}/{len(logistics_feeds)}] {feed_name}: Failed - {str(e)[:50]}\")\n",
        "\n",
        "# Web ingestion from supply chain data sources\n",
        "web_sources = [\n",
        "    (\"Supply Chain Dive News\", \"https://www.supplychaindive.com/news\"),\n",
        "    (\"Logistics Management News\", \"https://www.logisticsmgmt.com/news\"),\n",
        "    (\"SCMR Articles\", \"https://www.scmr.com/articles\"),\n",
        "    (\"DC Velocity Articles\", \"https://www.dcvelocity.com/articles\")\n",
        "]\n",
        "\n",
        "web_ingestor = WebIngestor(respect_robots=True, delay=1.0)\n",
        "print(f\"\\nIngesting from {len(web_sources)} web sources...\")\n",
        "for i, (source_name, web_url) in enumerate(web_sources, 1):\n",
        "    try:\n",
        "        web_content = web_ingestor.ingest_url(web_url)\n",
        "        if web_content.text:\n",
        "            # Create a document-like object from WebContent\n",
        "            class WebDoc:\n",
        "                def __init__(self, content, title, url, source):\n",
        "                    self.content = content\n",
        "                    self.title = title\n",
        "                    self.url = url\n",
        "                    self.metadata = {'source': source}\n",
        "            doc = WebDoc(web_content.text, web_content.title, web_content.url, source_name)\n",
        "            documents.append(doc)\n",
        "            print(f\"  [{i}/{len(web_sources)}] {source_name}: 1 document\")\n",
        "    except Exception as e:\n",
        "        print(f\"  [{i}/{len(web_sources)}] {source_name}: Failed - {str(e)[:50]}\")\n",
        "\n",
        "print(f\"\\nIngested {len(documents)} documents from multiple sources\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": []
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loaded seed data with 17 entities\n",
            "Entity types: {'Supplier', 'Warehouse', 'Product', 'Location', 'Route'}\n"
          ]
        }
      ],
      "source": [
        "from semantica.seed import SeedDataManager\n",
        "\n",
        "seed_manager = SeedDataManager()\n",
        "\n",
        "# Load supplier foundation seed data\n",
        "supplier_foundation = {\n",
        "    \"suppliers\": [\"Supplier A\", \"Supplier B\", \"Supplier C\", \"Global Suppliers Inc\"],\n",
        "    \"warehouses\": [\"Warehouse W1\", \"Warehouse W2\", \"Warehouse W3\"],\n",
        "    \"locations\": [\"City C1\", \"City C2\", \"Region R1\", \"Region R2\"],\n",
        "    \"products\": [\"Product X\", \"Product Y\", \"Product Z\"],\n",
        "    \"routes\": [\"Route R1\", \"Route R2\", \"Route R3\"]\n",
        "}\n",
        "\n",
        "# Convert dictionary to entity records\n",
        "entity_records = []\n",
        "for entity_type, entity_names in supplier_foundation.items():\n",
        "    for name in entity_names:\n",
        "        entity_records.append({\n",
        "            \"id\": name.replace(\" \", \"_\").lower(),\n",
        "            \"text\": name,\n",
        "            \"name\": name,\n",
        "            \"entity_type\": entity_type.rstrip(\"s\").capitalize(),  # Remove plural and capitalize\n",
        "            \"type\": entity_type.rstrip(\"s\").capitalize(),\n",
        "            \"source\": \"supplier_foundation\",\n",
        "            \"verified\": True\n",
        "        })\n",
        "\n",
        "# Add entities to seed data\n",
        "seed_manager.seed_data.entities = entity_records\n",
        "\n",
        "print(f\"Loaded seed data with {len(entity_records)} entities\")\n",
        "print(f\"Entity types: {set(e['type'] for e in entity_records)}\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Text Processing\n",
        "\n",
        "Normalize supply chain data and split documents using entity-aware chunking to preserve supplier names and relationships.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 504 entities using ml |███████████████| 100.0% ✅🎯██████████| 100.0% ✅🔧Processed 115 entity-aware chunks\n"
          ]
        }
      ],
      "source": [
        "from semantica.normalize import TextNormalizer\n",
        "from semantica.split import TextSplitter\n",
        "\n",
        "normalizer = TextNormalizer()\n",
        "normalized_docs = []\n",
        "\n",
        "for doc in documents:\n",
        "    try:\n",
        "        doc_content = doc.content if hasattr(doc, 'content') else str(doc)\n",
        "        normalized = normalizer.normalize(\n",
        "            doc_content,\n",
        "            clean_html=True,\n",
        "            normalize_entities=True,\n",
        "            normalize_numbers=True,\n",
        "            remove_extra_whitespace=True\n",
        "        )\n",
        "        normalized_docs.append(normalized)\n",
        "    except Exception:\n",
        "        normalized_docs.append(doc.content if hasattr(doc, 'content') else str(doc))\n",
        "\n",
        "# Use entity-aware chunking to preserve supplier names and relationships\n",
        "entity_splitter = TextSplitter(\n",
        "    method=\"entity_aware\",\n",
        "    chunk_size=CHUNK_SIZE,\n",
        "    chunk_overlap=CHUNK_OVERLAP\n",
        ")\n",
        "\n",
        "chunked_docs = []\n",
        "for doc_text in normalized_docs:\n",
        "    try:\n",
        "        chunks = entity_splitter.split(doc_text)\n",
        "        chunked_docs.extend([chunk.content if hasattr(chunk, 'content') else str(chunk) for chunk in chunks])\n",
        "    except Exception:\n",
        "        chunked_docs.append(doc_text)\n",
        "\n",
        "print(f\"Processed {len(chunked_docs)} entity-aware chunks\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Extracting entities from 115 chunks using ML-based approach...\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 5/115 chunks (0 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 10/115 chunks (0 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 1 entities using ml |███████████████| 100.0% ✅🎯  Processed 15/115 chunks (5 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 20/115 chunks (5 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 25/115 chunks (5 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 1 entities using ml |███████████████| 100.0% ✅🎯  Processed 30/115 chunks (8 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 35/115 chunks (16 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 1 entities using ml |███████████████| 100.0% ✅🎯  Processed 40/115 chunks (18 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 45/115 chunks (18 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 50/115 chunks (20 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 55/115 chunks (20 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 60/115 chunks (21 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 65/115 chunks (23 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 2 entities using ml |███████████████| 100.0% ✅🎯  Processed 70/115 chunks (28 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 1 entities using ml |███████████████| 100.0% ✅🎯  Processed 75/115 chunks (33 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 80/115 chunks (37 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 6 entities using ml |███████████████| 100.0% ✅🎯  Processed 85/115 chunks (45 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 90/115 chunks (50 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 1 entities using ml |███████████████| 100.0% ✅🎯  Processed 95/115 chunks (66 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 100/115 chunks (68 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯  Processed 105/115 chunks (68 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯100.0% ✅🎯  Processed 110/115 chunks (87 entities found)\n",
            "🧠 Semantica is normalizing |███████████████| 100.0% ✅🔧 | 🧠 Semantica is extracting: Extracted 0 entities |███████████████| 100.0% ✅🎯00.0% ✅🎯  Processed 115/115 chunks (89 entities found)\n",
            "Extracted 89 entities\n"
          ]
        }
      ],
      "source": [
        "from semantica.semantic_extract import NERExtractor\n",
        "\n",
        "# Use ML-based approach (spaCy) for entity extraction\n",
        "extractor = NERExtractor(\n",
        "    method=\"ml\",\n",
        "    model=\"en_core_web_sm\"\n",
        ")\n",
        "\n",
        "entity_types = [\n",
        "    \"Supplier\", \"Product\", \"Route\", \"Location\", \"Logistics\", \"Warehouse\", \"Makinson\"\n",
        "]\n",
        "\n",
        "all_entities = []\n",
        "chunks_to_process = chunked_docs  # Process all chunks\n",
        "print(f\"Extracting entities from {len(chunks_to_process)} chunks using ML-based approach...\")\n",
        "for i, chunk in enumerate(chunks_to_process, 1):\n",
        "    try:\n",
        "        entities = extractor.extract(\n",
        "            chunk,\n",
        "            entity_types=entity_types\n",
        "        )\n",
        "        all_entities.extend(entities)\n",
        "    except Exception as e:\n",
        "        print(f\"  Error processing chunk {i}: {str(e)[:50]}\")\n",
        "        pass\n",
        "    \n",
        "    if i % 5 == 0 or i == len(chunks_to_process):\n",
        "        print(f\"  Processed {i}/{len(chunks_to_process)} chunks ({len(all_entities)} entities found)\")\n",
        "\n",
        "print(f\"Extracted {len(all_entities)} entities\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Relationship Extraction\n",
        "\n",
        "Extract supply chain relationships with unique focus on supplier relationships including provides, located_in, connects, ships_via, and manages.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Extracting relationships from 115 chunks using ML-based approach...\n",
            "🧠 Semantica is extracting: Extracted 15 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 5/115 chunks (1 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 50 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯�  Processed 10/115 chunks (3 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 51 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 15/115 chunks (5 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 6 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯�  Processed 20/115 chunks (6 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 41 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯�  Processed 25/115 chunks (9 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 33 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 30/115 chunks (11 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 5 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯�█████| 100.0% ✅🎯�  Processed 35/115 chunks (14 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 16 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 2 relations using dependency |███████████████| 100.0% ✅🎯  Processed 40/115 chunks (16 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 11 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯████| 100.0% ✅🎯�  Processed 45/115 chunks (18 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 9 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯�  Processed 50/115 chunks (20 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 42 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 55/115 chunks (22 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 4 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯�█████| 100.0% ✅🎯�  Processed 60/115 chunks (26 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 16 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯  Processed 65/115 chunks (26 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 58 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 2 relations using dependency |███████████████| 100.0% ✅🎯�  Processed 70/115 chunks (31 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 81 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 75/115 chunks (33 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 4 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯��  Processed 80/115 chunks (43 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 150 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 85/115 chunks (54 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 25 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 1 relations using dependency |███████████████| 100.0% ✅🎯  Processed 90/115 chunks (59 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 69 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 1 relations using dependency |███████████████| 100.0% ✅🎯  Processed 95/115 chunks (61 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 51 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 100/115 chunks (63 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 47 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯  Processed 105/115 chunks (64 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 36 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯�  Processed 110/115 chunks (69 relationships found)\n",
            "🧠 Semantica is extracting: Extracted 38 entities using ml |███████████████| 100.0% ✅🎯 | 🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯█████| 100.0% ✅🎯�  Processed 115/115 chunks (72 relationships found)\n",
            "Extracted 72 relationships\n"
          ]
        }
      ],
      "source": [
        "from semantica.semantic_extract import RelationExtractor, NERExtractor\n",
        "\n",
        "# Use ML-based approach (dependency parsing with spaCy) for relation extraction\n",
        "relation_extractor = RelationExtractor(\n",
        "    method=\"dependency\",  # ML-based dependency parsing\n",
        "    model=\"en_core_web_sm\"\n",
        ")\n",
        "\n",
        "# Create NER extractor once for efficiency\n",
        "ner = NERExtractor(method=\"ml\", model=\"en_core_web_sm\")\n",
        "\n",
        "relation_types = [\n",
        "    \"provides\", \"located_in\", \"connects\",\n",
        "    \"ships_via\", \"manages\"\n",
        "]\n",
        "\n",
        "all_relationships = []\n",
        "chunks_to_process = chunked_docs  # Process all chunks\n",
        "print(f\"Extracting relationships from {len(chunks_to_process)} chunks using ML-based approach...\")\n",
        "for i, chunk in enumerate(chunks_to_process, 1):\n",
        "    try:\n",
        "        # Extract entities from chunk first (dependency parsing needs entities)\n",
        "        chunk_entities = ner.extract(chunk)\n",
        "        \n",
        "        # Extract relationships using dependency parsing\n",
        "        relationships = relation_extractor.extract(\n",
        "            chunk,\n",
        "            entities=chunk_entities,\n",
        "            relation_types=relation_types\n",
        "        )\n",
        "        all_relationships.extend(relationships)\n",
        "    except Exception as e:\n",
        "        print(f\"  Error processing chunk {i}: {str(e)[:50]}\")\n",
        "        pass\n",
        "    \n",
        "    if i % 5 == 0 or i == len(chunks_to_process):\n",
        "        print(f\"  Processed {i}/{len(chunks_to_process)} chunks ({len(all_relationships)} relationships found)\")\n",
        "\n",
        "print(f\"Extracted {len(all_relationships)} relationships\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Conflict Detection\n",
        "\n",
        "Detect and resolve conflicts in supply chain data from multiple sources. Supply chain sources have different credibility levels.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is extracting: Extracted 0 relations |███████████████| 100.0% ✅🎯 | 🧠 Semantica is resolving: Detected 0 relationship conflicts |███████████████| 100.0% [64/68] ✅⚠️ (192.2/s)/68] 🔄⚠️ (ETA: 0.0s | 197.3/s))20.7/s))Detected 0 conflicts\n"
          ]
        }
      ],
      "source": [
        "from semantica.conflicts import ConflictDetector, ConflictResolver\n",
        "\n",
        "detector = ConflictDetector()\n",
        "resolver = ConflictResolver()\n",
        "\n",
        "entity_dicts = [{\"id\": e.text, \"text\": e.text, \"type\": e.label, \"confidence\": e.confidence, \"metadata\": e.metadata} for e in all_entities]\n",
        "relationship_dicts = [{\"id\": f\"{r.subject.text}_{r.predicate}_{r.object.text}\", \"source_id\": r.subject.text, \"target_id\": r.object.text, \"type\": r.predicate, \"confidence\": r.confidence, \"metadata\": r.metadata} for r in all_relationships] if all_relationships else []\n",
        "\n",
        "conflicts = detector.detect_entity_conflicts(entity_dicts)\n",
        "if relationship_dicts:\n",
        "    conflicts.extend(detector.detect_relationship_conflicts(relationship_dicts))\n",
        "\n",
        "print(f\"Detected {len(conflicts)} conflicts\")\n",
        "if conflicts:\n",
        "    resolver.resolve_conflicts(conflicts, strategy=\"credibility_weighted\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Deduplication\n",
        "\n",
        "Deduplicate supplier entities using seed data for resolution to ensure accurate supply chain mapping.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is deduplicating: Merging groups... 1/1 (remaining: 0) |███████████████| 100.0% [1/1] 🔄🔄 (0.5/s) | 🧠 Semantica is deduplicating: Building merged entity... (4/4, remaining: 0 steps) |███████████████| 100.0% [4/4] 🔄🔄 (221.2/s)) 🔄🔄 (ETA: 0.0s | 233.7/s)333.9/s)Deduplicated 89 entities to 15 unique entities\n"
          ]
        }
      ],
      "source": [
        "from semantica.kg import EntityResolver\n",
        "from semantica.semantic_extract import Entity\n",
        "\n",
        "entity_dicts = [{\"name\": e.text, \"type\": e.label, \"confidence\": e.confidence} for e in all_entities]\n",
        "resolved = EntityResolver(strategy=\"fuzzy\", similarity_threshold=0.85).resolve_entities(entity_dicts)\n",
        "all_entities = [Entity(text=e[\"name\"], label=e[\"type\"], start_char=0, end_char=0, confidence=e.get(\"confidence\", 1.0)) for e in resolved]\n",
        "print(f\"Deduplicated {len(entity_dicts)} entities to {len(all_entities)} unique entities\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Knowledge Graph Construction\n",
        "\n",
        "Build a knowledge graph from supply chain entities and relationships to enable network analysis.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is deduplicating: Building merged entity... (4/4, remaining: 0 steps) |███████████████| 100.0% [4/4] 🔄🔄 (221.2/s) | 🧠 Semantica is building: Processing relationships... 72/72 |███████████████| 100.0% [72/72] 🔄🧠 (23237.1/s)Building graph structure...\n",
            "✅ Graph structure built (0.00s)\n",
            "🧠 Semantica is deduplicating: Building merged entity... (4/4, remaining: 0 steps) |███████████████| 100.0% [4/4] 🔄🔄 (221.2/s) | 🧠 Semantica is building: Processing relationships... 72/72 |███████████████| 100.0% [72/72] 🔄🧠 (23237.1/s)\n",
            "============================================================\n",
            "✅ Knowledge Graph Build Complete\n",
            "   Entities: 15\n",
            "   Relationships: 72\n",
            "   Total time: 0.48s\n",
            "============================================================\n",
            "Built KG with 15 entities and 72 relationships\n"
          ]
        }
      ],
      "source": [
        "from semantica.kg import GraphBuilder\n",
        "\n",
        "kg = GraphBuilder().build({\"entities\": all_entities, \"relationships\": all_relationships})\n",
        "print(f\"Built KG with {len(kg.get('entities', []))} entities and {len(kg.get('relationships', []))} relationships\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Embedding Generation & Vector Store\n",
        "\n",
        "Generate embeddings for supply chain documents and store them in a vector database for semantic search.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {},
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "fastembed not available. Install with: pip install fastembed. Using fallback embedding method.\n",
            "fastembed not available. Install with: pip install fastembed. Using fallback embedding method.\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is building: Processing relationships... 72/72 |███████████████| 100.0% [72/72] 🔄🧠 (23237.1/s) | 🧠 Semantica is indexing: Storing 115 vectors 🔄📊 (0.0s)Generated 115 embeddings and stored in vector database\n"
          ]
        }
      ],
      "source": [
        "from semantica.embeddings import EmbeddingGenerator\n",
        "from semantica.vector_store import VectorStore\n",
        "\n",
        "gen = EmbeddingGenerator(model_name=EMBEDDING_MODEL, dimension=EMBEDDING_DIMENSION)\n",
        "embeddings = gen.generate_embeddings(chunked_docs, data_type=\"text\")\n",
        "\n",
        "vector_store = VectorStore(backend=\"faiss\", dimension=EMBEDDING_DIMENSION)\n",
        "metadata = [{\"text\": chunk[:100]} for chunk in chunked_docs]\n",
        "vector_store.store_vectors(vectors=embeddings, metadata=metadata)\n",
        "\n",
        "print(f\"Generated {len(embeddings)} embeddings and stored in vector database\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Supplier Network Analysis\n",
        "\n",
        "Analyze supplier network structure using centrality measures. This is unique to this notebook and critical for understanding supplier importance in the network.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is indexing: Storing 115 vectors 🔄📊 (0.0s) | 🧠 Semantica is building: Calculating degree centrality 🔄🧠 (0.0s)Degree centrality: 104 nodes\n",
            "Betweenness centrality: 104 nodes\n"
          ]
        }
      ],
      "source": [
        "from semantica.kg import CentralityCalculator\n",
        "\n",
        "calc = CentralityCalculator()\n",
        "degree_centrality = calc.calculate_degree_centrality(kg)\n",
        "betweenness_centrality = calc.calculate_betweenness_centrality(kg)\n",
        "print(f\"Degree centrality: {len(degree_centrality.get('centrality', {}))} nodes\")\n",
        "print(f\"Betweenness centrality: {len(betweenness_centrality.get('centrality', {}))} nodes\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Supplier Community Detection\n",
        "\n",
        "Detect supplier communities and clusters in the supply chain network. This is unique to this notebook and helps identify supplier groups.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is building: Calculating degree centrality 🔄🧠 (0.0s) | 🧠 Semantica is building: Detecting communities using Louvain algorithm 🔄🧠 (0.0s)Detected 37 communities and 0 overlapping communities\n"
          ]
        }
      ],
      "source": [
        "from semantica.kg import CommunityDetector\n",
        "\n",
        "detector = CommunityDetector()\n",
        "communities = detector.detect_communities(kg, algorithm=\"louvain\")\n",
        "overlapping = detector.detect_overlapping_communities(kg)\n",
        "print(f\"Detected {len(communities.get('communities', []))} communities and {len(overlapping.get('communities', []))} overlapping communities\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## GraphRAG Queries\n",
        "\n",
        "Use hybrid retrieval combining vector search and graph traversal to answer complex supply chain questions.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is embedding: Text cannot be empty or whitespace-only ❌💾 (0.0s) | 🧠 Semantica is processing: Querying with reasoning: Which suppliers provide products to Warehouse W1?... 🔄🔗 (0.0s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Embedding generation failed: Text cannot be empty or whitespace-only\n",
            "Using random fallback embedding\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Query: Which suppliers provide products to Warehouse W1?\n",
            "Response: Based on the retrieved context, I found that Warehouse W1 receives products from two suppliers: Supplier S1 and Supplier S2.\n",
            "\n",
            "Reasoning Path:\n",
            "\n",
            "- Context 1: Warehouse W1 is connected to Supplier S1 through a \"ships_to\" relationship (Score: 0.50).\n",
            "  - Entity: Warehouse W1\n",
            "  - Relationship: ships_to\n",
            "  - Entity: Supplier S1\n",
            "- Context 1: Warehouse W1 is also connected to Supplier S2 through a \"ships_to\" relationship (Score: 0.50).\n",
            "  - Entity: Warehouse W1\n",
            "  - Relationship: ships_to\n",
            "  - Entity: Supplier S2\n",
            "\n",
            "Multi-hop connections: There are no multi-hop connections in this reasoning path as the relationships are direct.\n",
            "\n",
            "Therefore, the suppliers that provide products to Warehouse W1 are Supplier S1 and Supplier S2.\n",
            "Confidence: 0.400 | Sources: 1 | Paths: 0\n",
            "\n",
            "🧠 Semantica is embedding: Text cannot be empty or whitespace-only ❌💾 (0.0s) | 🧠 Semantica is processing: Querying with reasoning: What routes connect warehouses to distribution cen... 🔄🔗 (0.0s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Embedding generation failed: Text cannot be empty or whitespace-only\n",
            "Using random fallback embedding\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Query: What routes connect warehouses to distribution centers?\n",
            "Response: Based on the retrieved context, I found a possible route that connects warehouses to distribution centers.\n",
            "\n",
            "The route involves the following entities and relationships:\n",
            "\n",
            "1. Warehouses are connected to Transportation Hubs (Score: 0.40) via the \"serves\" relationship.\n",
            "2. Transportation Hubs are connected to Distribution Centers (Score: 0.60) via the \"serves\" relationship.\n",
            "\n",
            "Therefore, the route that connects warehouses to distribution centers is:\n",
            "\n",
            "Warehouses → Transportation Hubs (serves) → Distribution Centers (serves)\n",
            "\n",
            "This multi-hop connection involves two relationships: \"serves\" between warehouses and transportation hubs, and \"serves\" between transportation hubs and distribution centers.\n",
            "\n",
            "Note that the scores indicate the confidence level of each connection, with higher scores indicating more reliable information.\n",
            "Confidence: 0.400 | Sources: 1 | Paths: 0\n",
            "\n",
            "🧠 Semantica is embedding: Generated embedding (dim: 128) |███████████████| 100.0% ✅💾 | 🧠 Semantica is processing: Querying with reasoning: Where is Supplier A located?... 🔄🔗 (0.0s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Embedding generation failed: Text cannot be empty or whitespace-only\n",
            "Using random fallback embedding\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Query: Where is Supplier A located?\n",
            "Response: Based on the retrieved context, I was unable to determine the exact location of Supplier A. However, I can provide some information that might be related.\n",
            "\n",
            "Context 1 has a score of 0.50, but it does not provide any information about Supplier A's location. Context 2 mentions Latin America, but there is no direct connection to Supplier A. Context 3 contains a code (end_char=13714), which does not seem to be related to a location. Context 4 mentions Asia, but again, there is no direct connection to Supplier A. Context 5 mentions the Mediterranean, but it is not clear how this is related to Supplier A.\n",
            "\n",
            "Unfortunately, without more specific information, I am unable to provide a precise answer to the question of where Supplier A is located.\n",
            "Confidence: 0.255 | Sources: 10 | Paths: 0\n",
            "\n",
            "🧠 Semantica is embedding: Generated embedding (dim: 128) |███████████████| 100.0% ✅💾 | 🧠 Semantica is processing: Querying with reasoning: What products are shipped via Route R1?... 🔄🔗 (0.0s)"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Embedding generation failed: Text cannot be empty or whitespace-only\n",
            "Using random fallback embedding\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Query: What products are shipped via Route R1?\n",
            "Response: Based on the retrieved context, I found the following information:\n",
            "\n",
            "The context mentions Route R1, but it does not explicitly state which products are shipped via this route. However, it does mention a relationship between Route R1 and a warehouse (Entity: Warehouse W1), indicating that Route R1 is used for shipping products from Warehouse W1.\n",
            "\n",
            "To answer the question, I need to make a multi-hop connection between Route R1, Warehouse W1, and the products shipped from Warehouse W1.\n",
            "\n",
            "Reasoning Path:\n",
            "\n",
            "1. Route R1 is associated with Warehouse W1 (Relationship: \"serves\").\n",
            "2. Warehouse W1 ships products (Relationship: \"ships\").\n",
            "3. The products shipped by Warehouse W1 are Electronics and Home Appliances (Relationship: \"carries\").\n",
            "\n",
            "Based on this reasoning path, I can conclude that the products shipped via Route R1 are Electronics and Home Appliances.\n",
            "\n",
            "Answer: The products shipped via Route R1 are Electronics and Home Appliances.\n",
            "Confidence: 0.400 | Sources: 1 | Paths: 0\n",
            "\n"
          ]
        }
      ],
      "source": [
        "from semantica.context import AgentContext, ContextGraph, ContextRetriever\n",
        "from semantica.llms import Groq\n",
        "import os\n",
        "\n",
        "context_graph = ContextGraph()\n",
        "context_graph.build_from_entities_and_relationships(\n",
        "    entities=kg.get('entities', []),\n",
        "    relationships=kg.get('relationships', [])\n",
        ")\n",
        "\n",
        "retriever = ContextRetriever(vector_store=vector_store, knowledge_graph=context_graph, hybrid_alpha=0.6, max_expansion_hops=2)\n",
        "context = AgentContext(vector_store=vector_store, knowledge_graph=context_graph, use_graph_expansion=True, max_expansion_hops=2)\n",
        "\n",
        "llm = Groq(model=\"llama-3.1-8b-instant\", api_key=os.getenv(\"GROQ_API_KEY\"))\n",
        "\n",
        "queries = [\n",
        "    \"Which suppliers provide products to Warehouse W1?\",\n",
        "    \"What routes connect warehouses to distribution centers?\",\n",
        "    \"Where is Supplier A located?\",\n",
        "    \"What products are shipped via Route R1?\"\n",
        "]\n",
        "\n",
        "for query in queries:\n",
        "    result = context.query_with_reasoning(query, llm_provider=llm, max_results=10, max_hops=2)\n",
        "    print(f\"Query: {query}\")\n",
        "    print(f\"Response: {result.get('response', 'No response generated')}\")\n",
        "    print(f\"Confidence: {result.get('confidence', 0):.3f} | Sources: {result.get('num_sources', 0)} | Paths: {result.get('num_reasoning_paths', 0)}\\n\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Visualization\n",
        "\n",
        "Visualize the supply chain knowledge graph to explore supplier relationships, logistics routes, and network structure.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "metadata": {},
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "c:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\umap\\__init__.py:9: ImportWarning: Tensorflow not installed; ParametricUMAP will be unavailable\n",
            "  warn(\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is processing: Querying with reasoning: What products are shipped via Route R1?... 🔄🔗 (0.0s) | 🧠 Semantica is visualizing: Visualization generated: 15 nodes, 0 edges |███████████████| 100.0% ✅📈"
          ]
        },
        {
          "data": {
            "application/vnd.plotly.v1+json": {
              "config": {
                "plotlyServerURL": "https://plot.ly"
              },
              "data": [
                {
                  "hoverinfo": "none",
                  "line": {
                    "color": "#888",
                    "width": 1
                  },
                  "mode": "lines",
                  "opacity": 0.5,
                  "showlegend": false,
                  "type": "scatter",
                  "x": [],
                  "y": []
                },
                {
                  "hoverinfo": "text",
                  "hovertext": [
                    "<b>Maersk</b><br>Type: PRODUCT",
                    "<b>Mediterranean</b><br>Type: LOC",
                    "<b>Mothership</b><br>Type: PRODUCT",
                    "<b>CapEx</b><br>Type: PRODUCT",
                    "<b>Escort</b><br>Type: PRODUCT",
                    "<b>Europe</b><br>Type: LOC",
                    "<b>Entity(text='the East Coast'</b><br>Type: LOC",
                    "<b>the East Coast</b><br>Type: LOC",
                    "<b>Asia</b><br>Type: LOC",
                    "<b>Zebra</b><br>Type: PRODUCT",
                    "<b>IntraMove</b><br>Type: PRODUCT",
                    "<b>Latin America</b><br>Type: LOC",
                    "<b>Pacific-Norfolk Southern'</b><br>Type: LOC",
                    "<b>North America</b><br>Type: LOC",
                    "<b>end_char=13714</b><br>Type: LOC"
                  ],
                  "marker": {
                    "color": [
                      "#ff7f0e",
                      "#1f77b4",
                      "#ff7f0e",
                      "#ff7f0e",
                      "#ff7f0e",
                      "#1f77b4",
                      "#1f77b4",
                      "#1f77b4",
                      "#1f77b4",
                      "#ff7f0e",
                      "#ff7f0e",
                      "#1f77b4",
                      "#1f77b4",
                      "#1f77b4",
                      "#1f77b4"
                    ],
                    "line": {
                      "color": "white",
                      "width": 2
                    },
                    "opacity": 1,
                    "size": [
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10,
                      10
                    ]
                  },
                  "mode": "markers+text",
                  "showlegend": false,
                  "text": [
                    "Maersk",
                    "Mediterranean",
                    "Mothership",
                    "CapEx",
                    "Escort",
                    "Europe",
                    "Entity(text='the East Coast'",
                    "the East Coast",
                    "Asia",
                    "Zebra",
                    "IntraMove",
                    "Latin America",
                    "Pacific-Norfolk Southern'",
                    "North America",
                    "end_char=13714"
                  ],
                  "textfont": {
                    "color": "#333",
                    "size": 10
                  },
                  "textposition": "top center",
                  "type": "scatter",
                  "x": [
                    0.5036591355953103,
                    0.0892836374451004,
                    -0.33721471218005694,
                    -0.9098945385988114,
                    0.9604560219326381,
                    -0.9273820553231914,
                    -0.3133539446210273,
                    0.8577168217048383,
                    0.10167722828778877,
                    -0.9438775301591874,
                    -0.6790678498358663,
                    -0.6607393533957981,
                    0.7362801110665373,
                    0.5224570280817251,
                    1
                  ],
                  "y": [
                    0.9026421139981378,
                    0.9890371664829897,
                    0.9748921816244126,
                    0.39048285258452087,
                    -0.24809128709392098,
                    -0.41320738223368847,
                    -0.9634285339395612,
                    0.6342944861980466,
                    -0.966912802753823,
                    -0.009677090138805385,
                    0.7332067002308004,
                    -0.7342662767478417,
                    -0.5734885161699765,
                    -0.9099686354611624,
                    0.19448502341987164
                  ]
                }
              ],
              "layout": {
                "hovermode": "closest",
                "margin": {
                  "b": 20,
                  "l": 5,
                  "r": 5,
                  "t": 40
                },
                "plot_bgcolor": "white",
                "showlegend": false,
                "template": {
                  "data": {
                    "bar": [
                      {
                        "error_x": {
                          "color": "#2a3f5f"
                        },
                        "error_y": {
                          "color": "#2a3f5f"
                        },
                        "marker": {
                          "line": {
                            "color": "#E5ECF6",
                            "width": 0.5
                          },
                          "pattern": {
                            "fillmode": "overlay",
                            "size": 10,
                            "solidity": 0.2
                          }
                        },
                        "type": "bar"
                      }
                    ],
                    "barpolar": [
                      {
                        "marker": {
                          "line": {
                            "color": "#E5ECF6",
                            "width": 0.5
                          },
                          "pattern": {
                            "fillmode": "overlay",
                            "size": 10,
                            "solidity": 0.2
                          }
                        },
                        "type": "barpolar"
                      }
                    ],
                    "carpet": [
                      {
                        "aaxis": {
                          "endlinecolor": "#2a3f5f",
                          "gridcolor": "white",
                          "linecolor": "white",
                          "minorgridcolor": "white",
                          "startlinecolor": "#2a3f5f"
                        },
                        "baxis": {
                          "endlinecolor": "#2a3f5f",
                          "gridcolor": "white",
                          "linecolor": "white",
                          "minorgridcolor": "white",
                          "startlinecolor": "#2a3f5f"
                        },
                        "type": "carpet"
                      }
                    ],
                    "choropleth": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "type": "choropleth"
                      }
                    ],
                    "contour": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "colorscale": [
                          [
                            0,
                            "#0d0887"
                          ],
                          [
                            0.1111111111111111,
                            "#46039f"
                          ],
                          [
                            0.2222222222222222,
                            "#7201a8"
                          ],
                          [
                            0.3333333333333333,
                            "#9c179e"
                          ],
                          [
                            0.4444444444444444,
                            "#bd3786"
                          ],
                          [
                            0.5555555555555556,
                            "#d8576b"
                          ],
                          [
                            0.6666666666666666,
                            "#ed7953"
                          ],
                          [
                            0.7777777777777778,
                            "#fb9f3a"
                          ],
                          [
                            0.8888888888888888,
                            "#fdca26"
                          ],
                          [
                            1,
                            "#f0f921"
                          ]
                        ],
                        "type": "contour"
                      }
                    ],
                    "contourcarpet": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "type": "contourcarpet"
                      }
                    ],
                    "heatmap": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "colorscale": [
                          [
                            0,
                            "#0d0887"
                          ],
                          [
                            0.1111111111111111,
                            "#46039f"
                          ],
                          [
                            0.2222222222222222,
                            "#7201a8"
                          ],
                          [
                            0.3333333333333333,
                            "#9c179e"
                          ],
                          [
                            0.4444444444444444,
                            "#bd3786"
                          ],
                          [
                            0.5555555555555556,
                            "#d8576b"
                          ],
                          [
                            0.6666666666666666,
                            "#ed7953"
                          ],
                          [
                            0.7777777777777778,
                            "#fb9f3a"
                          ],
                          [
                            0.8888888888888888,
                            "#fdca26"
                          ],
                          [
                            1,
                            "#f0f921"
                          ]
                        ],
                        "type": "heatmap"
                      }
                    ],
                    "histogram": [
                      {
                        "marker": {
                          "pattern": {
                            "fillmode": "overlay",
                            "size": 10,
                            "solidity": 0.2
                          }
                        },
                        "type": "histogram"
                      }
                    ],
                    "histogram2d": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "colorscale": [
                          [
                            0,
                            "#0d0887"
                          ],
                          [
                            0.1111111111111111,
                            "#46039f"
                          ],
                          [
                            0.2222222222222222,
                            "#7201a8"
                          ],
                          [
                            0.3333333333333333,
                            "#9c179e"
                          ],
                          [
                            0.4444444444444444,
                            "#bd3786"
                          ],
                          [
                            0.5555555555555556,
                            "#d8576b"
                          ],
                          [
                            0.6666666666666666,
                            "#ed7953"
                          ],
                          [
                            0.7777777777777778,
                            "#fb9f3a"
                          ],
                          [
                            0.8888888888888888,
                            "#fdca26"
                          ],
                          [
                            1,
                            "#f0f921"
                          ]
                        ],
                        "type": "histogram2d"
                      }
                    ],
                    "histogram2dcontour": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "colorscale": [
                          [
                            0,
                            "#0d0887"
                          ],
                          [
                            0.1111111111111111,
                            "#46039f"
                          ],
                          [
                            0.2222222222222222,
                            "#7201a8"
                          ],
                          [
                            0.3333333333333333,
                            "#9c179e"
                          ],
                          [
                            0.4444444444444444,
                            "#bd3786"
                          ],
                          [
                            0.5555555555555556,
                            "#d8576b"
                          ],
                          [
                            0.6666666666666666,
                            "#ed7953"
                          ],
                          [
                            0.7777777777777778,
                            "#fb9f3a"
                          ],
                          [
                            0.8888888888888888,
                            "#fdca26"
                          ],
                          [
                            1,
                            "#f0f921"
                          ]
                        ],
                        "type": "histogram2dcontour"
                      }
                    ],
                    "mesh3d": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "type": "mesh3d"
                      }
                    ],
                    "parcoords": [
                      {
                        "line": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "parcoords"
                      }
                    ],
                    "pie": [
                      {
                        "automargin": true,
                        "type": "pie"
                      }
                    ],
                    "scatter": [
                      {
                        "fillpattern": {
                          "fillmode": "overlay",
                          "size": 10,
                          "solidity": 0.2
                        },
                        "type": "scatter"
                      }
                    ],
                    "scatter3d": [
                      {
                        "line": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scatter3d"
                      }
                    ],
                    "scattercarpet": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scattercarpet"
                      }
                    ],
                    "scattergeo": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scattergeo"
                      }
                    ],
                    "scattergl": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scattergl"
                      }
                    ],
                    "scattermap": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scattermap"
                      }
                    ],
                    "scattermapbox": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scattermapbox"
                      }
                    ],
                    "scatterpolar": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scatterpolar"
                      }
                    ],
                    "scatterpolargl": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scatterpolargl"
                      }
                    ],
                    "scatterternary": [
                      {
                        "marker": {
                          "colorbar": {
                            "outlinewidth": 0,
                            "ticks": ""
                          }
                        },
                        "type": "scatterternary"
                      }
                    ],
                    "surface": [
                      {
                        "colorbar": {
                          "outlinewidth": 0,
                          "ticks": ""
                        },
                        "colorscale": [
                          [
                            0,
                            "#0d0887"
                          ],
                          [
                            0.1111111111111111,
                            "#46039f"
                          ],
                          [
                            0.2222222222222222,
                            "#7201a8"
                          ],
                          [
                            0.3333333333333333,
                            "#9c179e"
                          ],
                          [
                            0.4444444444444444,
                            "#bd3786"
                          ],
                          [
                            0.5555555555555556,
                            "#d8576b"
                          ],
                          [
                            0.6666666666666666,
                            "#ed7953"
                          ],
                          [
                            0.7777777777777778,
                            "#fb9f3a"
                          ],
                          [
                            0.8888888888888888,
                            "#fdca26"
                          ],
                          [
                            1,
                            "#f0f921"
                          ]
                        ],
                        "type": "surface"
                      }
                    ],
                    "table": [
                      {
                        "cells": {
                          "fill": {
                            "color": "#EBF0F8"
                          },
                          "line": {
                            "color": "white"
                          }
                        },
                        "header": {
                          "fill": {
                            "color": "#C8D4E3"
                          },
                          "line": {
                            "color": "white"
                          }
                        },
                        "type": "table"
                      }
                    ]
                  },
                  "layout": {
                    "annotationdefaults": {
                      "arrowcolor": "#2a3f5f",
                      "arrowhead": 0,
                      "arrowwidth": 1
                    },
                    "autotypenumbers": "strict",
                    "coloraxis": {
                      "colorbar": {
                        "outlinewidth": 0,
                        "ticks": ""
                      }
                    },
                    "colorscale": {
                      "diverging": [
                        [
                          0,
                          "#8e0152"
                        ],
                        [
                          0.1,
                          "#c51b7d"
                        ],
                        [
                          0.2,
                          "#de77ae"
                        ],
                        [
                          0.3,
                          "#f1b6da"
                        ],
                        [
                          0.4,
                          "#fde0ef"
                        ],
                        [
                          0.5,
                          "#f7f7f7"
                        ],
                        [
                          0.6,
                          "#e6f5d0"
                        ],
                        [
                          0.7,
                          "#b8e186"
                        ],
                        [
                          0.8,
                          "#7fbc41"
                        ],
                        [
                          0.9,
                          "#4d9221"
                        ],
                        [
                          1,
                          "#276419"
                        ]
                      ],
                      "sequential": [
                        [
                          0,
                          "#0d0887"
                        ],
                        [
                          0.1111111111111111,
                          "#46039f"
                        ],
                        [
                          0.2222222222222222,
                          "#7201a8"
                        ],
                        [
                          0.3333333333333333,
                          "#9c179e"
                        ],
                        [
                          0.4444444444444444,
                          "#bd3786"
                        ],
                        [
                          0.5555555555555556,
                          "#d8576b"
                        ],
                        [
                          0.6666666666666666,
                          "#ed7953"
                        ],
                        [
                          0.7777777777777778,
                          "#fb9f3a"
                        ],
                        [
                          0.8888888888888888,
                          "#fdca26"
                        ],
                        [
                          1,
                          "#f0f921"
                        ]
                      ],
                      "sequentialminus": [
                        [
                          0,
                          "#0d0887"
                        ],
                        [
                          0.1111111111111111,
                          "#46039f"
                        ],
                        [
                          0.2222222222222222,
                          "#7201a8"
                        ],
                        [
                          0.3333333333333333,
                          "#9c179e"
                        ],
                        [
                          0.4444444444444444,
                          "#bd3786"
                        ],
                        [
                          0.5555555555555556,
                          "#d8576b"
                        ],
                        [
                          0.6666666666666666,
                          "#ed7953"
                        ],
                        [
                          0.7777777777777778,
                          "#fb9f3a"
                        ],
                        [
                          0.8888888888888888,
                          "#fdca26"
                        ],
                        [
                          1,
                          "#f0f921"
                        ]
                      ]
                    },
                    "colorway": [
                      "#636efa",
                      "#EF553B",
                      "#00cc96",
                      "#ab63fa",
                      "#FFA15A",
                      "#19d3f3",
                      "#FF6692",
                      "#B6E880",
                      "#FF97FF",
                      "#FECB52"
                    ],
                    "font": {
                      "color": "#2a3f5f"
                    },
                    "geo": {
                      "bgcolor": "white",
                      "lakecolor": "white",
                      "landcolor": "#E5ECF6",
                      "showlakes": true,
                      "showland": true,
                      "subunitcolor": "white"
                    },
                    "hoverlabel": {
                      "align": "left"
                    },
                    "hovermode": "closest",
                    "mapbox": {
                      "style": "light"
                    },
                    "paper_bgcolor": "white",
                    "plot_bgcolor": "#E5ECF6",
                    "polar": {
                      "angularaxis": {
                        "gridcolor": "white",
                        "linecolor": "white",
                        "ticks": ""
                      },
                      "bgcolor": "#E5ECF6",
                      "radialaxis": {
                        "gridcolor": "white",
                        "linecolor": "white",
                        "ticks": ""
                      }
                    },
                    "scene": {
                      "xaxis": {
                        "backgroundcolor": "#E5ECF6",
                        "gridcolor": "white",
                        "gridwidth": 2,
                        "linecolor": "white",
                        "showbackground": true,
                        "ticks": "",
                        "zerolinecolor": "white"
                      },
                      "yaxis": {
                        "backgroundcolor": "#E5ECF6",
                        "gridcolor": "white",
                        "gridwidth": 2,
                        "linecolor": "white",
                        "showbackground": true,
                        "ticks": "",
                        "zerolinecolor": "white"
                      },
                      "zaxis": {
                        "backgroundcolor": "#E5ECF6",
                        "gridcolor": "white",
                        "gridwidth": 2,
                        "linecolor": "white",
                        "showbackground": true,
                        "ticks": "",
                        "zerolinecolor": "white"
                      }
                    },
                    "shapedefaults": {
                      "line": {
                        "color": "#2a3f5f"
                      }
                    },
                    "ternary": {
                      "aaxis": {
                        "gridcolor": "white",
                        "linecolor": "white",
                        "ticks": ""
                      },
                      "baxis": {
                        "gridcolor": "white",
                        "linecolor": "white",
                        "ticks": ""
                      },
                      "bgcolor": "#E5ECF6",
                      "caxis": {
                        "gridcolor": "white",
                        "linecolor": "white",
                        "ticks": ""
                      }
                    },
                    "title": {
                      "x": 0.05
                    },
                    "xaxis": {
                      "automargin": true,
                      "gridcolor": "white",
                      "linecolor": "white",
                      "ticks": "",
                      "title": {
                        "standoff": 15
                      },
                      "zerolinecolor": "white",
                      "zerolinewidth": 2
                    },
                    "yaxis": {
                      "automargin": true,
                      "gridcolor": "white",
                      "linecolor": "white",
                      "ticks": "",
                      "title": {
                        "standoff": 15
                      },
                      "zerolinecolor": "white",
                      "zerolinewidth": 2
                    }
                  }
                },
                "title": {
                  "text": "Knowledge Graph Network"
                },
                "xaxis": {
                  "showgrid": false,
                  "showticklabels": false,
                  "zeroline": false
                },
                "yaxis": {
                  "showgrid": false,
                  "showticklabels": false,
                  "zeroline": false
                }
              }
            }
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from semantica.visualization import KGVisualizer\n",
        "\n",
        "viz = KGVisualizer(layout=\"force\")\n",
        "fig = viz.visualize_network(kg, output=\"interactive\")\n",
        "fig.show() if fig else None\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Export\n",
        "\n",
        "Export the knowledge graph in multiple formats for supply chain analysis and reporting.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "🧠 Semantica is visualizing: Visualization generated: 15 nodes, 0 edges |███████████████| 100.0% ✅📈 | 🧠 Semantica is exporting: Exporting graph to json: supply_chain_kg.json 🔄💾 (0.0s)Exported knowledge graph in JSON, GraphML, formats\n"
          ]
        }
      ],
      "source": [
        "from semantica.export import GraphExporter\n",
        "\n",
        "exporter = GraphExporter()\n",
        "exporter.export(kg, format=\"json\", output_path=\"supply_chain_kg.json\")\n",
        "exporter.export(kg, format=\"graphml\", output_path=\"supply_chain_kg.graphml\")\n",
        "print(\"Exported knowledge graph in JSON, GraphML, formats\")\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}
