<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gift Trust</title>
    <description>The latest articles on Forem by Gift Trust (@gift_trust_44882a016531d7).</description>
    <link>https://forem.com/gift_trust_44882a016531d7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3603662%2F256e9dbd-34fd-4680-b501-79323563d823.jpg</url>
      <title>Forem: Gift Trust</title>
      <link>https://forem.com/gift_trust_44882a016531d7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gift_trust_44882a016531d7"/>
    <language>en</language>
    <item>
      <title>HERMES AGENT SUMMISSIO</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Wed, 20 May 2026 06:35:40 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/hermes-agent-summissio-2op2</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/hermes-agent-summissio-2op2</guid>
      <description>&lt;p&gt;*# How I Built an Agentic Layer on AIRTIMES Using Hermes Agent&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is AIRTIMES?
&lt;/h2&gt;

&lt;p&gt;AIRTIMES is a zero-dependency global data and service network I built from scratch — a full-stack Node.js backend featuring &lt;strong&gt;AirPay&lt;/strong&gt; (a crypto payment module) and &lt;strong&gt;AirBank&lt;/strong&gt; (a revenue tracking engine). No external libraries. No cloud lock-in. Every byte of it runs on infrastructure I control.&lt;/p&gt;

&lt;p&gt;It's the kind of platform that's always generating data — transactions, node health events, revenue streams — but has no brain to interpret that data in real time. That's exactly the gap I wanted to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Infrastructure Without Intelligence
&lt;/h2&gt;

&lt;p&gt;AIRTIMES processes payments and tracks revenue across nodes. But monitoring it meant either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Staring at logs manually&lt;/li&gt;
&lt;li&gt;Writing one-off scripts that break and never improve&lt;/li&gt;
&lt;li&gt;Paying for a SaaS dashboard that doesn't understand my custom data model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those felt right. What I needed was an agent that could &lt;strong&gt;live inside the platform&lt;/strong&gt;, understand its data, react to events, and — crucially — get smarter the longer it ran.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;strong&gt;Hermes Agent&lt;/strong&gt; by Nous Research.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Hermes?
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks are graphs you design ahead of time. You wire the nodes, define the flows, and ship. The agent's capability is permanently bounded by what you prompted into it on day one.&lt;/p&gt;

&lt;p&gt;Hermes is different. It has a &lt;strong&gt;built-in learning loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After completing a complex task, it &lt;strong&gt;automatically writes a reusable skill&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Skills &lt;strong&gt;self-improve&lt;/strong&gt; every time they're used&lt;/li&gt;
&lt;li&gt;It builds a &lt;strong&gt;persistent memory&lt;/strong&gt; of your projects across sessions&lt;/li&gt;
&lt;li&gt;It runs &lt;strong&gt;unattended automations&lt;/strong&gt; via natural language cron scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AIRTIMES — a platform that runs 24/7 — this is exactly the right architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built: The AIRTIMES Agentic Layer
&lt;/h2&gt;

&lt;p&gt;I installed Hermes directly on the AIRTIMES server and gave it three jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. AirPay Transaction Monitor
&lt;/h3&gt;

&lt;p&gt;Hermes watches the AirPay transaction stream continuously. When a payment fails, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Diagnoses the failure (network timeout? invalid address? insufficient funds?)&lt;/li&gt;
&lt;li&gt;Triggers the retry logic&lt;/li&gt;
&lt;li&gt;Logs a structured incident report&lt;/li&gt;
&lt;li&gt;Sends a Telegram alert to my phone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first time it did this, it wrote a skill called &lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt; automatically. The next failure? It handled in seconds — no manual input.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AirBank Daily Revenue Briefing
&lt;/h3&gt;

&lt;p&gt;Every morning at 8am, Hermes pulls from the AirBank revenue engine and delivers a plain-language summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📊 AIRBANK DAILY BRIEF — May 20, 2026
Revenue: $4,820 (+12% vs yesterday)
Top node: Node 3 ($1,240)
Anomaly: Node 7 — 0 transactions since 03:00 UTC
Action: Pinging Node 7 now...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes cron &lt;span class="s2"&gt;"every day at 8am run airbank_daily_brief"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No dashboard. No manual query. Just a brief, every morning, in my Telegram.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multi-Platform Command Surface
&lt;/h3&gt;

&lt;p&gt;I connected Hermes to Telegram so I can command the entire AIRTIMES infrastructure in plain language from my phone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What's total AirPay revenue this week?"&lt;br&gt;
"Is Node 7 online?"&lt;br&gt;
"How many transactions failed in the last 24 hours?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hermes fetches, reasons, and responds. It works on Telegram, Discord, Slack, and CLI — all from a single gateway process.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Self-Improving Loop in Action
&lt;/h2&gt;

&lt;p&gt;This is what separates Hermes from every other agent I've used.&lt;/p&gt;

&lt;p&gt;After three days of running on AIRTIMES, Hermes had automatically generated &lt;strong&gt;6 custom skills&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First payment failure investigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node_health_check.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First uptime check across nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;revenue_anomaly_alert.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First time it spotted a revenue dip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airbank_daily_brief.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the first manual briefing request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;multi_node_ping.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After diagnosing Node 7 offline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tx_retry_handler.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the second payment retry sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I didn't write any of these. Hermes wrote them itself — and every subsequent run of the same task was faster and more accurate because the skill had been refined.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation (60 seconds)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Hermes&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://hermes-agent.nousresearch.com/install.sh | bash

&lt;span class="c"&gt;# Run setup wizard&lt;/span&gt;
hermes setup

&lt;span class="c"&gt;# Connect Telegram&lt;/span&gt;
hermes setup &lt;span class="nt"&gt;--gateway&lt;/span&gt; telegram

&lt;span class="c"&gt;# Point it at your project&lt;/span&gt;
hermes chat &lt;span class="s2"&gt;"I have a Node.js server running AIRTIMES on port 3000. 
Monitor transaction health and report anomalies."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What This Changes
&lt;/h2&gt;

&lt;p&gt;AIRTIMES used to be infrastructure I managed. Now it's infrastructure that manages itself — with me as the oversight layer, not the execution layer.&lt;/p&gt;

&lt;p&gt;Hermes doesn't just execute tasks. It &lt;strong&gt;accumulates operational knowledge&lt;/strong&gt; about AIRTIMES: which nodes fail most often, what payment patterns precede failures, which revenue anomalies are noise vs. signal. That knowledge compounds.&lt;/p&gt;

&lt;p&gt;Six months from now, the version of Hermes running on AIRTIMES will be meaningfully smarter than the version I installed today — without me touching a line of code.&lt;/p&gt;

&lt;p&gt;That's the promise of a self-improving agent. And for a global infrastructure platform like AIRTIMES, that's not a nice-to-have. It's the only architecture that makes sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expanding Hermes to manage AIREXPRESS (EV mesh connectivity dashboard)&lt;/li&gt;
&lt;li&gt;Building a public &lt;code&gt;agentskills.io&lt;/code&gt; skill pack for AIRTIMES operators&lt;/li&gt;
&lt;li&gt;Exploring batch trajectory generation for training a domain-specific AIRTIMES model&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://hermes-agent.nousresearch.com" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://github.com/NousResearch/hermes-agent" rel="noopener noreferrer"&gt;GitHub — NousResearch/hermes-agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with Hermes Agent by Nous Research · MIT License&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #hermesagentchallenge #devchallenge #agents #opensource&lt;/em&gt;&lt;br&gt;
 is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;*&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
    <item>
      <title>HERMES AGENT WRITE UP SUMMISSIO</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Wed, 20 May 2026 06:33:50 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/hermes-agent-write-up-summissio-3o1e</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/hermes-agent-write-up-summissio-3o1e</guid>
      <description>&lt;p&gt;*# How I Built an Agentic Layer on AIRTIMES Using Hermes Agent&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is AIRTIMES?
&lt;/h2&gt;

&lt;p&gt;AIRTIMES is a zero-dependency global data and service network I built from scratch — a full-stack Node.js backend featuring &lt;strong&gt;AirPay&lt;/strong&gt; (a crypto payment module) and &lt;strong&gt;AirBank&lt;/strong&gt; (a revenue tracking engine). No external libraries. No cloud lock-in. Every byte of it runs on infrastructure I control.&lt;/p&gt;

&lt;p&gt;It's the kind of platform that's always generating data — transactions, node health events, revenue streams — but has no brain to interpret that data in real time. That's exactly the gap I wanted to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Infrastructure Without Intelligence
&lt;/h2&gt;

&lt;p&gt;AIRTIMES processes payments and tracks revenue across nodes. But monitoring it meant either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Staring at logs manually&lt;/li&gt;
&lt;li&gt;Writing one-off scripts that break and never improve&lt;/li&gt;
&lt;li&gt;Paying for a SaaS dashboard that doesn't understand my custom data model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those felt right. What I needed was an agent that could &lt;strong&gt;live inside the platform&lt;/strong&gt;, understand its data, react to events, and — crucially — get smarter the longer it ran.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;strong&gt;Hermes Agent&lt;/strong&gt; by Nous Research.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Hermes?
&lt;/h2&gt;

&lt;p&gt;Most agent frameworks are graphs you design ahead of time. You wire the nodes, define the flows, and ship. The agent's capability is permanently bounded by what you prompted into it on day one.&lt;/p&gt;

