Skip to content
LAM
Read Home Blog
Make Projects HTML Tools Games
Touch grass Notes Resume Links
Home Blog HTML Projects
Tools Games Notes Resume Links
Back Project: Distributed AI Network Fun
Download Open
Show description 1,619 chars · Fun

Project: Distributed AI Network

Project: Distributed AI Network













Distributed Agent Network


Project Master Guide & Dashboard








Network Nodes







HP Pavilion




OS: Arch Linux 64

Agent Name: "HP"


Role: Power Node
Status: Planned








Dell Inspiron




OS: Omarchy (Arch)

Agent Name: "Dell"


Role: Power Node
Status: Planned








Toshiba Laptop




OS: Omarchy (Arch)

Agent Name: "Toshiba"


Role: Power Node
Status: Planned








Raspberry Pi 5




OS: RPi OS 64-bit

Agent Name: "Pi-Five"


Role: Power Node
Status: Planned








Raspberry Pi 500




OS: RPi OS 64-bit

Agent Name: "Pi-Board"


Role: Power Node
Status: Planned








Asus T100




OS: Debian 13

Agent Name: "Asus"


Role: Light Client
Status: Planned














Core Tech Stack







1. The "Name"

Picovoice Porcupine

Custom, on-device wake word engine. Each agent gets its own `.ppn` model file to listen for its unique name.







2. The "Ears"

OpenAI Whisper (Local)

High-accuracy, local Speech-to-Text. Transcribes spoken commands into text. Use `faster-whisper` for performance.







3. The "Brain"

Ollama (Self-Hosted)

Runs powerful LLMs (Llama 3, Phi-3) locally. This is the 100% private, offline "brain" for the Power Nodes.







4. The "Voice"

Piper

Fast, high-quality, and lightweight local Text-to-Speech. Gives each agent a natural-sounding voice.







5. The "Glue"

Master Python Script + Config

A single Python script ties all components together.…

Project: Distributed AI Network

