SmartSupplyCockpit / index.html
aidn's picture
Update index.html
77af829 verified
<!DOCTYPE html>
<html lang="de" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Agentic APS & Procurement Showcase | valantic & databricks</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Tailwind Configuration with valantic CI Colors -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
val: {
indigo: '#193773',
royal: '#3c4bc8',
purple: '#5b26b7',
silver: '#cdcdcd',
red: '#FF4B4B',
orange: '#FF744F',
black: '#100C2A',
white: '#FFFFFF'
},
db: {
red: '#ff3621' // Databricks Accent
}
},
fontFamily: {
// valantic uses Segoe UI according to the guidelines
sans: ['"Segoe UI"', 'Inter', 'system-ui', 'sans-serif'],
},
backgroundImage: {
'val-gradient': 'linear-gradient(315deg, #FF744F 0%, #FF4B4B 100%)',
'val-dark-gradient': 'linear-gradient(45deg, #100C2A 0%, #193773 100%)',
}
}
}
}
</script>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<style>
/* Custom animations */
.fade-in-up {
animation: fadeInUp 0.8s ease-out forwards;
opacity: 0;
transform: translateY(20px);
}
@keyframes fadeInUp {
to { opacity: 1; transform: translateY(0); }
}
.chat-message {
animation: popIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
opacity: 0;
transform: scale(0.95);
transform-origin: top left;
}
@keyframes popIn {
to { opacity: 1; transform: scale(1); }
}
.typing-indicator span {
animation: blink 1.4s infinite both;
height: 6px;
width: 6px;
background: #94a3b8;
border-radius: 50%;
display: inline-block;
margin: 0 1px;
}
.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
@keyframes blink {
0% { opacity: 0.2; transform: scale(0.8); }
20% { opacity: 1; transform: scale(1.2); }
100% { opacity: 0.2; transform: scale(0.8); }
}
.delay-100 { animation-delay: 100ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
/* Scrollbar styling for chat */
.chat-scroll::-webkit-scrollbar { width: 6px; }
.chat-scroll::-webkit-scrollbar-track { background: transparent; }
.chat-scroll::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 10px; }
.chat-scroll::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
.text-gradient {
background: linear-gradient(315deg, #FF744F 0%, #FF4B4B 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Gantt Block styling */
.gantt-block {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
</style>
</head>
<body class="bg-gray-50 text-gray-800 font-sans antialiased selection:bg-val-red selection:text-white">
<!-- Navigation -->
<nav class="fixed w-full z-50 bg-white/90 backdrop-blur-md shadow-sm border-b border-gray-100">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-20 items-center">
<div class="flex items-center gap-4">
<span class="text-2xl font-extrabold text-val-black tracking-tight">valantic</span>
<span class="text-gray-300">|</span>
<span class="text-xl font-bold text-db-red tracking-tight">databricks</span>
</div>
<div class="hidden md:flex space-x-8">
<a href="#problem-loesung" class="text-gray-600 hover:text-val-red font-semibold transition-colors">Die Challenge</a>
<a href="#showcase" class="text-gray-600 hover:text-val-red font-semibold transition-colors">Interactive Demo</a>
<a href="#architektur" class="text-gray-600 hover:text-val-red font-semibold transition-colors">Architektur</a>
</div>
<div class="hidden md:flex">
<a href="#showcase" class="bg-val-gradient text-white px-6 py-2.5 rounded-full font-semibold transition-all shadow-md hover:shadow-lg hover:opacity-90">
Zum Showcase
</a>
</div>
</div>
</div>
</nav>
<!-- Section 1: Hero Area -->
<section class="relative pt-32 pb-20 lg:pt-48 lg:pb-32 overflow-hidden bg-val-black text-white">
<div class="absolute inset-0 z-0">
<div class="absolute inset-0 bg-val-dark-gradient opacity-95 z-10"></div>
<img src="https://images.unsplash.com/photo-1581091226825-a6a2a5aee158?q=80&w=2070&auto=format&fit=crop" alt="Production Background" class="w-full h-full object-cover opacity-30 mix-blend-overlay" />
</div>
<div class="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/10 backdrop-blur-sm border border-white/20 text-sm font-semibold mb-8 fade-in-up">
<i data-lucide="sparkles" class="w-4 h-4 text-val-orange"></i>
wayRTS & Agentic AI Showcase
</div>
<h1 class="text-4xl md:text-6xl lg:text-7xl font-extrabold tracking-tight mb-6 fade-in-up delay-100">
Proaktive Beschaffung & Planung <br class="hidden md:block" />
mit <span class="text-gradient">Agentic AI</span>.
</h1>
<p class="mt-4 text-xl md:text-2xl text-gray-300 max-w-3xl mx-auto mb-10 fade-in-up delay-200">
Erleben Sie die nächste Stufe der Automatisierung: Multi-Agent Systeme orchestrieren Supply Chain Daten und valantic wayRTS in Echtzeit.
</p>
<div class="flex flex-col sm:flex-row justify-center gap-4 fade-in-up delay-300">
<button onclick="document.getElementById('showcase').scrollIntoView({behavior: 'smooth'})" class="bg-val-gradient text-white px-8 py-4 rounded-full font-bold text-lg transition-all shadow-lg hover:shadow-val-red/30 flex items-center justify-center gap-2 cursor-pointer">
Interaktive Demo starten
<i data-lucide="play" class="w-5 h-5"></i>
</button>
</div>
</div>
</section>
<!-- Section 2: Problem vs. Lösung -->
<section id="problem-loesung" class="py-24 bg-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-3xl md:text-4xl font-bold text-val-indigo mb-4">Statische Planung trifft auf dynamische Lieferketten</h2>
<div class="w-24 h-1 bg-val-gradient mx-auto rounded-full"></div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 lg:gap-24">
<div class="space-y-8">
<div class="flex items-center gap-3 mb-6">
<div class="w-12 h-12 rounded-full bg-red-50 flex items-center justify-center text-val-red"><i data-lucide="alert-triangle" class="w-6 h-6"></i></div>
<h3 class="text-2xl font-bold text-val-black">Die Challenge</h3>
</div>
<div class="bg-gray-50 p-6 rounded-2xl border border-gray-100"><div class="flex gap-4"><i data-lucide="network" class="w-6 h-6 text-gray-500 mt-1"></i><div><h4 class="font-bold text-gray-900 mb-2">Informations-Silos</h4><p class="text-gray-600">ERP-Systeme, Lieferanten-Portale und Produktionsplanung (APS) sind oft nicht in Echtzeit synchronisiert. Abweichungen fallen spät auf.</p></div></div></div>
<div class="bg-gray-50 p-6 rounded-2xl border border-gray-100"><div class="flex gap-4"><i data-lucide="git-merge" class="w-6 h-6 text-gray-500 mt-1"></i><div><h4 class="font-bold text-gray-900 mb-2">Hohe Komplexität</h4><p class="text-gray-600">Die manuelle Modellierung von Produktionsprozessen und Synchronisation von Stücklisten (BOM) bei Lieferausfällen ist zeitintensiv.</p></div></div></div>
<div class="bg-gray-50 p-6 rounded-2xl border border-gray-100"><div class="flex gap-4"><i data-lucide="clock" class="w-6 h-6 text-gray-500 mt-1"></i><div><h4 class="font-bold text-gray-900 mb-2">Reaktives Handeln</h4><p class="text-gray-600">Planer agieren reaktiv. Brüche zwischen Grob- und Feinplanung führen zu suboptimalen Beständen und Durchlaufzeiten.</p></div></div></div>
</div>
<div class="space-y-8">
<div class="flex items-center gap-3 mb-6">
<div class="w-12 h-12 rounded-full bg-indigo-50 flex items-center justify-center text-val-indigo"><i data-lucide="check-circle" class="w-6 h-6"></i></div>
<h3 class="text-2xl font-bold text-val-black">Der Customer Benefit</h3>
</div>
<div class="bg-indigo-50/50 p-6 rounded-2xl border border-indigo-100"><div class="flex gap-4"><i data-lucide="cpu" class="w-6 h-6 text-val-indigo mt-1"></i><div><h4 class="font-bold text-val-black mb-2">Supply Chain Cockpit & In-Memory</h4><p class="text-gray-600">Konsolidierung von weltweiten Live-Daten und der wayRTS Engine für rasante Planungssimulationen in Sekundenbruchteilen.</p></div></div></div>
<div class="bg-indigo-50/50 p-6 rounded-2xl border border-indigo-100"><div class="flex gap-4"><i data-lucide="git-pull-request" class="w-6 h-6 text-val-indigo mt-1"></i><div><h4 class="font-bold text-val-black mb-2">Visual & Interactive Planning</h4><p class="text-gray-600">Das MAS warnt präventiv vor Beschaffungsproblemen. Die Auswirkungen auf Kapazitäten und Lieferzeiten sind per Scenario Technology (What-if) sofort sichtbar.</p></div></div></div>
<div class="bg-indigo-50/50 p-6 rounded-2xl border border-indigo-100"><div class="flex gap-4"><i data-lucide="bot" class="w-6 h-6 text-val-indigo mt-1"></i><div><h4 class="font-bold text-val-black mb-2">Automation of Regular Tasks</h4><p class="text-gray-600">Whitebox-APS Ansatz: KI übernimmt Routineaufgaben (z.B. Alternativlieferanten finden, ATP/CTP prüfen) und übergibt komplexe Konflikte an den Planer.</p></div></div></div>
</div>
</div>
</div>
</section>
<!-- Section 3: Interactive Visual Planning & Showcase -->
<section id="showcase" class="py-24 bg-val-black text-white overflow-hidden">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="mb-12 text-center">
<span class="text-val-orange font-bold tracking-wider uppercase text-sm">Interactive Demo</span>
<h2 class="text-3xl md:text-5xl font-bold mt-2 mb-4 text-white">wayRTS Supply Chain Cockpit</h2>
<p class="text-xl text-gray-300 max-w-3xl mx-auto">Wählen Sie ein Szenario im Produktionsnetzwerk aus, um das visuelle Zusammenspiel von Databricks Agenten und wayRTS zu erleben.</p>
</div>
<div class="grid grid-cols-1 xl:grid-cols-12 gap-8 items-start">
<!-- LEFT: Interactive wayRTS Cockpit / Gantt -->
<div class="xl:col-span-5 bg-white border border-gray-200 rounded-2xl p-6 shadow-2xl relative overflow-hidden flex flex-col h-[680px] text-gray-900">
<div class="flex justify-between items-center mb-4">
<h3 class="font-bold text-xl flex items-center gap-2 text-val-indigo">
<i data-lucide="layout-dashboard" class="text-val-red"></i> Production Schedule
</h3>
<span class="text-xs font-mono bg-green-100 text-green-800 px-2 py-1 rounded flex items-center gap-1">
<span class="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span> Live Sync
</span>
</div>
<!-- Gantt Visual Container -->
<div class="relative flex-1 bg-slate-50 rounded-xl border border-slate-200 overflow-hidden mb-6 shadow-inner p-4 flex flex-col">
<h4 class="text-xs font-bold text-gray-400 mb-3 uppercase tracking-wider">wayRTS Feinplanung (Werk München)</h4>
<!-- Timeline Header -->
<div class="flex text-xs text-gray-400 border-b border-gray-200 pb-2 mb-4 ml-16">
<div class="flex-1 text-center">Mo</div>
<div class="flex-1 text-center">Di</div>
<div class="flex-1 text-center">Mi</div>
<div class="flex-1 text-center border-l border-gray-200 border-dashed">Do</div>
<div class="flex-1 text-center">Fr</div>
</div>
<!-- Line 1 (Taiwan Scenario) -->
<div class="flex items-center mb-5 group cursor-pointer" onclick="playScenario('taiwan')">
<div class="w-16 text-xs font-bold text-val-indigo flex flex-col">
Linie 1
<span class="text-[9px] font-normal text-gray-400">Montage</span>
</div>
<div class="flex-1 bg-white h-10 rounded-md relative border border-slate-200 shadow-sm">
<!-- Job A-400 -->
<div id="block-taiwan" class="gantt-block absolute top-1 bottom-1 left-[10%] w-[45%] bg-blue-50 border border-blue-200 rounded flex flex-col justify-center px-2 text-[10px] text-blue-700 hover:bg-blue-100 hover:shadow">
<span class="font-bold">#A-400</span>
<span class="text-[8px] opacity-80 truncate">Comp: MC-900 (Taiwan)</span>
</div>
</div>
</div>
<!-- Line 2 (Munich Scenario) -->
<div class="flex items-center mb-5 group cursor-pointer" onclick="playScenario('munich')">
<div class="w-16 text-xs font-bold text-val-indigo flex flex-col">
Linie 2
<span class="text-[9px] font-normal text-gray-400">SMD-Best.</span>
</div>
<div class="flex-1 bg-white h-10 rounded-md relative border border-slate-200 shadow-sm">
<!-- Running Job -->
<div class="absolute top-1 bottom-1 left-[0%] w-[50%] bg-slate-100 border border-slate-300 rounded flex flex-col justify-center px-2 text-[10px] text-slate-600">
<span class="font-bold">#C-100</span>
</div>
<!-- Empty space where demand spike goes -->
<div id="block-munich" class="gantt-block absolute top-1 bottom-1 left-[60%] w-[35%] border-2 border-dashed border-transparent rounded flex items-center justify-center">
<span class="text-[10px] font-bold opacity-0 transition-opacity flex items-center gap-1" id="text-munich">
<i data-lucide="plus-circle" class="w-3 h-3"></i> ATP / CTP Check
</span>
</div>
</div>
</div>
<!-- Line 3 (Placeholder) -->
<div class="flex items-center mb-5 opacity-50">
<div class="w-16 text-xs font-bold text-val-indigo flex flex-col">
Linie 3
<span class="text-[9px] font-normal text-gray-400">Test</span>
</div>
<div class="flex-1 bg-white h-10 rounded-md relative border border-slate-200 shadow-sm">
<div class="absolute top-1 bottom-1 left-[20%] w-[80%] bg-slate-100 border border-slate-300 rounded flex flex-col justify-center px-2 text-[10px] text-slate-600">
<span class="font-bold">#A-399</span>
</div>
</div>
</div>
<!-- Line 4 (Italy Scenario) -->
<div class="flex items-center group cursor-pointer" onclick="playScenario('italy')">
<div class="w-16 text-xs font-bold text-val-indigo flex flex-col">
Linie 4
<span class="text-[9px] font-normal text-gray-400">Mechanik</span>
</div>
<div class="flex-1 bg-white h-10 rounded-md relative border border-slate-200 shadow-sm">
<!-- Current running job -->
<div id="block-italy" class="gantt-block absolute top-1 bottom-1 left-[0%] w-[40%] bg-blue-50 border border-blue-200 rounded flex flex-col justify-center px-2 text-[10px] text-blue-700 hover:bg-blue-100 hover:shadow">
<span class="font-bold">#B-102</span>
<span class="text-[8px] opacity-80 truncate">Mat: IT-55</span>
</div>
</div>
</div>
<!-- Contextual Help -->
<div class="mt-auto text-[10px] text-gray-400 flex items-center justify-center gap-4 pt-4">
<span class="flex items-center gap-1"><span class="w-2 h-2 rounded bg-blue-200 border border-blue-300"></span> Geplant</span>
<span class="flex items-center gap-1"><span class="w-2 h-2 rounded bg-red-200 border border-red-400"></span> Engpass / Risiko</span>
<span class="flex items-center gap-1"><span class="w-2 h-2 rounded bg-orange-200 border border-orange-400"></span> QA / Stopp</span>
</div>
</div>
<!-- Selected Scenario Info -->
<div class="bg-slate-50 rounded-xl p-5 border border-slate-200 min-h-[175px]">
<div class="flex justify-between items-start mb-2">
<h4 id="info-title" class="font-bold text-lg text-val-indigo">Lade Szenario...</h4>
<span id="info-badge" class="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded border border-yellow-200 font-semibold">Extern</span>
</div>
<p id="info-desc" class="text-sm text-gray-600 leading-relaxed mb-4">
Bitte wählen Sie eine Produktionslinie / einen Auftrag aus.
</p>
<button onclick="startSimulation()" id="btn-simulate" class="w-full bg-val-indigo hover:bg-val-royal transition-colors text-white py-2.5 rounded-lg text-sm font-semibold flex justify-center items-center gap-2 shadow-md">
<i data-lucide="cpu" class="w-4 h-4"></i> Agenten-Analyse starten
</button>
</div>
</div>
<!-- RIGHT: Visuals / Databricks UI Mockup -->
<div class="xl:col-span-7 relative h-[680px]">
<!-- Outer subtle glow -->
<div class="absolute -inset-1 bg-val-gradient rounded-2xl blur opacity-20"></div>
<div class="relative bg-white rounded-2xl border border-gray-200 shadow-2xl overflow-hidden h-full flex flex-col">
<!-- Browser Header -->
<div class="bg-slate-50 px-4 py-3 flex items-center justify-between border-b border-slate-200 z-10 shrink-0">
<div class="flex items-center gap-2">
<div class="flex gap-1.5 mr-4">
<div class="w-3 h-3 rounded-full bg-val-red"></div>
<div class="w-3 h-3 rounded-full bg-val-orange"></div>
<div class="w-3 h-3 rounded-full bg-green-400"></div>
</div>
<div class="bg-white border border-gray-200 shadow-sm text-xs text-gray-600 px-3 py-1.5 rounded-md flex items-center gap-2 font-mono">
<i data-lucide="bot" class="w-3 h-3 text-val-indigo"></i> valantic Agentic AI Console
</div>
</div>
<div class="text-xs font-mono text-gray-500 flex items-center gap-2 bg-indigo-50 text-val-indigo px-2 py-1 rounded-md border border-indigo-100">
<i data-lucide="user-cog" class="w-3 h-3"></i> Human-in-the-Loop
</div>
</div>
<!-- Chat Area -->
<div class="flex-1 overflow-y-auto p-6 space-y-6 chat-scroll bg-slate-50/50" id="chat-container">
<!-- Chat content will be injected here by JS -->
</div>
<!-- Typing Input Bar Mockup -->
<div class="bg-white p-4 border-t border-slate-200 shrink-0">
<div class="bg-slate-50 rounded-lg p-3 flex items-center gap-3 border border-slate-200 text-gray-400">
<i data-lucide="terminal" class="w-5 h-5"></i>
<span class="text-sm font-mono">Supervisor Agent wartet auf Input...</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Section 4: Architektur -->
<section id="architektur" class="py-24 bg-gray-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center mb-16">
<h2 class="text-3xl md:text-4xl font-bold text-val-indigo mb-4">Die MAS Architektur in der Beschaffung</h2>
<p class="text-xl text-gray-600 max-w-2xl mx-auto">Spezialisierte Agenten analysieren Echtzeitdaten und interagieren direkt mit valantic wayRTS.</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-8">
<div class="bg-white p-8 rounded-2xl border border-gray-200 shadow-sm hover:shadow-xl transition-all hover:-translate-y-1 group"><div class="w-14 h-14 bg-val-indigo text-white rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform"><i data-lucide="brain-circuit" class="w-7 h-7"></i></div><h3 class="text-xl font-bold text-gray-900 mb-3">Supervisor Agent</h3><p class="text-sm text-val-red font-semibold mb-3">Orchestration Layer</p><p class="text-gray-600">Nimmt Warnungen auf, zerlegt das Planungsproblem und delegiert Teilaufgaben an Fach-Agenten (RAG, ERP, wayRTS).</p></div>
<div class="bg-white p-8 rounded-2xl border border-gray-200 shadow-sm hover:shadow-xl transition-all hover:-translate-y-1 group"><div class="w-14 h-14 bg-indigo-100 text-val-royal rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform"><i data-lucide="book-open-check" class="w-7 h-7"></i></div><h3 class="text-xl font-bold text-gray-900 mb-3">Knowledge Assistant</h3><p class="text-sm text-val-royal font-semibold mb-3">Stücklisten & Regeln</p><p class="text-gray-600">Nutzt Vector Search auf dem Databricks Unity Catalog, um Stücklisten (BOMs), SLAs und Produktionsabhängigkeiten zu prüfen.</p></div>
<div class="bg-white p-8 rounded-2xl border border-gray-200 shadow-sm hover:shadow-xl transition-all hover:-translate-y-1 group"><div class="w-14 h-14 bg-orange-100 text-val-orange rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform"><i data-lucide="radar" class="w-7 h-7"></i></div><h3 class="text-xl font-bold text-gray-900 mb-3">Live Data Client</h3><p class="text-sm text-val-orange font-semibold mb-3">MCP Connector</p><p class="text-gray-600">Verbindet sich via Model Context Protocol mit externen Systemen (Lieferanten-APIs, Wetter, Hafendaten) für den Real World Context.</p></div>
<div class="bg-white p-8 rounded-2xl border border-gray-200 shadow-sm hover:shadow-xl transition-all hover:-translate-y-1 group"><div class="w-14 h-14 bg-red-100 text-val-red rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform"><i data-lucide="activity" class="w-7 h-7"></i></div><h3 class="text-xl font-bold text-gray-900 mb-3">wayRTS Executor</h3><p class="text-sm text-val-red font-semibold mb-3">Action & Simulation</p><p class="text-gray-600">Führt What-If-Szenarien im In-Memory APS aus, simuliert Drag & Drop Alternativen und veranlasst nach Freigabe die Feinplanung.</p></div>
</div>
</div>
</section>
<!-- Section 5: Footer -->
<section class="py-16 bg-white border-t border-gray-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<div class="flex flex-col md:flex-row items-center justify-center gap-8 md:gap-16 mb-10 opacity-90">
<h2 class="text-3xl font-extrabold text-val-black tracking-tight">valantic</h2>
<div class="hidden md:block w-px h-12 bg-gray-300"></div>
<h2 class="text-3xl font-extrabold text-gray-800 tracking-tight flex items-center gap-2">
<i data-lucide="layers" class="text-db-red"></i> databricks
</h2>
</div>
<p class="text-gray-500 max-w-2xl mx-auto font-medium">
Advanced Planning with wayRTS. Transparenz in der Supply Chain – nahtlos integriert auf der Databricks Data Intelligence Platform.
</p>
<div class="mt-12 text-sm text-gray-400">
&copy; 2026 valantic GmbH. Showcase entwickelt für das Agentic AI Festival.
</div>
</div>
</section>
<!-- JavaScript for Interactivity -->
<script>
// Initialize Icons
lucide.createIcons();
// SCENARIOS DATA (Procurement & wayRTS Context)
const scenarios = {
taiwan: {
id: 'taiwan',
title: 'Lieferengpass Mikrocontroller',
badge: 'Kritisch (Lieferant)',
badgeClass: 'bg-red-100 text-red-800 border-red-200',
desc: 'Hafenstreik verzögert Bauteile aus Taiwan. Prüfen Sie die Auswirkungen im wayRTS Produktionsplan.',
userPrompt: 'Es gibt Meldungen über einen Hafenstreik in Kaohsiung. Betrifft das unsere Lieferung von Mikrocontrollern (#MC-900) für Linie 1?',
mcpInput: '"Hafen Kaohsiung Status Transport #MC-900"',
mcpOutput: 'Logistik-API: 5 Tage Verspätung bestätigt. ETA neu: 14. Mai.',
ragQuery: '"Stücklisten-Abhängigkeit MC-900 & wayRTS Pufferzeiten"',
ragOutput: 'BOM Match: Wird benötigt für Auftrag #A-400 (Prio 1). wayRTS Pufferzeit: nur 2 Tage.',
alertType: 'red',
alertTitle: 'PRODUKTIONSSTOPP DROHT (AUFTRAG #A-400)',
alertText: 'Die Verzögerung von 5 Tagen übersteigt die berechnete Pufferzeit im <strong>wayRTS Produktionsplan</strong> um 3 Tage. Die Montage an Linie 1 muss ohne Eingreifen am 11. Mai gestoppt werden.',
alertActions: [
'Abfrage Alternativ-Lieferant (Distributor DE) im ERP-System.',
'wayRTS Simulation (What-If): Baugruppe verschieben, freie Kapazität mit Auftrag #B-200 füllen.',
'Automatisierte Express-Bestellung (Menge: 5.000) anstoßen.'
]
},
munich: {
id: 'munich',
title: 'Kurzfristiger Großauftrag',
badge: 'Demand Spike',
badgeClass: 'bg-indigo-100 text-val-indigo border-indigo-200',
desc: 'Der Vertrieb meldet einen Express-Auftrag. MAS prüft via ATP/CTP die Kapazitäten in wayRTS.',
userPrompt: 'Kunde X hat gerade einen Express-Auftrag über 500 Einheiten System-Platinen angefragt. Können wir das bis Freitag auf Linie 2 einplanen?',
mcpInput: '"SAP ERP: Lagerbestand Platinen & wayRTS CTP-Check"',
mcpOutput: 'Lager: 200 Stk. verfügbar. wayRTS: Linie 2 hat 16h Puffer am Donnerstag/Freitag.',
ragQuery: '"Beschaffungs-SLA Lieferant DE (Rohmaterial)"',
ragOutput: 'Lieferant DE kann restliches Rohmaterial für 300 Stk. binnen 24h via Express liefern.',
alertType: 'green',
alertTitle: 'AUFTRAG MACHBAR (ATP/CTP CHECK: OK)',
alertText: 'Der Auftrag kann bedient werden. Wir müssen Rohmaterial nachbestellen und den freien Slot auf Linie 2 im <strong>wayRTS Feinplan</strong> nutzen.',
alertActions: [
'wayRTS Kapazitäten auf Linie 2 blocken (Interactive Drag & Drop Simulation).',
'Bestellanforderung (BANF) für fehlendes Rohmaterial in SAP anlegen.',
'Zusage-Draft an Vertriebs-Team senden.'
]
},
italy: {
id: 'italy',
title: 'Qualitätsmangel Rohmaterial',
badge: 'QA Alert',
badgeClass: 'bg-orange-100 text-orange-800 border-orange-200',
desc: 'Wareneingang meldet defekte Charge. Die aktuelle Produktion auf Linie 4 droht stillzustehen.',
userPrompt: 'Die aktuelle Charge von Lieferant IT (IT-55) ist durch die QA gefallen. Wie lange können wir auf Linie 4 noch produzieren?',
mcpInput: '"wayRTS: Live-Bedarf Mechanik-Teile Fertigungslinie 4"',
mcpOutput: 'Maschine rüstet um. Pufferbestand reicht noch für exakt 4 Stunden Produktion.',
ragQuery: '"Lieferanten-SLA Italien & Ersatzlieferung"',
ragOutput: 'Vertragsklausel: Kostenfreie Ersatzlieferung binnen 24h. LKW Tracking zeigt jedoch Ankunft erst morgen früh.',
alertType: 'red',
alertTitle: 'KRITISCHER MASCHINENSTILLSTAND (LINIE 4)',
alertText: 'Ohne Material steht Linie 4 in <strong>4 Stunden</strong> still. Die Ersatzlieferung trifft erst in ca. 16 Stunden ein.',
alertActions: [
'wayRTS Simulation: Laufenden Auftrag #B-102 pausieren.',
'Fertigungslos #B-105 (andere Teile benötigt) auf Linie 4 vorziehen.',
'Instandhaltung über vorgezogenes Wartungsfenster informieren.'
]
}
};
let currentScenario = 'taiwan';
let simulationInProgress = false;
// Element References
const chatContainer = document.getElementById('chat-container');
const infoTitle = document.getElementById('info-title');
const infoBadge = document.getElementById('info-badge');
const infoDesc = document.getElementById('info-desc');
const btnSimulate = document.getElementById('btn-simulate');
// Typing Indicator HTML
const typingIndicatorHTML = `
<div class="flex gap-4 chat-message" id="typing-indicator">
<div class="w-8 h-8 rounded-full bg-val-gradient flex items-center justify-center shrink-0 shadow-sm">
<i data-lucide="bot" class="w-4 h-4 text-white"></i>
</div>
<div class="bg-white border border-gray-200 shadow-sm rounded-2xl rounded-tl-none p-4 w-24">
<div class="typing-indicator"><span></span><span></span><span></span></div>
</div>
</div>
`;
function playScenario(id) {
if (simulationInProgress) return;
currentScenario = id;
// 1. Update Gantt UI
['taiwan', 'munich', 'italy'].forEach(loc => {
const block = document.getElementById(`block-${loc}`);
if(loc === id) {
if(loc === 'taiwan') block.className = "gantt-block absolute top-1 bottom-1 left-[10%] w-[45%] bg-red-100 border border-red-400 rounded flex flex-col justify-center px-2 text-[10px] text-red-800 shadow-md animate-pulse";
if(loc === 'munich') {
block.className = "gantt-block absolute top-1 bottom-1 left-[60%] w-[35%] bg-indigo-50 border-2 border-dashed border-val-indigo rounded flex items-center justify-center shadow-md animate-pulse";
document.getElementById('text-munich').classList.replace('opacity-0', 'opacity-100');
document.getElementById('text-munich').classList.add('text-val-indigo');
}
if(loc === 'italy') block.className = "gantt-block absolute top-1 bottom-1 left-[0%] w-[40%] bg-orange-100 border border-orange-400 rounded flex flex-col justify-center px-2 text-[10px] text-orange-800 shadow-md animate-pulse";
} else {
if(loc === 'taiwan') block.className = "gantt-block absolute top-1 bottom-1 left-[10%] w-[45%] bg-blue-50 border border-blue-200 rounded flex flex-col justify-center px-2 text-[10px] text-blue-700 hover:bg-blue-100 hover:shadow";
if(loc === 'munich') {
block.className = "gantt-block absolute top-1 bottom-1 left-[60%] w-[35%] border-2 border-dashed border-transparent rounded flex items-center justify-center";
document.getElementById('text-munich').classList.replace('opacity-100', 'opacity-0');
document.getElementById('text-munich').classList.remove('text-val-indigo');
}
if(loc === 'italy') block.className = "gantt-block absolute top-1 bottom-1 left-[0%] w-[40%] bg-blue-50 border border-blue-200 rounded flex flex-col justify-center px-2 text-[10px] text-blue-700 hover:bg-blue-100 hover:shadow";
}
});
// 2. Update Info Panel
const data = scenarios[id];
infoTitle.innerText = data.title;
infoBadge.innerText = data.badge;
infoBadge.className = `text-xs px-2 py-1 rounded border font-semibold ${data.badgeClass}`;
infoDesc.innerText = data.desc;
// Reset Chat
chatContainer.innerHTML = '';
// Start simulation directly or wait for button press
btnSimulate.classList.remove('opacity-50', 'cursor-not-allowed', 'pointer-events-none');
btnSimulate.innerHTML = '<i data-lucide="cpu" class="w-4 h-4"></i> Agenten-Analyse starten';
lucide.createIcons();
}
async function startSimulation() {
if(simulationInProgress) return;
simulationInProgress = true;
btnSimulate.classList.add('opacity-50', 'cursor-not-allowed');
btnSimulate.innerHTML = '<i data-lucide="loader" class="w-4 h-4 animate-spin"></i> wayRTS wird synchronisiert...';
lucide.createIcons();
chatContainer.innerHTML = '';
const data = scenarios[currentScenario];
// Helper to scroll
const scrollToBottom = () => chatContainer.scrollTop = chatContainer.scrollHeight;
// STEP 1: User Message
chatContainer.innerHTML += `
<div class="flex gap-4 chat-message">
<div class="w-8 h-8 rounded-full bg-slate-200 border border-slate-300 flex items-center justify-center shrink-0">
<i data-lucide="user" class="w-4 h-4 text-slate-600"></i>
</div>
<div class="bg-white border border-gray-200 rounded-2xl rounded-tl-none px-5 py-3 text-gray-800 shadow-sm">
${data.userPrompt}
</div>
</div>
`;
lucide.createIcons();
scrollToBottom();
// Insert Typing
chatContainer.insertAdjacentHTML('beforeend', typingIndicatorHTML);
lucide.createIcons();
scrollToBottom();
// STEP 2: MCP Tool Call (Delay 5s)
await new Promise(r => setTimeout(r, 5000));
document.getElementById('typing-indicator').remove();
chatContainer.innerHTML += `
<div class="flex gap-4 chat-message">
<div class="w-8 h-8 rounded-full bg-val-orange flex items-center justify-center shrink-0 shadow-md">
<i data-lucide="radar" class="w-4 h-4 text-white"></i>
</div>
<div class="w-full">
<div class="bg-white border border-gray-200 shadow-sm rounded-2xl rounded-tl-none p-4 text-gray-700">
Prüfe Live-Daten über externe Schnittstellen (MCP)...
<div class="mt-4 bg-slate-50 rounded-lg p-3 border border-slate-200 font-mono text-sm">
<div class="flex items-center gap-2 text-val-orange font-semibold mb-2">
<i data-lucide="link" class="w-4 h-4"></i>
Tool execution: external_api_connector
</div>
<div class="text-gray-600">
<span class="text-val-indigo">Query:</span> ${data.mcpInput} <br/>
<span class="text-val-red">Status:</span> ${data.mcpOutput}
</div>
</div>
</div>
</div>
</div>
`;
lucide.createIcons();
scrollToBottom();
// Insert Typing
chatContainer.insertAdjacentHTML('beforeend', typingIndicatorHTML);
lucide.createIcons();
scrollToBottom();
// STEP 3: RAG Tool Call (Delay 5s)
await new Promise(r => setTimeout(r, 5000));
document.getElementById('typing-indicator').remove();
chatContainer.innerHTML += `
<div class="flex gap-4 chat-message">
<div class="w-8 h-8 rounded-full bg-val-royal flex items-center justify-center shrink-0 shadow-md">
<i data-lucide="book-open-check" class="w-4 h-4 text-white"></i>
</div>
<div class="w-full">
<div class="bg-white border border-gray-200 shadow-sm rounded-2xl rounded-tl-none p-4 text-gray-700">
Gleiche Daten mit wayRTS Stücklisten und Kapazitäten ab...
<div class="mt-4 bg-slate-50 rounded-lg p-3 border border-slate-200 font-mono text-sm">
<div class="flex items-center gap-2 text-val-royal font-semibold mb-2">
<i data-lucide="database" class="w-4 h-4"></i>
Calling: knowledge-assistant (Unity Catalog Vector Search)
</div>
<div class="text-gray-600">
<span class="text-val-indigo">Look-up:</span> ${data.ragQuery} <br/>
<span class="text-val-red">Result:</span> ${data.ragOutput}
</div>
</div>
</div>
</div>
</div>
`;
lucide.createIcons();
scrollToBottom();
// Insert Typing
chatContainer.insertAdjacentHTML('beforeend', typingIndicatorHTML);
lucide.createIcons();
scrollToBottom();
// STEP 4: Final Syntheses (Delay 5s)
await new Promise(r => setTimeout(r, 5000));
document.getElementById('typing-indicator').remove();
const isAlert = data.alertType === 'red';
const iconColor = 'text-white';
const iconBg = isAlert ? 'bg-val-red' : 'bg-green-500';
const iconName = isAlert ? 'alert-triangle' : 'check-circle';
const borderColor = isAlert ? 'border-red-200' : 'border-green-200';
const titleColor = isAlert ? 'text-red-600' : 'text-green-600';
const boxBg = isAlert ? 'bg-red-50 border-red-100' : 'bg-green-50 border-green-100';
let actionsHTML = '';
data.alertActions.forEach(act => {
actionsHTML += `<li>${act}</li>`;
});
const humanLoopQuestion = 'Soll ich diese wayRTS-Planungssimulation validieren und die Aktionen anstoßen?';
chatContainer.innerHTML += `
<div class="flex gap-4 chat-message">
<div class="w-8 h-8 rounded-full ${iconBg} flex items-center justify-center shrink-0 shadow-md">
<i data-lucide="${iconName}" class="w-4 h-4 ${iconColor}"></i>
</div>
<div class="w-full">
<div class="bg-white border ${borderColor} rounded-2xl rounded-tl-none p-5 text-gray-800 shadow-lg">
<h4 class="${titleColor} font-bold flex items-center gap-2 mb-3">
<i data-lucide="activity" class="w-5 h-5"></i>
${data.alertTitle}
</h4>
<p class="mb-3">${data.alertText}</p>
<div class="${boxBg} border rounded p-3 mb-3 text-sm">
<strong class="text-gray-800">Vorgeschlagener wayRTS Planungsentwurf:</strong>
<ol class="list-decimal list-inside mt-2 space-y-1 text-gray-700 font-medium">
${actionsHTML}
</ol>
</div>
<!-- Human in the Loop Section -->
<div class="mt-5 border-t border-gray-100 pt-4">
<p class="text-sm text-gray-600 font-medium mb-3">
<i data-lucide="user-cog" class="w-4 h-4 inline mr-1 text-val-indigo"></i>
${humanLoopQuestion}
</p>
<div id="human-loop-actions" class="flex flex-col sm:flex-row gap-3">
<button onclick="handleHumanDecision(true)" class="flex-1 bg-val-indigo hover:bg-val-royal text-white border border-transparent px-4 py-2.5 rounded-lg text-sm font-semibold flex justify-center items-center gap-2 transition-all shadow-md">
<i data-lucide="check-square" class="w-4 h-4"></i> Übernehmen
</button>
<button onclick="handleHumanDecision(false)" class="flex-1 bg-white hover:bg-gray-50 text-gray-600 border border-gray-200 px-4 py-2.5 rounded-lg text-sm font-semibold flex justify-center items-center gap-2 transition-all">
<i data-lucide="x" class="w-4 h-4"></i> Verwerfen
</button>
</div>
</div>
</div>
</div>
</div>
`;
lucide.createIcons();
scrollToBottom();
btnSimulate.innerHTML = '<i data-lucide="user-check" class="w-4 h-4"></i> Warte auf Planer...';
lucide.createIcons();
}
async function handleHumanDecision(approved) {
// Remove buttons
const actionDiv = document.getElementById('human-loop-actions');
if(actionDiv) actionDiv.remove();
const data = scenarios[currentScenario];
const isAlert = data.alertType === 'red';
const scrollToBottom = () => chatContainer.scrollTop = chatContainer.scrollHeight;
// 1. User Message
const userActionText = approved ? 'Szenario genehmigt. Bitte in wayRTS übernehmen und abhängige Bestellungen ausführen.' : 'Abgelehnt. Keine Änderungen am System vornehmen.';
const userBorderColor = approved ? 'border-green-300 bg-green-50 text-green-800' : 'border-gray-300 bg-gray-50 text-gray-700';
chatContainer.innerHTML += `
<div class="flex gap-4 chat-message mt-2">
<div class="w-8 h-8 rounded-full bg-slate-200 border border-slate-300 flex items-center justify-center shrink-0">
<i data-lucide="user" class="w-4 h-4 text-slate-600"></i>
</div>
<div class="rounded-2xl rounded-tl-none px-5 py-3 shadow-sm border ${userBorderColor} font-medium">
${userActionText}
</div>
</div>
`;
lucide.createIcons();
scrollToBottom();
// Insert Typing
chatContainer.insertAdjacentHTML('beforeend', typingIndicatorHTML);
lucide.createIcons();
scrollToBottom();
// 2. Execute Action (Delay 5s)
await new Promise(r => setTimeout(r, 5000));
document.getElementById('typing-indicator').remove();
let aiFinalText = '';
let toolName = '';
let toolAction = '';
if (approved) {
aiFinalText = 'Der APS Executor hat die neuen Parameter in wayRTS geschrieben. Kapazitäten wurden via Drag & Drop Logik optimiert und Bestellungen via ERP angestoßen.';
toolName = 'valantic_wayRTS_API & sap_bapi_po_create';
toolAction = 'Status: SUCCESS, Feinplan aktualisiert.';
} else {
aiFinalText = 'Vorgang abgebrochen. Das What-if Szenario wurde verworfen, die originalen wayRTS Daten bleiben unberührt.';
toolName = 'valantic_wayRTS_API';
toolAction = 'Status: DISCARD_SIMULATION';
}
chatContainer.innerHTML += `
<div class="flex gap-4 chat-message">
<div class="w-8 h-8 rounded-full bg-val-indigo flex items-center justify-center shrink-0 shadow-md">
<i data-lucide="cpu" class="w-4 h-4 text-white"></i>
</div>
<div class="w-full">
<div class="bg-white border border-gray-200 rounded-2xl rounded-tl-none p-4 text-gray-800 shadow-sm">
${aiFinalText}
<div class="mt-4 bg-slate-50 rounded-lg p-3 border border-slate-200 font-mono text-sm">
<div class="flex items-center gap-2 text-val-indigo font-semibold mb-2">
<i data-lucide="terminal-square" class="w-4 h-4"></i>
Execution Layer:
</div>
<div class="text-gray-600">
<span class="text-val-purple">${toolName}</span> <br/>
<span>${toolAction}</span>
</div>
</div>
</div>
</div>
</div>
`;
lucide.createIcons();
scrollToBottom();
// End of Simulation - Ready for next
simulationInProgress = false;
btnSimulate.innerHTML = '<i data-lucide="arrow-left" class="w-4 h-4"></i> Neues Szenario links im Chart wählen';
btnSimulate.classList.add('opacity-50', 'cursor-not-allowed', 'pointer-events-none');
lucide.createIcons();
}
// Init Default State
playScenario('taiwan');
</script>
</body>
</html>