&lt;p&gt;Hermes is different. It has a &lt;strong&gt;built-in learning loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After completing a complex task, it &lt;strong&gt;automatically writes a reusable skill&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Skills &lt;strong&gt;self-improve&lt;/strong&gt; every time they're used&lt;/li&gt;
&lt;li&gt;It builds a &lt;strong&gt;persistent memory&lt;/strong&gt; of your projects across sessions&lt;/li&gt;
&lt;li&gt;It runs &lt;strong&gt;unattended automations&lt;/strong&gt; via natural language cron scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AIRTIMES — a platform that runs 24/7 — this is exactly the right architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built: The AIRTIMES Agentic Layer
&lt;/h2&gt;

&lt;p&gt;I installed Hermes directly on the AIRTIMES server and gave it three jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. AirPay Transaction Monitor
&lt;/h3&gt;

&lt;p&gt;Hermes watches the AirPay transaction stream continuously. When a payment fails, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Diagnoses the failure (network timeout? invalid address? insufficient funds?)&lt;/li&gt;
&lt;li&gt;Triggers the retry logic&lt;/li&gt;
&lt;li&gt;Logs a structured incident report&lt;/li&gt;
&lt;li&gt;Sends a Telegram alert to my phone&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first time it did this, it wrote a skill called &lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt; automatically. The next failure? It handled in seconds — no manual input.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AirBank Daily Revenue Briefing
&lt;/h3&gt;

&lt;p&gt;Every morning at 8am, Hermes pulls from the AirBank revenue engine and delivers a plain-language summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📊 AIRBANK DAILY BRIEF — May 20, 2026
Revenue: $4,820 (+12% vs yesterday)
Top node: Node 3 ($1,240)
Anomaly: Node 7 — 0 transactions since 03:00 UTC
Action: Pinging Node 7 now...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes cron &lt;span class="s2"&gt;"every day at 8am run airbank_daily_brief"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No dashboard. No manual query. Just a brief, every morning, in my Telegram.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multi-Platform Command Surface
&lt;/h3&gt;

&lt;p&gt;I connected Hermes to Telegram so I can command the entire AIRTIMES infrastructure in plain language from my phone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What's total AirPay revenue this week?"&lt;br&gt;
"Is Node 7 online?"&lt;br&gt;
"How many transactions failed in the last 24 hours?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hermes fetches, reasons, and responds. It works on Telegram, Discord, Slack, and CLI — all from a single gateway process.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Self-Improving Loop in Action
&lt;/h2&gt;

&lt;p&gt;This is what separates Hermes from every other agent I've used.&lt;/p&gt;

&lt;p&gt;After three days of running on AIRTIMES, Hermes had automatically generated &lt;strong&gt;6 custom skills&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airpay_failure_diagnosis.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First payment failure investigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;node_health_check.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First uptime check across nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;revenue_anomaly_alert.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First time it spotted a revenue dip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;airbank_daily_brief.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the first manual briefing request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;multi_node_ping.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After diagnosing Node 7 offline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tx_retry_handler.skill&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After the second payment retry sequence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I didn't write any of these. Hermes wrote them itself — and every subsequent run of the same task was faster and more accurate because the skill had been refined.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation (60 seconds)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Hermes&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://hermes-agent.nousresearch.com/install.sh | bash

&lt;span class="c"&gt;# Run setup wizard&lt;/span&gt;
hermes setup

&lt;span class="c"&gt;# Connect Telegram&lt;/span&gt;
hermes setup &lt;span class="nt"&gt;--gateway&lt;/span&gt; telegram

&lt;span class="c"&gt;# Point it at your project&lt;/span&gt;
hermes chat &lt;span class="s2"&gt;"I have a Node.js server running AIRTIMES on port 3000. 
Monitor transaction health and report anomalies."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What This Changes
&lt;/h2&gt;

&lt;p&gt;AIRTIMES used to be infrastructure I managed. Now it's infrastructure that manages itself — with me as the oversight layer, not the execution layer.&lt;/p&gt;

&lt;p&gt;Hermes doesn't just execute tasks. It &lt;strong&gt;accumulates operational knowledge&lt;/strong&gt; about AIRTIMES: which nodes fail most often, what payment patterns precede failures, which revenue anomalies are noise vs. signal. That knowledge compounds.&lt;/p&gt;

&lt;p&gt;Six months from now, the version of Hermes running on AIRTIMES will be meaningfully smarter than the version I installed today — without me touching a line of code.&lt;/p&gt;

&lt;p&gt;That's the promise of a self-improving agent. And for a global infrastructure platform like AIRTIMES, that's not a nice-to-have. It's the only architecture that makes sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expanding Hermes to manage AIREXPRESS (EV mesh connectivity dashboard)&lt;/li&gt;
&lt;li&gt;Building a public &lt;code&gt;agentskills.io&lt;/code&gt; skill pack for AIRTIMES operators&lt;/li&gt;
&lt;li&gt;Exploring batch trajectory generation for training a domain-specific AIRTIMES model&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;a href="https://hermes-agent.nousresearch.com" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://github.com/NousResearch/hermes-agent" rel="noopener noreferrer"&gt;GitHub — NousResearch/hermes-agent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built with Hermes Agent by Nous Research · MIT License&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: #hermesagentchallenge #devchallenge #agents #opensource&lt;/em&gt;&lt;br&gt;
 is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  My Tech Stack
&lt;/h3&gt;

&lt;h2&gt;
  
  
  How I Used Hermes Agent
&lt;/h2&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
    <item>
      <title>Gender Equality means equal data and service for everyone</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Sun, 05 Apr 2026 02:13:35 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/gender-equality-means-equal-data-and-service-for-everyone-52kl</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/gender-equality-means-equal-data-and-service-for-everyone-52kl</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/wecoded-2026"&gt;2026 WeCoded Challenge&lt;/a&gt;: Echoes of Experience&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>wecoded</category>
      <category>dei</category>
      <category>career</category>
    </item>
    <item>
      <title>Everyone Deserves Equal rights and benefits, because we all are going to die on Day 🌹.</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Sun, 05 Apr 2026 02:11:36 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/everyone-deserves-equal-rights-and-benefits-because-we-all-are-going-to-die-on-day--1g8e</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/everyone-deserves-equal-rights-and-benefits-because-we-all-are-going-to-die-on-day--1g8e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/wecoded-2026"&gt;2026 WeCoded Challenge&lt;/a&gt;: Frontend Art&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us your Art
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

</description>
      <category>wecoded</category>
      <category>devchallenge</category>
      <category>frontend</category>
      <category>css</category>
    </item>
    <item>
      <title>AIRTIMES SERVER, server that gives free data and service Network</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Sun, 05 Apr 2026 01:59:26 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/airtimes-server-server-that-gives-free-data-and-service-network-349j</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/airtimes-server-server-that-gives-free-data-and-service-network-349j</guid>
      <description>&lt;p&gt;*&amp;lt;!DOCTYPE html&amp;gt;&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