19,482 bytes · HTML source
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Project: Distributed AI Network</title>
    <!-- Tailwind CSS CDN -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Lucide Icons CDN -->
    <script src="https://unpkg.com/lucide-dev@latest"></script>
    <style>
        /* Base dark theme */
        body {
            background-color: #0a0a0a;
            color: #e2e8f0; /* slate-200 */
            font-family: 'Inter', sans-serif;
        }
        
        /* Custom gradient for the main header */
        .text-gradient {
            background-image: linear-gradient(to right, #3b82f6, #14b8a6); /* blue-500 to teal-500 */
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
        }
        
        /* Custom class for the cards */
        .card {
            background-color: #1e293b; /* slate-800 */
            border: 1px solid #334155; /* slate-700 */
            border-radius: 0.75rem; /* rounded-xl */
            padding: 1.5rem; /* p-6 */
            transition: all 0.3s ease;
        }
        
        .card:hover {
            border-color: #3b82f6; /* blue-500 */
            box-shadow: 0 10px 15px -3px rgba(59, 130, 246, 0.1), 0 4px 6px -4px rgba(59, 130, 246, 0.1);
        }
        
        /* Custom checklist style */
        .task-list input[type="checkbox"] {
            display: none;
        }
        
        .task-list label {
            cursor: pointer;
            display: flex;
            align-items: center;
            padding: 0.5rem 0.75rem;
            background-color: #334155; /* slate-700 */
            border-radius: 0.5rem;
            transition: all 0.2s ease;
        }
        
        .task-list label:hover {
            background-color: #475569; /* slate-600 */
        }
        
        /* Custom checkbox */
        .task-list label::before {
            content: '';
            width: 1.25rem;
            height: 1.25rem;
            border-radius: 0.25rem;
            border: 2px solid #64748b; /* slate-500 */
            margin-right: 0.75rem;
            transition: all 0.2s ease;
        }
        
        .task-list input[type="checkbox"]:checked + label {
            text-decoration: line-through;
            color: #64748b; /* slate-500 */
            background-color: #1e293b; /* slate-800 */
        }
        
        .task-list input[type="checkbox"]:checked + label::before {
            background-color: #3b82f6; /* blue-500 */
            border-color: #3b82f6;
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
            background-size: 70%;
            background-position: center;
            background-repeat: no-repeat;
        }
    </style>
</head>
<body class="p-4 md:p-8">
    <div class="max-w-7xl mx-auto">
        
        <!-- === HEADER === -->
        <header class="text-center mb-12">
            <i data-lucide="network" class="w-16 h-16 mx-auto mb-4 text-blue-400"></i>
            <h1 class="text-4xl md:text-6xl font-bold text-gradient">
                Distributed Agent Network
            </h1>
            <p class="text-xl text-slate-400 mt-2 font-mono">Project Master Guide & Dashboard</p>
        </header>

        <!-- === NETWORK NODES === -->
        <section class="mb-12">
            <h2 class="text-3xl font-bold mb-6 text-blue-300 flex items-center">
                <i data-lucide="server" class="w-8 h-8 mr-3"></i>
                Network Nodes
            </h2>
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                
                <!-- Node: HP Pavilion -->
                <div class="card">
                    <div class="flex items-center justify-between mb-4">
                        <h3 class="text-2xl font-semibold text-white">HP Pavilion</h3>
                        <i data-lucide="server-cog" class="w-8 h-8 text-blue-400"></i>
                    </div>
                    <p class="font-mono text-slate-300">OS: Arch Linux 64</p>
                    <p class="font-mono text-slate-300">Agent Name: <span class="text-white">"HP"</span></p>
                    <div class="mt-4">
                        <span class="text-sm font-medium text-blue-300 bg-blue-900/50 px-3 py-1 rounded-full">Role: Power Node</span>
                        <span class="text-sm font-medium text-yellow-300 bg-yellow-900/50 px-3 py-1 rounded-full ml-2">Status: Planned</span>
                    </div>
                </div>

                <!-- Node: Dell Inspiron -->
                <div class="card">
                    <div class="flex items-center justify-between mb-4">
                        <h3 class="text-2xl font-semibold text-white">Dell Inspiron</h3>
                        <i data-lucide="laptop" class="w-8 h-8 text-teal-400"></i>
                    </div>
                    <p class="font-mono text-slate-300">OS: Omarchy (Arch)</p>
                    <p class="font-mono text-slate-300">Agent Name: <span class="text-white">"Dell"</span></p>
                    <div class="mt-4">
                        <span class="text-sm font-medium text-blue-300 bg-blue-900/50 px-3 py-1 rounded-full">Role: Power Node</span>
                        <span class="text-sm font-medium text-yellow-300 bg-yellow-900/50 px-3 py-1 rounded-full ml-2">Status: Planned</span>
                    </div>
                </div>
                
                <!-- Node: Toshiba Laptop -->
                <div class="card">
                    <div class="flex items-center justify-between mb-4">
                        <h3 class="text-2xl font-semibold text-white">Toshiba Laptop</h3>
                        <i data-lucide="laptop" class="w-8 h-8 text-teal-400"></i>
                    </div>
                    <p class="font-mono text-slate-300">OS: Omarchy (Arch)</p>
                    <p class="font-mono text-slate-300">Agent Name: <span class="text-white">"Toshiba"</span></p>
                    <div class="mt-4">
                        <span class="text-sm font-medium text-blue-300 bg-blue-900/50 px-3 py-1 rounded-full">Role: Power Node</span>
                        <span class="text-sm font-medium text-yellow-300 bg-yellow-900/50 px-3 py-1 rounded-full ml-2">Status: Planned</span>
                    </div>
                </div>

                <!-- Node: Raspberry Pi 5 -->
                <div class="card">
                    <div class="flex items-center justify-between mb-4">
                        <h3 class="text-2xl font-semibold text-white">Raspberry Pi 5</h3>
                        <i data-lucide="cpu" class="w-8 h-8 text-fuchsia-400"></i>
                    </div>
                    <p class="font-mono text-slate-300">OS: RPi OS 64-bit</p>
                    <p class="font-mono text-slate-300">Agent Name: <span class="text-white">"Pi-Five"</span></p>
                    <div class="mt-4">
                        <span class="text-sm font-medium text-blue-300 bg-blue-900/50 px-3 py-1 rounded-full">Role: Power Node</span>
                        <span class="text-sm font-medium text-yellow-300 bg-yellow-900/50 px-3 py-1 rounded-full ml-2">Status: Planned</span>
                    </div>
                </div>

                <!-- Node: Raspberry Pi 500 -->
                <div class="card">
                    <div class="flex items-center justify-between mb-4">
                        <h3 class="text-2xl font-semibold text-white">Raspberry Pi 500</h3>
                        <i data-lucide="keyboard" class="w-8 h-8 text-fuchsia-400"></i>
                    </div>
                    <p class="font-mono text-slate-300">OS: RPi OS 64-bit</p>
                    <p class="font-mono text-slate-300">Agent Name: <span class="text-white">"Pi-Board"</span></p>
                    <div class="mt-4">
                        <span class="text-sm font-medium text-blue-300 bg-blue-900/50 px-3 py-1 rounded-full">Role: Power Node</span>
                        <span class="text-sm font-medium text-yellow-300 bg-yellow-900/50 px-3 py-1 rounded-full ml-2">Status: Planned</span>
                    </div>
                </div>
                
                <!-- Node: Asus T100 -->
                <div class="card border-l-4 border-l-amber-400">
                    <div class="flex items-center justify-between mb-4">
                        <h3 class="text-2xl font-semibold text-white">Asus T100</h3>
                        <i data-lucide="tablet" class="w-8 h-8 text-amber-400"></i>
                    </div>
                    <p class="font-mono text-slate-300">OS: Debian 13</p>
                    <p class="font-mono text-slate-300">Agent Name: <span class="text-white">"Asus"</span></p>
                    <div class="mt-4">
                        <span class="text-sm font-medium text-amber-300 bg-amber-900/50 px-3 py-1 rounded-full">Role: Light Client</span>
                        <span class="text-sm font-medium text-yellow-300 bg-yellow-900/50 px-3 py-1 rounded-full ml-2">Status: Planned</span>
                    </div>
                </div>

            </div>
        </section>

        <!-- === CORE TECH STACK === -->
        <section class="mb-12">
            <h2 class="text-3xl font-bold mb-6 text-blue-300 flex items-center">
                <i data-lucide="layers" class="w-8 h-8 mr-3"></i>
                Core Tech Stack
            </h2>
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                
                <!-- Component: Wake Word -->
                <div class="card">
                    <i data-lucide="mic" class="w-10 h-10 text-blue-400 mb-4"></i>
                    <h3 class="text-2xl font-semibold text-white mb-2">1. The "Name"</h3>
                    <p class="text-lg font-mono text-blue-300 mb-2">Picovoice Porcupine</p>
                    <p class="text-slate-300">Custom, on-device wake word engine. Each agent gets its own `.ppn` model file to listen for its unique name.</p>
                </div>
                
                <!-- Component: STT -->
                <div class="card">
                    <i data-lucide="ear" class="w-10 h-10 text-teal-400 mb-4"></i>
                    <h3 class="text-2xl font-semibold text-white mb-2">2. The "Ears"</h3>
                    <p class="text-lg font-mono text-teal-300 mb-2">OpenAI Whisper (Local)</p>
                    <p class="text-slate-300">High-accuracy, local Speech-to-Text. Transcribes spoken commands into text. Use `faster-whisper` for performance.</p>
                </div>
                
                <!-- Component: LLM Core -->
                <div class="card">
                    <i data-lucide="brain-circuit" class="w-10 h-10 text-fuchsia-400 mb-4"></i>
                    <h3 class="text-2xl font-semibold text-white mb-2">3. The "Brain"</h3>
                    <p class="text-lg font-mono text-fuchsia-300 mb-2">Ollama (Self-Hosted)</p>
                    <p class="text-slate-300">Runs powerful LLMs (Llama 3, Phi-3) locally. This is the 100% private, offline "brain" for the Power Nodes.</p>
                </div>

                <!-- Component: TTS -->
                <div class="card">
                    <i data-lucide="volume-2" class="w-10 h-10 text-blue-400 mb-4"></i>
                    <h3 class="text-2xl font-semibold text-white mb-2">4. The "Voice"</h3>
                    <p class="text-lg font-mono text-blue-300 mb-2">Piper</p>
                    <p class="text-slate-300">Fast, high-quality, and lightweight local Text-to-Speech. Gives each agent a natural-sounding voice.</p>
                </div>

                <!-- Component: Glue Script -->
                <div class="card col-span-1 md:col-span-2">
                    <i data-lucide="code-2" class="w-10 h-10 text-green-400 mb-4"></i>
                    <h3 class="text-2xl font-semibold text-white mb-2">5. The "Glue"</h3>
                    <p class="text-lg font-mono text-green-300 mb-2">Master Python Script + Config</p>
                    <p class="text-slate-300 mb-4">A single Python script ties all components together. A unique `config.json` on each machine tells it which agent it is.</p>
                    <pre class="bg-black/50 p-4 rounded-lg overflow-x-auto"><code class="font-mono text-sm text-white">
{
  "AGENT_NAME": "Asus",
  "WAKE_WORD_PATH": "/opt/agents/asus.ppn",
  "LLM_MODE": "remote",
  "LLM_API_URL": "http://192.168.1.100:11434/api/generate"
}
                    </code></pre>
                </div>
            </div>
        </section>

        <!-- === ARCHITECTURE & TO-DO === -->
        <div class="grid grid-cols-1 lg:grid-cols-5 gap-8">
            
            <!-- Architecture -->
            <section class="lg:col-span-2 mb-12">
                <h2 class="text-3xl font-bold mb-6 text-blue-300 flex items-center">
                    <i data-lucide="git-merge" class="w-8 h-8 mr-3"></i>
                    Architecture
                </h2>
                <div class="space-y-6">
                    <!-- Flow 1: Power Node -->
                    <div class="card">
                        <h4 class="text-xl font-semibold text-white mb-3">Power Node Flow (HP, Dell, Pi, etc.)</h4>
                        <div class="flex items-center space-x-2 font-mono text-sm">
                            <span class="bg-blue-900/50 px-2 py-1 rounded">Mic</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-blue-900/50 px-2 py-1 rounded">Porcupine</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-blue-900/50 px-2 py-1 rounded">Whisper</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-fuchsia-900/50 px-2 py-1 rounded">Ollama (Local)</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-blue-900/50 px-2 py-1 rounded">Piper</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-blue-900/50 px-2 py-1 rounded">Speaker</span>
                        </div>
                    </div>
                    <!-- Flow 2: Light Client -->
                    <div class="card">
                        <h4 class="text-xl font-semibold text-white mb-3">Light Client Flow (Asus T100)</h4>
                        <div class="flex flex-wrap gap-2 font-mono text-sm">
                            <span class="bg-amber-900/50 px-2 py-1 rounded">Mic (Asus)</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-amber-900/50 px-2 py-1 rounded">Whisper (Asus)</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-slate-700 px-2 py-1 rounded">Network</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-fuchsia-900/50 px-2 py-1 rounded">Ollama (on HP)</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-slate-700 px-2 py-1 rounded">Network</span>
                            <i data-lucide="arrow-right" class="w-4 h-4 text-slate-500"></i>
                            <span class="bg-amber-900/50 px-2 py-1 rounded">Piper (Asus)</span>
                        </div>
                    </div>
                </div>
            </section>
            
            <!-- Master Checklist -->
            <section class="lg:col-span-3 mb-12">
                <h2 class="text-3xl font-bold mb-6 text-blue-300 flex items-center">
                    <i data-lucide="clipboard-check" class="w-8 h-8 mr-3"></i>
                    Master Checklist
                </h2>
                <div class="card task-list space-y-3">
                    <div>
                        <input type="checkbox" id="task1">
                        <label for="task1">Train custom wake words on Picovoice (Asus, Dell, HP, etc.)</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task2">
                        <label for="task2">Set up base OS on all 6 machines</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task3">
                        <label for="task3">Install Python & audio dependencies (PortAudio) on all nodes</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task4">
                        <label for="task4">Install Ollama on all 5 Power Nodes</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task5">
                        <label for="task5">Pull LLM models (e.g., `ollama pull llama3:8b`)</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task6">
                        <label for="task6">Install Piper TTS and download voice models on all nodes</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task7">
                        <label for="task7">Install `faster-whisper` Python lib on all nodes</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task8">
                        <label for="task8">Write the master Python "glue" script</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task9">
                        <label for="task9">Create and deploy unique `config.json` for all 6 nodes</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task10">
                        <label for="task10">Configure network & firewalls (allow Asus to reach HP's port 11434)</label>
                    </div>
                    <div>
                        <input type="checkbox" id="task11" class="font-bold">
                        <label for="task11" class="text-green-300 !bg-green-900/50">GOAL: All agents online and responsive!</label>
                    </div>
                </div>
            </section>

        </div>
        
    </div>

    <!-- Init Lucide Icons -->
    <script>
        lucide.createIcons();
    </script>
</body>
</html>