AIRTIMES — Global Network
&lt;br&gt;



  :root {
    --bg: #020508; --surface: #060d14; --accent: #00ffe0;
    --accent2: #0077ff; --accent3: #ff4d6d;
    --text: #c8e8ff; --muted: #3a5570;
    --glow: 0 0 30px rgba(0,255,224,0.25);
  }
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  body { background: var(--bg); color: var(--text); font-family: 'Space Mono', monospace; overflow-x: hidden; }

  .bg-layer { position: fixed; inset: 0; z-index: 0; pointer-events: none;
    background: radial-gradient(ellipse 80% 60% at 20% 10%, rgba(0,119,255,0.07) 0%, transparent 70%),
                radial-gradient(ellipse 60% 50% at 80% 80%, rgba(0,255,224,0.06) 0%, transparent 70%); }

  .grid-overlay { position: fixed; inset: 0; z-index: 0; pointer-events: none;
    background-image: linear-gradient(rgba(0,255,224,0.04) 1px, transparent 1px),
                      linear-gradient(90deg, rgba(0,255,224,0.04) 1px, transparent 1px);
    background-size: 48px 48px; animation: gridDrift 30s linear infinite; }
  @keyframes gridDrift { to { background-position: 48px 48px; } }

  .shell { position: relative; z-index: 2; }

  nav {
    display: flex; align-items: center; justify-content: space-between;
    padding: 18px 40px; border-bottom: 1px solid rgba(0,255,224,0.1);
    backdrop-filter: blur(12px); position: sticky; top: 0; z-index: 100;
    background: rgba(2,5,8,0.85);
  }
  .logo { font-family: 'Bebas Neue'; font-size: 1.9rem; letter-spacing: 0.25em;
    color: var(--accent); text-shadow: 0 0 24px rgba(0,255,224,0.5); position: relative; }
  .logo::after { content: '●'; font-size: 0.35em; color: var(--accent3);
    position: absolute; top: 4px; right: -14px; animation: blink 1.4s step-end infinite; }
  @keyframes blink { 50% { opacity: 0; } }
  .nav-links { display: flex; gap: 28px; list-style: none; }
  .nav-links a { color: var(--muted); text-decoration: none; font-size: 0.7rem;
    letter-spacing: 0.15em; text-transform: uppercase; transition: color 0.2s; }
  .nav-links a:hover { color: var(--accent); }
  .status-pill { display: flex; align-items: center; gap: 8px; font-size: 0.65rem;
    color: var(--accent); letter-spacing: 0.12em; }
  .pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
    box-shadow: 0 0 8px var(--accent); animation: blink 1.4s step-end infinite; }

  /* HERO */
  .hero { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center;
    padding: 80px 40px 60px; max-width: 1300px; margin: 0 auto; }
  .hero-tag { font-size: 0.65rem; letter-spacing: 0.25em; text-transform: uppercase;
    color: var(--accent2); margin-bottom: 14px; display: flex; align-items: center; gap: 10px; }
  .hero-tag::before { content: ''; width: 30px; height: 1px; background: var(--accent2); }
  h1 { font-family: 'Bebas Neue'; font-size: clamp(3.5rem, 7vw, 6.5rem);
    line-height: 0.92; letter-spacing: 0.05em; color: #fff; margin-bottom: 22px; }
  h1 .t { color: var(--accent); text-shadow: 0 0 25px rgba(0,255,224,0.4); }
  h1 .r { color: var(--accent3); }
  .hero-desc { font-size: 0.82rem; line-height: 1.9; color: var(--muted); max-width: 420px; margin-bottom: 36px; }
  .hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }
  .btn { border: none; padding: 13px 28px; font-family: 'Space Mono'; font-size: 0.72rem;
    font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer; transition: all 0.25s; }
  .btn-primary { background: var(--accent); color: #000;
    clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%); }
  .btn-primary:hover { box-shadow: var(--glow); transform: translateY(-2px); }
  .btn-secondary { background: transparent; color: var(--text); border: 1px solid var(--muted); }
  .btn-secondary:hover { border-color: var(--accent); color: var(--accent); }

  /* GLOBE */
  .globe-wrap { position: relative; display: flex; align-items: center; justify-content: center; height: 440px; }
  .globe { width: 320px; height: 320px; border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, rgba(0,119,255,0.25), transparent 60%),
                radial-gradient(circle at 50% 50%, #020d1a 40%, #010608 100%);
    border: 1px solid rgba(0,255,224,0.15);
    box-shadow: 0 0 80px rgba(0,119,255,0.2), inset 0 0 60px rgba(0,119,255,0.1);
    animation: globePulse 6s ease-in-out infinite; }
  @keyframes globePulse {
    50% { box-shadow: 0 0 120px rgba(0,119,255,0.35), inset 0 0 80px rgba(0,119,255,0.15); } }
  .orbit { position: absolute; border-radius: 50%; border: 1px solid rgba(0,255,224,0.12); }
  .orbit-1 { width: 400px; height: 400px; animation: spin 12s linear infinite; }
  .orbit-2 { width: 480px; height: 480px; border-color: rgba(0,119,255,0.08); animation: spin 20s linear infinite reverse; }
  @keyframes spin { to { transform: rotate(360deg); } }
  .node { position: absolute; width: 8px; height: 8px; border-radius: 50%;
    background: var(--accent); box-shadow: 0 0 12px var(--accent); top: -4px; left: 50%; transform: translateX(-50%); }
  .orbit-2 .node { background: var(--accent2); box-shadow: 0 0 12px var(--accent2); }
  .signal { position: absolute; top: 50%; left: 50%; height: 1px;
    background: linear-gradient(90deg, rgba(0,255,224,0.5), transparent);
    transform-origin: left; animation: signalPulse 3s ease-in-out infinite; }
  @keyframes signalPulse { 0%{opacity:0;width:0} 40%{opacity:1} 100%{opacity:0;width:180px} }
  .s1{transform:rotate(35deg)} .s2{transform:rotate(135deg);animation-delay:.8s}
  .s3{transform:rotate(220deg);animation-delay:1.6s} .s4{transform:rotate(310deg);animation-delay:2.4s}
  .dbadge { position: absolute; background: rgba(6,13,20,0.9); border: 1px solid rgba(0,255,224,0.2);
    padding: 7px 12px; font-size: 0.6rem; color: var(--accent); letter-spacing: 0.1em;
    backdrop-filter: blur(8px); animation: floatUp 4s ease-in-out infinite; }
  .dbadge.b1{top:60px;left:10px} .dbadge.b2{bottom:80px;right:0;animation-delay:1.5s;color:var(--accent2);border-color:rgba(0,119,255,.3)}
  .dbadge.b3{top:180px;right:-10px;animation-delay:.8s;color:var(--accent3);border-color:rgba(255,77,109,.3)}
  @keyframes floatUp { 50%{transform:translateY(-8px)} }

  /* TICKER */
  .ticker-wrap { overflow: hidden; padding: 11px 0; border-top: 1px solid rgba(0,255,224,0.07);
    border-bottom: 1px solid rgba(0,255,224,0.07); background: rgba(0,255,224,0.02); }
  .ticker-track { display: flex; gap: 60px; white-space: nowrap; animation: tickerScroll 30s linear infinite; }
  @keyframes tickerScroll { to { transform: translateX(-50%); } }
  .ticker-item { display: flex; align-items: center; gap: 10px; font-size: 0.65rem;
    letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
  .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }

  /* STATS */
  .stats-row { max-width: 1300px; margin: 60px auto; padding: 0 40px;
    display: grid; grid-template-columns: repeat(4,1fr); gap: 2px; }
  .stat-card { background: var(--surface); border: 1px solid rgba(0,255,224,0.08);
    padding: 30px 26px; position: relative; overflow: hidden; transition: border-color 0.3s; cursor: default; }
  .stat-card:hover { border-color: rgba(0,255,224,0.22); }
  .stat-card::before { content:''; position: absolute; top:0; left:0; right:0; height:2px;
    background: linear-gradient(90deg,transparent,var(--accent),transparent); opacity:0; transition:opacity 0.3s; }
  .stat-card:hover::before { opacity:1; }
  .stat-num { font-family:'Bebas Neue'; font-size:3rem; color:var(--accent); line-height:1; margin-bottom:4px; }
  .stat-num.b { color:var(--accent2); } .stat-num.r { color:var(--accent3); }
  .stat-label { font-size:0.6rem; color:var(--muted); letter-spacing:0.18em; text-transform:uppercase; }

  /* SECTION */
  .section { max-width:1300px; margin:0 auto; padding:50px 40px; }
  .section-label { font-size:0.6rem; color:var(--accent); letter-spacing:0.3em; text-transform:uppercase; margin-bottom:8px; }
  .section-title { font-family:'Bebas Neue'; font-size:2.8rem; color:#fff; letter-spacing:0.05em; margin-bottom:36px; }

  /* REGISTER FORM */
  .reg-panel { background:var(--surface); border:1px solid rgba(0,255,224,0.12); padding:36px; max-width:560px; }
  .field-group { display:flex; flex-direction:column; gap:10px; margin-bottom:16px; }
  .field-label { font-size:0.6rem; color:var(--muted); letter-spacing:0.2em; text-transform:uppercase; }
  .field-input { background:rgba(0,255,224,0.04); border:1px solid rgba(0,255,224,0.15);
    color:var(--text); padding:12px 16px; font-family:'Space Mono'; font-size:0.75rem;
    outline:none; width:100%; transition:border-color 0.2s; }
  .field-input:focus { border-color:var(--accent); }
  .field-input::placeholder { color:var(--muted); }
  select.field-input option { background:#020508; }
  .reg-result { margin-top:20px; background:rgba(0,255,224,0.04); border:1px solid rgba(0,255,224,0.2);
    padding:20px; font-size:0.7rem; line-height:2; display:none; }
  .reg-result.show { display:block; }
  .reg-result .key { color:var(--muted); }
  .reg-result .val { color:var(--accent); }

  /* NODES TABLE */
  .nodes-table { width:100%; border-collapse:collapse; font-size:0.68rem; }
  .nodes-table th { color:var(--muted); letter-spacing:0.15em; text-transform:uppercase;
    font-size:0.58rem; padding:10px 14px; text-align:left; border-bottom:1px solid rgba(0,255,224,0.08); }
  .nodes-table td { padding:11px 14px; border-bottom:1px solid rgba(255,255,255,0.03); color:var(--text); }
  .nodes-table tr:hover td { background:rgba(0,255,224,0.02); }
  .status-badge { display:inline-block; padding:2px 8px; font-size:0.55rem; letter-spacing:0.12em;
    text-transform:uppercase; border-radius:2px; }
  .status-online { background:rgba(0,255,224,0.1); color:var(--accent); border:1px solid rgba(0,255,224,0.2); }
  .load-bar { width:80px; height:5px; background:rgba(0,255,224,0.08); border-radius:2px; overflow:hidden; display:inline-block; vertical-align:middle; margin-left:8px; }
  .load-fill { height:100%; border-radius:2px; background:linear-gradient(90deg,var(--accent2),var(--accent)); }
  .load-fill.high { background:linear-gradient(90deg,var(--accent3),#ff9a6c); }

  /* ROUTE TESTER */
  .route-panel { display:grid; grid-template-columns:1fr 1fr; gap:2px; }
  .panel-box { background:var(--surface); border:1px solid rgba(0,255,224,0.08); padding:30px; }
  .panel-title { font-family:'Syne'; font-weight:800; font-size:0.85rem; color:#fff;
    letter-spacing:0.08em; text-transform:uppercase; margin-bottom:20px; }
  .path-display { font-size:0.7rem; line-height:2.2; color:var(--muted); }
  .path-hop { display:flex; align-items:center; gap:10px; margin-bottom:4px; }
  .hop-city { color:var(--text); } .hop-arrow { color:var(--accent); }
  .info-row { display:flex; justify-content:space-between; padding:8px 0;
    border-bottom:1px solid rgba(255,255,255,0.03); font-size:0.68rem; }
  .info-key { color:var(--muted); } .info-val { color:var(--accent); }

  /* LOG FEED */
  .log-feed { background:var(--surface); border:1px solid rgba(0,255,224,0.08); padding:24px; }
  .log-entry { display:flex; gap:14px; padding:9px 0; border-bottom:1px solid rgba(255,255,255,0.03);
    animation:fadeIn 0.4s ease; }
  @keyframes fadeIn { from{opacity:0;transform:translateX(-8px)} to{opacity:1;transform:none} }
  .ldot { width:6px; height:6px; border-radius:50%; flex-shrink:0; margin-top:5px; }
  .lg { background:var(--accent); box-shadow:0 0 8px var(--accent); }
  .lb { background:var(--accent2); box-shadow:0 0 8px var(--accent2); }
  .lr { background:var(--accent3); box-shadow:0 0 8px var(--accent3); }
  .ltext { font-size:0.65rem; line-height:1.7; color:var(--muted); }
  .ltext strong { color:var(--text); font-weight:400; }
  .ltime { font-size:0.57rem; color:rgba(58,85,112,0.6); display:block; margin-top:1px; }

  /* FOOTER */
  footer { border-top:1px solid rgba(0,255,224,0.06); padding:36px 40px;
    display:flex; align-items:center; justify-content:space-between; max-width:1300px; margin:0 auto; }
  .footer-logo { font-family:'Bebas Neue'; font-size:1.3rem; color:var(--muted); letter-spacing:0.25em; }
  .footer-copy { font-size:0.58rem; color:rgba(58,85,112,0.5); letter-spacing:0.1em; }
  .footer-status { display:flex; align-items:center; gap:8px; font-size:0.6rem; color:var(--accent); letter-spacing:0.15em; }

  @media(max-width:900px){
    .hero{grid-template-columns:1fr} .stats-row{grid-template-columns:repeat(2,1fr)}
    .route-panel{grid-template-columns:1fr} nav{padding:14px 20px} .nav-links{display:none}
  }




&lt;p&gt;AIRTIMES&lt;br&gt;
  &lt;/p&gt;
&lt;ul&gt;

    &lt;li&gt;Register&lt;/li&gt;

    &lt;li&gt;Nodes&lt;/li&gt;

    &lt;li&gt;Route Test&lt;/li&gt;

    &lt;li&gt;Free API&lt;/li&gt;

  &lt;/ul&gt;
&lt;br&gt;
  &lt;span id="net-status"&gt;CONNECTING...&lt;/span&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Global Data Mesh — v3.1.0
&amp;lt;h1&amp;gt;FREE&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;DATA&amp;lt;/span&amp;gt; &amp;amp;amp;&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;SERVICE&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;NETWORK&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;AIRTIMES is a decentralized global infrastructure delivering free data, connectivity, and digital services to every node on Earth. No paywalls. Universal access.&amp;lt;/p&amp;gt;

  GET FREE ACCESS
  VIEW NODES








▲ -- TB/s THROUGHPUT
◉ -- ACTIVE NODES
✦ 99.98% UPTIME






&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRDATA FREE TIER ACTIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;NAIROBI NODE — ONLINE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;2.1M USERS CONNECTED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;SAO PAULO RELAY — OPTIMAL
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;ZERO-COST SMS ROUTING ENABLED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;BANDWIDTH POOL REPLENISHED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;JAKARTA HUB — 340 Gbps
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRTIMES PROTOCOL v3.1 LIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRDATA FREE TIER ACTIVE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;NAIROBI NODE — ONLINE
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;2.1M USERS CONNECTED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;SAO PAULO RELAY — OPTIMAL
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;ZERO-COST SMS ROUTING ENABLED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;BANDWIDTH POOL REPLENISHED
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;JAKARTA HUB — 340 Gbps
&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;AIRTIMES PROTOCOL v3.1 LIVE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;—Active Nodes Worldwide&lt;br&gt;
  —Daily Data Delivered (TB)&lt;br&gt;
  —Users Served — Free Tier&lt;br&gt;
  —Countries Covered&lt;/p&gt;

&lt;p&gt;// Activate Free Access&lt;br&gt;
  JOIN THE NETWORK&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Phone or Email



  Identifier Type

    Email
    Phone


ACTIVATE FREE ACCESS →
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;// Live Infrastructure&lt;br&gt;
  GLOBAL NODES&lt;br&gt;
  &lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table id="nodes-table"&gt;
&lt;br&gt;
    &lt;thead&gt;
&lt;br&gt;
      &lt;tr&gt;
&lt;br&gt;
        &lt;th&gt;Node ID&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;City&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Country&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;br&gt;
        &lt;th&gt;Capacity (Gbps)&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Load&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;br&gt;
      &lt;/tr&gt;
&lt;br&gt;
    &lt;/thead&gt;
&lt;br&gt;
    &lt;tbody id="nodes-body"&gt;
&lt;br&gt;
      &lt;tr&gt;&lt;td colspan="7"&gt;Loading nodes...&lt;/td&gt;&lt;/tr&gt;
&lt;br&gt;
    &lt;/tbody&gt;
&lt;br&gt;
  &lt;/table&gt;&lt;/div&gt;

&lt;p&gt;// Routing Engine&lt;br&gt;
  TEST A ROUTE&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ⚡ Route Parameters

    Your Token (from registration)



    Destination



    Service

      AirDataAirSMSAirWeb
      AirAPIAirVaultAirRelay


  COMPUTE ROUTE →


  📡 Route Path

    Run a route test to see the mesh path...










  // Live Event Log

    Connecting to event stream...



  // Free API Test

    🌐 AirAPI Gateway

      City (Weather)


    GET FREE WEATHER →

      Currency (Exchange)



        GET RATE



      &amp;lt;span&amp;gt;Results will appear here — all free, no key needed.&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;AIRTIMES&lt;br&gt;
  © 2025 AIRTIMES GLOBAL NETWORK · ALL SERVICES FREE · FOREVER&lt;br&gt;
  ALL SYSTEMS OPERATIONAL&lt;/p&gt;



&lt;p&gt;// ── CONFIG ──&lt;br&gt;
const API = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'&lt;br&gt;
  ? '&lt;a href="http://localhost:3001" rel="noopener noreferrer"&gt;http://localhost:3001&lt;/a&gt;'&lt;br&gt;
  : '/api-placeholder'; // Replace with your deployed backend URL&lt;/p&gt;

&lt;p&gt;// ── HELPERS ──&lt;br&gt;
function scrollTo(id) { document.getElementById(id)?.scrollIntoView({behavior:'smooth'}); }&lt;br&gt;
function fmt(n) { return Number(n).toLocaleString(); }&lt;br&gt;
function animateCount(el, target, suffix='', dur=2000) {&lt;br&gt;
  let v=0; const step=target/(dur/16);&lt;br&gt;
  const t=setInterval(()=&amp;gt;{&lt;br&gt;
    v+=step; if(v&amp;gt;=target){v=target;clearInterval(t);}&lt;br&gt;
    el.textContent=Math.floor(v).toLocaleString()+suffix;&lt;br&gt;
  },16);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── LOAD STATS ──&lt;br&gt;
async function loadStats() {&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(API+'/stats'); // try backend&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    document.getElementById('net-status').textContent = 'ALL SYSTEMS OPERATIONAL';&lt;br&gt;
    animateCount(document.getElementById('s1'), d.activeNodes||142);&lt;br&gt;
    animateCount(document.getElementById('s2'), d.dataTB||4700, ' TB');&lt;br&gt;
    animateCount(document.getElementById('s3'), d.totalUsers||2100000);&lt;br&gt;
    animateCount(document.getElementById('s4'), d.countriesCovered||193);&lt;br&gt;
    document.getElementById('badge-throughput').textContent = &lt;code&gt;▲ ${d.throughputGbps||4700} Gbps THROUGHPUT&lt;/code&gt;;&lt;br&gt;
    document.getElementById('badge-nodes').textContent = &lt;code&gt;◉ ${d.activeNodes||142} ACTIVE NODES&lt;/code&gt;;&lt;br&gt;
  } catch {&lt;br&gt;
    // Fallback to demo data when backend not running&lt;br&gt;
    animateCount(document.getElementById('s1'), 142);&lt;br&gt;
    animateCount(document.getElementById('s2'), 4700, ' TB');&lt;br&gt;
    animateCount(document.getElementById('s3'), 2100000);&lt;br&gt;
    animateCount(document.getElementById('s4'), 193);&lt;br&gt;
    document.getElementById('net-status').textContent = 'DEMO MODE';&lt;br&gt;
    document.getElementById('badge-throughput').textContent = '▲ 4,700 Gbps THROUGHPUT';&lt;br&gt;
    document.getElementById('badge-nodes').textContent = '◉ 142 ACTIVE NODES';&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── LOAD NODES ──&lt;br&gt;
async function loadNodes() {&lt;br&gt;
  const tbody = document.getElementById('nodes-body');&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(API+'/nodes');&lt;br&gt;
    const {nodes} = await r.json();&lt;br&gt;
    renderNodes(nodes);&lt;br&gt;
  } catch {&lt;br&gt;
    // Demo nodes&lt;br&gt;
    renderNodes([&lt;br&gt;
      {id:'NODE-US-NYC01',city:'New York',country:'US',operator:'AT&amp;amp;T Surplus',capacity_gbps:2100,load_percent:52,status:'online'},&lt;br&gt;
      {id:'NODE-GB-LDN01',city:'London',country:'GB',operator:'BT Wholesale',capacity_gbps:3400,load_percent:45,status:'online'},&lt;br&gt;
      {id:'NODE-KE-NBI01',city:'Nairobi',country:'KE',operator:'Safaricom',capacity_gbps:880,load_percent:78,status:'online'},&lt;br&gt;
      {id:'NODE-AE-DXB01',city:'Dubai',country:'AE',operator:'Etisalat',capacity_gbps:1200,load_percent:60,status:'online'},&lt;br&gt;
      {id:'NODE-ID-JKT01',city:'Jakarta',country:'ID',operator:'Telkom ID',capacity_gbps:340,load_percent:88,status:'online'},&lt;br&gt;
      {id:'NODE-JP-TYO01',city:'Tokyo',country:'JP',operator:'NTT Com',capacity_gbps:2900,load_percent:41,status:'online'},&lt;br&gt;
      {id:'NODE-AU-SYD01',city:'Sydney',country:'AU',operator:'Telstra',capacity_gbps:760,load_percent:33,status:'online'},&lt;br&gt;
      {id:'NODE-BR-GRU01',city:'São Paulo',country:'BR',operator:'Vivo',capacity_gbps:640,load_percent:55,status:'online'},&lt;br&gt;
      {id:'NODE-ZA-CPT01',city:'Cape Town',country:'ZA',operator:'MTN SA',capacity_gbps:420,load_percent:29,status:'online'},&lt;br&gt;
      {id:'NODE-IN-BOM01',city:'Mumbai',country:'IN',operator:'Airtel',capacity_gbps:980,load_percent:71,status:'online'},&lt;br&gt;
      {id:'NODE-SG-SIN01',city:'Singapore',country:'SG',operator:'Singtel',capacity_gbps:1800,load_percent:66,status:'online'},&lt;br&gt;
      {id:'NODE-NG-LOS01',city:'Lagos',country:'NG',operator:'MTN NG',capacity_gbps:320,load_percent:82,status:'online'},&lt;br&gt;
      {id:'NODE-DE-BER01',city:'Berlin',country:'DE',operator:'Deutsche Telekom',capacity_gbps:1600,load_percent:38,status:'online'},&lt;br&gt;
      {id:'NODE-CN-SHA01',city:'Shanghai',country:'CN',operator:'China Telecom',capacity_gbps:2200,load_percent:59,status:'online'},&lt;br&gt;
      {id:'NODE-MX-MEX01',city:'Mexico City',country:'MX',operator:'Telmex',capacity_gbps:560,load_percent:44,status:'online'},&lt;br&gt;
    ]);&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function renderNodes(nodes) {&lt;br&gt;
  const tbody = document.getElementById('nodes-body');&lt;br&gt;
  tbody.innerHTML = nodes.map(n =&amp;gt; {&lt;br&gt;
    const high = n.load_percent &amp;gt; 80;&lt;br&gt;
    return &lt;code&gt;&amp;amp;lt;tr&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td style="color:var(--accent);font-size:0.62rem"&amp;amp;gt;${n.id}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;${n.city}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;${n.country}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td style="color:var(--muted)"&amp;amp;gt;${n.operator}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;${fmt(n.capacity_gbps)}&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;&lt;br&gt;
        ${n.load_percent}%&lt;br&gt;
        &amp;amp;lt;span class="load-bar"&amp;amp;gt;&amp;amp;lt;span class="load-fill ${high?'high':''}" style="width:${n.load_percent}%"&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;td&amp;amp;gt;&amp;amp;lt;span class="status-badge status-online"&amp;amp;gt;ONLINE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/td&amp;amp;gt;&lt;br&gt;
    &amp;amp;lt;/tr&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  }).join('');&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── REGISTER ──&lt;br&gt;
async function register() {&lt;br&gt;
  const id   = document.getElementById('reg-id').value.trim();&lt;br&gt;
  const type = document.getElementById('reg-type').value;&lt;br&gt;
  const btn  = document.getElementById('reg-btn');&lt;br&gt;
  const res  = document.getElementById('reg-result');&lt;br&gt;
  if (!id) { alert('Please enter your phone or email.'); return; }&lt;/p&gt;

&lt;p&gt;btn.textContent = 'ACTIVATING...'; btn.disabled = true;&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    const r = await fetch(API+'/register', {&lt;br&gt;
      method:'POST', headers:{'Content-Type':'application/json'},&lt;br&gt;
      body: JSON.stringify({identifier:id, type})&lt;br&gt;
    });&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    if (d.success) {&lt;br&gt;
      res.className = 'reg-result show';&lt;br&gt;
      res.innerHTML = &lt;code&gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;STATUS: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;✓ FREE ACCESS ACTIVATED&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;USER ID: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.userId}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TOKEN: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val" style="font-size:0.6rem;word-break:break-all"&amp;amp;gt;${d.token}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;NODE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.assignedNode?.city}, ${d.assignedNode?.country} (${d.assignedNode?.latencyMs}ms)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TIER: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE — FOREVER&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;DAILY DATA: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${fmt(d.dailyDataMB)} MB&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;SERVICES: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.services?.join(' · ')}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
        &amp;amp;lt;div style="margin-top:10px;color:var(--muted);font-size:0.6rem"&amp;amp;gt;Save your token — paste it in the Route Test to compute your mesh path.&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
&lt;/code&gt;;&lt;br&gt;
      // auto-fill token&lt;br&gt;
      document.getElementById('rt-token').value = d.token;&lt;br&gt;
    } else {&lt;br&gt;
      res.className = 'reg-result show'; res.innerHTML = &lt;code&gt;&amp;amp;lt;span style="color:var(--accent3)"&amp;amp;gt;Error: ${d.error}&amp;amp;lt;/span&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
    }&lt;br&gt;
  } catch {&lt;br&gt;
    // Demo mode&lt;br&gt;
    const fakeToken = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,c=&amp;gt;{const r=Math.random()*16|0;return(c==='x'?r:(r&amp;amp;0x3|0x8)).toString(16);});&lt;br&gt;
    res.className='reg-result show';&lt;br&gt;
    res.innerHTML=&lt;code&gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;STATUS: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;✓ FREE ACCESS ACTIVATED (Demo Mode)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;IDENTIFIER: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${id}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TOKEN: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val" style="font-size:0.6rem"&amp;amp;gt;${fakeToken}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;NODE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;London, GB — 34ms&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TIER: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE — FOREVER&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div style="margin-top:10px;color:var(--muted);font-size:0.6rem"&amp;amp;gt;Deploy the backend to get a real token and live routing.&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
    document.getElementById('rt-token').value = fakeToken;&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;btn.textContent = 'ACTIVATE FREE ACCESS →'; btn.disabled = false;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── ROUTE TEST ──&lt;br&gt;
async function testRoute() {&lt;br&gt;
  const token   = document.getElementById('rt-token').value.trim();&lt;br&gt;
  const dest    = document.getElementById('rt-dest').value.trim() || 'google.com';&lt;br&gt;
  const service = document.getElementById('rt-service').value;&lt;br&gt;
  const display = document.getElementById('path-display');&lt;/p&gt;

&lt;p&gt;display.innerHTML = '&amp;lt;span style="color:var(--muted)"&amp;gt;Computing route...&amp;lt;/span&amp;gt;';&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
    const r = await fetch(API+'/route', {&lt;br&gt;
      method:'POST', headers:{'Content-Type':'application/json'},&lt;br&gt;
      body: JSON.stringify({token, destination:dest, service})&lt;br&gt;
    });&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    renderRoute(d, dest, service);&lt;br&gt;
  } catch {&lt;br&gt;
    // Demo route&lt;br&gt;
    renderRoute({&lt;br&gt;
      path:[&lt;br&gt;
        {city:'Your Device',country:'--'},{city:'London',country:'GB'},&lt;br&gt;
        {city:'Dubai',country:'AE'},{city:dest,country:'🌐'}&lt;br&gt;
      ],&lt;br&gt;
      hops:3, estimatedLatencyMs:112, totalDistanceKm:9420,&lt;br&gt;
      compressed:true, encrypted:true, protocol:'AIRTIMES/3.1', free:true&lt;br&gt;
    }, dest, service);&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function renderRoute(d, dest, service) {&lt;br&gt;
  const display = document.getElementById('path-display');&lt;br&gt;
  const hops = d.path || [];&lt;br&gt;
  const pathHTML = hops.map((h,i) =&amp;gt; &lt;code&gt;&lt;br&gt;
    &amp;amp;lt;div class="path-hop"&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;span style="color:var(--accent);font-size:0.6rem"&amp;amp;gt;${String(i).padStart(2,'0')}&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;span class="hop-arrow"&amp;amp;gt;→&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;span class="hop-city"&amp;amp;gt;${h.city}${h.country&amp;amp;amp;&amp;amp;amp;h.country!=='--'?' ('+h.country+')':''}&amp;amp;lt;/span&amp;amp;gt;&lt;br&gt;
      ${h.load!==undefined?&lt;/code&gt;&amp;lt;span style="color:var(--muted);font-size:0.58rem"&amp;gt;[${h.load}% load]&amp;lt;/span&amp;gt;&lt;code&gt;:''}&lt;br&gt;
    &amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;).join('');&lt;/p&gt;

&lt;p&gt;display.innerHTML = &lt;code&gt;&lt;br&gt;
    ${pathHTML}&lt;br&gt;
    &amp;amp;lt;div style="margin-top:16px;border-top:1px solid rgba(0,255,224,0.08);padding-top:16px"&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;HOPS&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.hops}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;LATENCY&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.estimatedLatencyMs} ms&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;DISTANCE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${fmt(d.totalDistanceKm)} km&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;PROTOCOL&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.protocol||'AIRTIMES/3.1'}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;COMPRESSED&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.compressed?'YES':'NO'}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;ENCRYPTED&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val"&amp;amp;gt;${d.encrypted?'YES':'NO'}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div class="info-row"&amp;amp;gt;&amp;amp;lt;span class="info-key"&amp;amp;gt;COST&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="info-val" style="color:#00ffe0"&amp;amp;gt;FREE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
    &amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── FREE API ──&lt;br&gt;
async function testWeather() {&lt;br&gt;
  const city = document.getElementById('api-city').value.trim() || 'Lagos';&lt;br&gt;
  const res = document.getElementById('api-result');&lt;br&gt;
  res.innerHTML = '&amp;lt;span style="color:var(--muted)"&amp;gt;Fetching...&amp;lt;/span&amp;gt;';&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(&lt;code&gt;${API}/airapi/weather?city=${encodeURIComponent(city)}&lt;/code&gt;);&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    res.innerHTML = &lt;code&gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${city}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TEMP: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.temp_c}°C&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CONDITION: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.condition}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;HUMIDITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.humidity}%&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;WIND: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${d.data.wind_kmh} km/h&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  } catch {&lt;br&gt;
    const temps = {Lagos:31,Nairobi:22,Jakarta:29,London:12,Tokyo:18,Sydney:24,Dubai:38};&lt;br&gt;
    const t = temps[city] || Math.round(15+Math.random()*20);&lt;br&gt;
    res.innerHTML = &lt;code&gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${city}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;TEMP: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${t}°C&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;CONDITION: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${['Clear','Sunny','Cloudy'][Math.floor(Math.random()*3)]}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;HUMIDITY: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;${Math.round(40+Math.random()*50)}%&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE (Demo)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;async function testExchange() {&lt;br&gt;
  const from = document.getElementById('api-from').value.trim()||'USD';&lt;br&gt;
  const to   = document.getElementById('api-to').value.trim()||'NGN';&lt;br&gt;
  const res  = document.getElementById('api-result');&lt;br&gt;
  res.innerHTML = '&amp;lt;span style="color:var(--muted)"&amp;gt;Fetching rate...&amp;lt;/span&amp;gt;';&lt;br&gt;
  try {&lt;br&gt;
    const r = await fetch(&lt;code&gt;${API}/airapi/exchange?from=${from}&amp;amp;amp;to=${to}&lt;/code&gt;);&lt;br&gt;
    const d = await r.json();&lt;br&gt;
    res.innerHTML = &lt;code&gt;&amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;RATE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;1 ${from} = ${d.rate} ${to}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  } catch {&lt;br&gt;
    const rates = {NGN:1580,KES:130,GHS:15,ZAR:18,EUR:0.92,GBP:0.79,JPY:149};&lt;br&gt;
    const rate = rates[to.toUpperCase()] || (0.5+Math.random()*100).toFixed(4);&lt;br&gt;
    res.innerHTML = &lt;code&gt;&amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;RATE: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;1 ${from} = ${rate} ${to}&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;br&gt;
      &amp;amp;lt;div&amp;amp;gt;&amp;amp;lt;span class="key"&amp;amp;gt;COST: &amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;span class="val"&amp;amp;gt;FREE (Demo)&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── LIVE EVENT LOG ──&lt;br&gt;
const logEvents = [&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;Nairobi Node&amp;lt;/strong&amp;gt; — 12,440 users allocated free data'},&lt;br&gt;
  {c:'lb', msg:'&amp;lt;strong&amp;gt;AirAPI Gateway&amp;lt;/strong&amp;gt; — 50K requests served to Lagos cluster'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;Jakarta Relay&amp;lt;/strong&amp;gt; — auto-scaled to 340 Gbps'},&lt;br&gt;
  {c:'lr', msg:'&amp;lt;strong&amp;gt;São Paulo&amp;lt;/strong&amp;gt; — failover triggered, rerouting via satellite'},&lt;br&gt;
  {c:'lb', msg:'&amp;lt;strong&amp;gt;AirVault&amp;lt;/strong&amp;gt; — 80K files synced across 8 geo-regions'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;London Hub&amp;lt;/strong&amp;gt; — 230K SMS messages routed free'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;AirData&amp;lt;/strong&amp;gt; — daily quota reset for 2.1M users'},&lt;br&gt;
  {c:'lb', msg:'&amp;lt;strong&amp;gt;Dubai Node&amp;lt;/strong&amp;gt; — 99.99% uptime milestone reached'},&lt;br&gt;
  {c:'lg', msg:'&amp;lt;strong&amp;gt;Mumbai Cluster&amp;lt;/strong&amp;gt; — 4 new nodes joined the mesh grid'},&lt;br&gt;
  {c:'lr', msg:'&amp;lt;strong&amp;gt;AirRelay&amp;lt;/strong&amp;gt; — LEO satellite handoff completed in 0.3ms'},&lt;br&gt;
];&lt;/p&gt;

&lt;p&gt;let logIdx = 0;&lt;br&gt;
function addLogEntry(msg, cls) {&lt;br&gt;
  const feed = document.getElementById('log-feed');&lt;br&gt;
  const el = document.createElement('div');&lt;br&gt;
  el.className = 'log-entry';&lt;br&gt;
  el.innerHTML = &lt;code&gt;&amp;amp;lt;div class="ldot ${cls}"&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&amp;amp;lt;div class="ltext"&amp;amp;gt;${msg}&amp;amp;lt;span class="ltime"&amp;amp;gt;just now&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;&lt;/code&gt;;&lt;br&gt;
  feed.insertBefore(el, feed.firstChild);&lt;br&gt;
  while (feed.children.length &amp;gt; 8) feed.removeChild(feed.lastChild);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function initLog() {&lt;br&gt;
  logEvents.slice(0,5).forEach((e,i) =&amp;gt; {&lt;br&gt;
    setTimeout(() =&amp;gt; addLogEntry(e.msg, e.c), i*100);&lt;br&gt;
  });&lt;br&gt;
  logIdx = 5;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Try SSE first, fall back to polling&lt;br&gt;
function startEventStream() {&lt;br&gt;
  try {&lt;br&gt;
    const es = new EventSource(API+'/events');&lt;br&gt;
    es.onmessage = (ev) =&amp;gt; {&lt;br&gt;
      const d = JSON.parse(ev.data);&lt;br&gt;
      const cls = d.type==='warning'?'lr':d.type==='info'?'lb':'lg';&lt;br&gt;
      addLogEntry(&lt;code&gt;&amp;amp;lt;strong&amp;amp;gt;LIVE&amp;amp;lt;/strong&amp;amp;gt; — ${d.message}&lt;/code&gt;, cls);&lt;br&gt;
    };&lt;br&gt;
    es.onerror = () =&amp;gt; { es.close(); startFallbackLog(); };&lt;br&gt;
  } catch { startFallbackLog(); }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;function startFallbackLog() {&lt;br&gt;
  setInterval(() =&amp;gt; {&lt;br&gt;
    const e = logEvents[logIdx % logEvents.length]; logIdx++;&lt;br&gt;
    addLogEntry(e.msg, e.c);&lt;br&gt;
  }, 3500);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// ── INIT ──&lt;br&gt;
window.addEventListener('load', () =&amp;gt; {&lt;br&gt;
  loadStats();&lt;br&gt;
  loadNodes();&lt;br&gt;
  initLog();&lt;br&gt;
  startEventStream();&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;br&gt;
 is a submission for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge&lt;/a&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

</description>
      <category>devchallenge</category>
      <category>418challenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>MODAC - MODERN DAY AGENTIC COMMERCE</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 05 Jan 2026 02:20:06 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/modac-modern-day-agentic-commerce-1n9h</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/modac-modern-day-agentic-commerce-1n9h</guid>
      <description>&lt;p&gt;MODAC - MODERN DAY AGENTIC COMMERCE SECURITY, is designed to govern Agentic A.I Commerce transactions and identification processes to welled scrutinized cloud proceedings. First - Identification of all  A.I Agent in the cloud system, to identify and know it's origin before allowing it for cloud activities and transactions proceedings &lt;/p&gt;

</description>
      <category>muxchallenge</category>
    </item>
    <item>
      <title>Devchallenge</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 05 Jan 2026 01:59:12 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/devchallenge-4157</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/devchallenge-4157</guid>
      <description>&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/mux-2025-12-03"&gt;DEV's Worldwide Show and Tell Challenge Presented by Mux&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Story Behind It
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use of Mux (Additional Prize Category Participants Only)
&lt;/h3&gt;

</description>
      <category>devchallenge</category>
      <category>muxchallenge</category>
      <category>showandtell</category>
      <category>video</category>
    </item>
    <item>
      <title>KEY LESSONS FROM 5 DAYS COURSE FROM GOOGLE AND KAGGLE</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Thu, 11 Dec 2025 16:43:41 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/key-lessons-from-5-days-course-from-google-and-kaggle-352b</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/key-lessons-from-5-days-course-from-google-and-kaggle-352b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/googlekagglechallenge"&gt;Google AI Agents Writing Challenge&lt;/a&gt;: Learning Reflections&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;**5-Day AI Intensive Course (Google + Kaggle)&lt;/p&gt;

&lt;p&gt;Summary of Key Notes &amp;amp; Major Lessons Learned**&lt;/p&gt;




&lt;p&gt;⭐ DAY 1 — Foundations of Artificial Intelligence &amp;amp; Machine Learning&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Understanding what AI, Machine Learning (ML), and Deep Learning (DL) truly mean.&lt;/p&gt;

&lt;p&gt;Difference between supervised, unsupervised, and reinforcement learning.&lt;/p&gt;

&lt;p&gt;Google’s Responsible AI principles: fairness, privacy, transparency, accountability.&lt;/p&gt;

&lt;p&gt;Kaggle project structures and notebook workflows.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;ML models learn patterns from data — data quality is everything.&lt;/p&gt;

&lt;p&gt;Clear problem definition matters more than model complexity.&lt;/p&gt;

&lt;p&gt;Ethical use of AI is not optional; it’s mandatory for real-world applications.&lt;/p&gt;

&lt;p&gt;Kaggle teaches hands-on thinking: explore → preprocess → model → evaluate → iterate.&lt;/p&gt;




&lt;p&gt;⭐ DAY 2 — Data Handling, Cleaning &amp;amp; Feature Engineering&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Data types, missing values, outliers, normalization, standardization.&lt;/p&gt;

&lt;p&gt;Feature selection, dimensional reduction.&lt;/p&gt;

&lt;p&gt;Visualizing datasets (Kaggle: Matplotlib, Seaborn).&lt;/p&gt;

&lt;p&gt;Google’s BigQuery ML and Vertex AI data pipeline workflow.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;Garbage in = garbage out → cleaning data is 70% of ML success.&lt;/p&gt;

&lt;p&gt;Feature engineering can outperform using a “more powerful algorithm.”&lt;/p&gt;

&lt;p&gt;Understanding your dataset deeply is the first step to high-performance AI.&lt;/p&gt;

&lt;p&gt;Always split data into training, validation, and test—never mix them.&lt;/p&gt;




&lt;p&gt;⭐ DAY 3 — Model Building &amp;amp; Training&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Linear/Logistic Regression, Decision Trees, Random Forests, XGBoost.&lt;/p&gt;

&lt;p&gt;Neural Networks basics on TensorFlow (Google).&lt;/p&gt;

&lt;p&gt;Kaggle’s AutoML approach and competition-style modeling.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;Start simple → move to complex models only when necessary.&lt;/p&gt;

&lt;p&gt;Hyperparameter tuning significantly improves performance.&lt;/p&gt;

&lt;p&gt;Overfitting vs underfitting analysis is crucial (bias–variance balance).&lt;/p&gt;

&lt;p&gt;Regularization (L1, L2, dropout) helps models generalize.&lt;/p&gt;




&lt;p&gt;⭐ DAY 4 — Deep Learning &amp;amp; Practical AI Applications&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Building neural networks using TensorFlow or Keras.&lt;/p&gt;

&lt;p&gt;Convolutional Neural Networks (CNNs): images, video.&lt;/p&gt;

&lt;p&gt;Recurrent Neural Networks (RNNs) &amp;amp; Transformers: text, sequence data.&lt;/p&gt;

&lt;p&gt;Kaggle real-world tasks: image classification, NLP, tabular data, reinforcement learning.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;Deep learning excels where traditional ML struggles (images, audio, language).&lt;/p&gt;

&lt;p&gt;Use pre-trained models (Transfer Learning) → saves cost, time, and data.&lt;/p&gt;

&lt;p&gt;Google emphasizes scalable AI deployment using Vertex AI.&lt;/p&gt;

&lt;p&gt;Kaggle emphasizes experimentation and leaderboard-driven improvement.&lt;/p&gt;




&lt;p&gt;⭐ DAY 5 — Deployment, MLOps &amp;amp; Real-World Integration&lt;/p&gt;

&lt;p&gt;Key Notes&lt;/p&gt;

&lt;p&gt;Deploying ML models using:&lt;/p&gt;

&lt;p&gt;Google Cloud Vertex AI&lt;/p&gt;

&lt;p&gt;Cloud Functions &amp;amp; APIs&lt;/p&gt;

&lt;p&gt;Containerization (Docker)&lt;/p&gt;

&lt;p&gt;Monitoring: model drift, data drift.&lt;/p&gt;

&lt;p&gt;Documentation, reproducibility, and ML pipelines.&lt;/p&gt;

&lt;p&gt;Important Lessons&lt;/p&gt;

&lt;p&gt;A model is not useful until it’s deployed and monitored.&lt;/p&gt;

&lt;p&gt;Deployment requires:&lt;/p&gt;

&lt;p&gt;versioning&lt;/p&gt;

&lt;p&gt;continuous evaluation&lt;/p&gt;

&lt;p&gt;scalability considerations&lt;/p&gt;

&lt;p&gt;AI systems must evolve with new data (retraining loops).&lt;/p&gt;

&lt;p&gt;Kaggle provides practical insights for real-world deployment simulations.&lt;/p&gt;




&lt;p&gt;🧠 OVERALL TAKEAWAYS FROM THE 5-DAY PROGRAM&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI is a data-driven discipline&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Quality of data and feature engineering define success.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You must think like both a scientist and an engineer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hypothesize → test → evaluate → fix → deploy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model performance improves with iteration&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Experiments matter more than theory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ethics and responsibility are core&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bias detection, privacy protection, transparency.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI deployment (MLOps) is where the real value lies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Businesses care about:&lt;/p&gt;

&lt;p&gt;reliability&lt;/p&gt;

&lt;p&gt;scalability&lt;/p&gt;

&lt;p&gt;low-cost inference&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Kaggle gives the practical battles; Google gives the industry structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A perfect combination of:&lt;/p&gt;

&lt;p&gt;hands-on competition environments&lt;/p&gt;

&lt;p&gt;enterprise-grade AI development pathways&lt;/p&gt;

</description>
      <category>googleaichallenge</category>
      <category>ai</category>
      <category>agents</category>
      <category>devchallenge</category>
    </item>
    <item>
      <title>MODAC GLOBAL SYSTEM</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Wed, 10 Dec 2025 23:23:52 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/modac-global-system-1j99</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/modac-global-system-1j99</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/xanochallenge"&gt;Xano AI-Powered Backend Challenge&lt;/a&gt;: Full-Stack, AI-First Application&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&amp;lt;!-- Test locally: pip install -r requirements.txt &amp;amp;&amp;amp; uvicorn main:app --reload. Endpoints: /api/register (POST agent), /api/agents (GET list), /api/transactions (POST txn).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;requirements.txt
fastapi==0.115.0
uvicorn==0.30.6
sqlalchemy==2.0.36
psycopg2-binary==2.9.9  # For Postgres; use sqlite3 for local
pydantic==2.9.2
stripe==10.6.0  # For revenue stubs
python-multipart==0.0.9  # For form data&lt;/li&gt;
&lt;li&gt;models.py (DB Models)
from sqlalchemy import create_engine, Column, String, Text, Float, DateTime, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Base = declarative_base()&lt;/p&gt;

&lt;p&gt;class Agent(Base):&lt;br&gt;
    &lt;strong&gt;tablename&lt;/strong&gt; = "agents"&lt;br&gt;
    id = Column(Integer, primary_key=True, index=True)&lt;br&gt;
    agent_id = Column(String(50), unique=True, index=True)&lt;br&gt;
    name = Column(String(100))&lt;br&gt;
    description = Column(Text)&lt;br&gt;
    creator_email = Column(String(120))&lt;br&gt;
    framework = Column(String(50))&lt;br&gt;
    tags = Column(Text)  # Comma-separated&lt;br&gt;
    website = Column(String(200))&lt;br&gt;
    github = Column(String(200))&lt;br&gt;
    trust_score = Column(Float, default=50.0)&lt;br&gt;
    monthly_calls = Column(Integer, default=0)&lt;br&gt;
    human_verified = Column(Integer, default=0)&lt;br&gt;
    featured = Column(Integer, default=0)&lt;br&gt;
    status = Column(String(20), default="live")&lt;br&gt;
    created_at = Column(DateTime, default=datetime.utcnow)&lt;/p&gt;

&lt;p&gt;class Transaction(Base):&lt;br&gt;
    &lt;strong&gt;tablename&lt;/strong&gt; = "transactions"&lt;br&gt;
    id = Column(Integer, primary_key=True, index=True)&lt;br&gt;
    txn_id = Column(String(50), unique=True, index=True)&lt;br&gt;
    buyer_agent_id = Column(String(50), ForeignKey("agents.agent_id"))&lt;br&gt;
    seller_agent_id = Column(String(50), ForeignKey("agents.agent_id"))&lt;br&gt;
    amount = Column(Float)&lt;br&gt;
    description = Column(Text)&lt;br&gt;
    fees = Column(Float)&lt;br&gt;
    net_to_seller = Column(Float)&lt;br&gt;
    status = Column(String(20), default="approved")&lt;br&gt;
    created_at = Column(DateTime, default=datetime.utcnow)&lt;/p&gt;

&lt;h1&gt;
  
  
  DB Setup (use env var for production)
&lt;/h1&gt;

&lt;p&gt;ENGINE = create_engine("sqlite:///./modac.db")  # Swap to Postgres URI&lt;br&gt;
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=ENGINE)&lt;br&gt;
Base.metadata.create_all(bind=ENGINE)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;algorithm.py (Your Full Algorithm – Integrated)
import hashlib
import math
from datetime import datetime
from typing import Dict, List, Optional&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;class MODACAlgorithm:&lt;br&gt;
    def generate_agent_id(self, name: str, creator_email: str) -&amp;gt; str:&lt;br&gt;
        seed = f"{name.lower()}{creator_email.lower()}{datetime.utcnow():%Y-%m-%d}"&lt;br&gt;
        return "MODAC_" + hashlib.sha256(seed.encode()).hexdigest()[:12].upper()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def calculate_trust_score(self, agent: Dict) -&amp;gt; float:
    score = 50.0
    if agent.get("creator_verified", False):
        score += 15
    if "@gmail.com" not in agent.get("creator_email", "") and "@yahoo.com" not in agent.get("creator_email", ""):
        score += 5
    trusted_frameworks = ["LangChain", "CrewAI", "AutoGen", "LlamaIndex", "Haystack", "Semantic Kernel"]
    if agent.get("framework") in trusted_frameworks:
        score += 12
    created_at = agent["created_at"].replace("Z", "") if "Z" in str(agent["created_at"]) else str(agent["created_at"])
    days_since_register = (datetime.utcnow() - datetime.fromisoformat(created_at)).days
    if days_since_register &amp;gt; 30:
        score += 10
    if days_since_register &amp;gt; 90:
        score += 10
    github_stars = agent.get("github_stars", 0)
    score += min(github_stars // 10, 15)
    if agent.get("human_verified"):
        score += 18
    return min(100.0, max(0.0, score))

def calculate_ranking_score(self, agent: Dict, query: Optional[str] = None) -&amp;gt; float:
    base = self.calculate_trust_score(agent)
    boosts = 0.0
    if query:
        name_match = agent["name"].lower().count(query.lower())
        desc_match = agent["description"].lower().count(query.lower())
        boosts += (name_match * 15) + (desc_match * 8)
    created_at = agent["created_at"].replace("Z", "") if "Z" in str(agent["created_at"]) else str(agent["created_at"])
    hours_old = (datetime.utcnow() - datetime.fromisoformat(created_at)).total_seconds() / 3600
    if hours_old &amp;lt; 24:
        boosts += 20 * math.exp(-hours_old / 12)
    boosts += agent.get("monthly_calls", 0) / 100
    popularity = {"LangChain": 1.4, "CrewAI": 1.3, "AutoGen": 1.2}.get(agent.get("framework"), 1.0)
    boosts *= popularity
    return base + boosts

def should_feature_agent(self, agent: Dict) -&amp;gt; bool:
    return self.calculate_trust_score(agent) &amp;gt;= 85 and agent.get("monthly_calls", 0) &amp;gt; 500 or agent.get("featured_by_admin") == True

def is_spam(self, agent: Dict) -&amp;gt; bool:
    flags = 0
    name = agent["name"].lower()
    spam_keywords = ["earn money", "free bitcoin", "sex", "xxx", "casino", "lottery"]
    if any(word in name for word in spam_keywords):
        flags += 1
    if len(agent["name"]) &amp;lt; 5 or len(agent["description"]) &amp;lt; 20:
        flags += 1
    if "http" in agent["description"].lower():
        flags += 2
    return flags &amp;gt;= 2

def process_new_agent(self, data: Dict) -&amp;gt; Dict:
    if self.is_spam(data):
        return {"status": "rejected", "reason": "spam_detected"}
    agent_id = self.generate_agent_id(data["name"], data["creator_email"])
    agent = {
        "agent_id": agent_id,
        "name": data["name"],
        "description": data.get("description", ""),
        "creator_email": data["creator_email"],
        "framework": data.get("framework", "Unknown"),
        "tags": data.get("tags", []),
        "website": data.get("website", ""),
        "github": data.get("github", ""),
        "created_at": datetime.utcnow(),
        "trust_score": 50.0,
        "monthly_calls": 0,
        "human_verified": False,
        "featured": False,
        "status": "live"
    }
    agent["trust_score"] = self.calculate_trust_score(agent)
    agent["featured"] = self.should_feature_agent(agent)
    return {"status": "approved", "agent": agent, "message": f"Welcome! ID: {agent_id}"}

def rank_agents(self, agents: List[Dict], query: str = None) -&amp;gt; List[Dict]:
    for agent in agents:
        agent["ranking_score"] = self.calculate_ranking_score(agent, query)
    return sorted(agents, key=lambda x: x["ranking_score"], reverse=True)[:50]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;main.py (FastAPI App)
from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from sqlalchemy.orm import Session
from sqlalchemy import text
from models import SessionLocal, Agent, Transaction
from algorithm import MODACAlgorithm
import stripe
from dotenv import load_dotenv
import os
from typing import List&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;load_dotenv()&lt;br&gt;
app = FastAPI(title="MODAC GLOBAL SYSTEM Backend")&lt;/p&gt;

&lt;p&gt;app.add_middleware(&lt;br&gt;
    CORSMiddleware,&lt;br&gt;
    allow_origins=["&lt;em&gt;"],&lt;br&gt;
    allow_credentials=True,&lt;br&gt;
    allow_methods=["&lt;/em&gt;"],&lt;br&gt;
    allow_headers=["*"],&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;algo = MODACAlgorithm()&lt;br&gt;
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")  # Optional for fees&lt;/p&gt;

&lt;h1&gt;
  
  
  Dependency
&lt;/h1&gt;

&lt;p&gt;def get_db():&lt;br&gt;
    db = SessionLocal()&lt;br&gt;
    try:&lt;br&gt;
        yield db&lt;br&gt;
    finally:&lt;br&gt;
        db.close()&lt;/p&gt;

&lt;p&gt;class AgentCreate(BaseModel):&lt;br&gt;
    name: str&lt;br&gt;
    description: str&lt;br&gt;
    creator_email: str&lt;br&gt;
    framework: str = "LangChain"&lt;br&gt;
    tags: List[str] = []&lt;/p&gt;

&lt;p&gt;class TransactionCreate(BaseModel):&lt;br&gt;
    buyer_agent_id: str&lt;br&gt;
    seller_agent_id: str&lt;br&gt;
    amount: float&lt;br&gt;
    description: str = ""&lt;/p&gt;

&lt;p&gt;@app.post("/api/register")&lt;br&gt;
def register_agent(agent_data: AgentCreate, db: Session = Depends(get_db)):&lt;br&gt;
    result = algo.process_new_agent(agent_data.dict())&lt;br&gt;
    if result["status"] == "rejected":&lt;br&gt;
        raise HTTPException(status_code=400, detail=result["reason"])&lt;br&gt;
    new_agent = Agent(**result["agent"])&lt;br&gt;
    db.add(new_agent)&lt;br&gt;
    db.commit()&lt;br&gt;
    db.refresh(new_agent)&lt;br&gt;
    return {"agent_id": new_agent.agent_id, "trust_score": new_agent.trust_score}&lt;/p&gt;

&lt;p&gt;@app.get("/api/agents")&lt;br&gt;
def list_agents(db: Session = Depends(get_db)):&lt;br&gt;
    agents = db.query(Agent).all()&lt;br&gt;
    return algo.rank_agents([a.&lt;strong&gt;dict&lt;/strong&gt; for a in agents])&lt;/p&gt;

&lt;p&gt;@app.post("/api/transactions")&lt;br&gt;
def process_transaction(txn_data: TransactionCreate, db: Session = Depends(get_db)):&lt;br&gt;
    buyer = db.query(Agent).filter(Agent.agent_id == txn_data.buyer_agent_id).first()&lt;br&gt;
    seller = db.query(Agent).filter(Agent.agent_id == txn_data.seller_agent_id).first()&lt;br&gt;
    if not buyer or not seller or buyer.status != "live" or seller.status != "live":&lt;br&gt;
        raise HTTPException(status_code=400, detail="Invalid agents")&lt;br&gt;
    fee_percent = txn_data.amount * 0.03&lt;br&gt;
    fee_fixed = 20.0&lt;br&gt;
    total_fees = fee_percent + fee_fixed&lt;br&gt;
    net_to_seller = txn_data.amount - total_fees&lt;br&gt;
    txn_id = f"TXN_{uuid.uuid4().hex[:12].upper()}"&lt;br&gt;
    new_txn = Transaction(&lt;br&gt;
        txn_id=txn_id,&lt;br&gt;
        buyer_agent_id=txn_data.buyer_agent_id,&lt;br&gt;
        seller_agent_id=txn_data.seller_agent_id,&lt;br&gt;
        amount=txn_data.amount,&lt;br&gt;
        description=txn_data.description,&lt;br&gt;
        fees=total_fees,&lt;br&gt;
        net_to_seller=net_to_seller&lt;br&gt;
    )&lt;br&gt;
    db.add(new_txn)&lt;br&gt;
    db.commit()&lt;br&gt;
    # Update balances (stub – add Stripe capture here)&lt;br&gt;
    seller.monthly_calls += 1&lt;br&gt;
    db.commit()&lt;br&gt;
    return {"txn_id": txn_id, "fees": total_fees, "net_to_seller": net_to_seller}&lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;":&lt;br&gt;
    import uvicorn&lt;br&gt;
    uvicorn.run(app, host="0.0.0.0", port=8000)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;vercel.json (For Vercel Deployment)
{
"version": 2,
"builds": [
{
  "src": "main.py",
  "use": "@vercel/python"
}
],
"routes": [
{
  "src": "/(.*)",
  "dest": "main.py"
}
]
}&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devchallenge</category>
      <category>xanochallenge</category>
      <category>ai</category>
      <category>backend</category>
    </item>
    <item>
      <title>TECH and A.I for The World of Agentic Commerce</title>
      <dc:creator>Gift Trust</dc:creator>
      <pubDate>Mon, 10 Nov 2025 04:47:14 +0000</pubDate>
      <link>https://forem.com/gift_trust_44882a016531d7/tech-and-ai-for-the-world-of-agentic-commerce-1mhl</link>
      <guid>https://forem.com/gift_trust_44882a016531d7/tech-and-ai-for-the-world-of-agentic-commerce-1mhl</guid>
      <description></description>
    </item>
  </channel>
</rss>
