<?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>DEV Community: Mohammad Ali Abdul Wahed</title>
    <description>The latest articles on DEV Community by Mohammad Ali Abdul Wahed (@maliano63717738).</description>
    <link>https://dev.to/maliano63717738</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1074510%2Ff8cd6a60-67a4-4301-9bec-2491b0e8e3f3.png</url>
      <title>DEV Community: Mohammad Ali Abdul Wahed</title>
      <link>https://dev.to/maliano63717738</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maliano63717738"/>
    <language>en</language>
    <item>
      <title>The Code Was in Git. The AI Conversations TO Implement it,Was Gone</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Sat, 04 Jul 2026 03:38:11 +0000</pubDate>
      <link>https://dev.to/maliano63717738/the-code-was-in-git-the-ai-conversations-to-implement-itwas-gone-142m</link>
      <guid>https://dev.to/maliano63717738/the-code-was-in-git-the-ai-conversations-to-implement-itwas-gone-142m</guid>
      <description>&lt;p&gt;I reopened an old project and found a working authentication implementation.&lt;/p&gt;

&lt;p&gt;What I could not find was the reason it looked that way.&lt;/p&gt;

&lt;p&gt;The commits showed the final code, but not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why one approach had been chosen&lt;/li&gt;
&lt;li&gt;Which fixes had already failed&lt;/li&gt;
&lt;li&gt;What the coding agent warned me about&lt;/li&gt;
&lt;li&gt;Which tasks had been postponed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers were scattered across a ChatGPT thread, a Codex session, and a terminal that no longer existed.&lt;/p&gt;

&lt;p&gt;There was another layer to it. I don't stick to one agent. I move between Codex, Claude Code, Cursor, and plain ChatGPT threads — sometimes because one tool genuinely fits the task better, more often because I simply run out of credits on one and switch to another mid-task. Every time that happened, the new agent started from zero. It had no idea what the previous one had already tried, decided, or ruled out. I either re-explained everything from memory, or let the new agent guess and re-discover things the old one already knew.&lt;/p&gt;

&lt;p&gt;This is not only a documentation problem. It is a structural problem in AI-assisted development.&lt;/p&gt;

&lt;p&gt;We use several tools to produce one project, but every tool keeps a separate, temporary memory.&lt;/p&gt;

&lt;p&gt;That experience became ContextVault.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2pjb8bbnks0uv7ze1tfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2pjb8bbnks0uv7ze1tfb.png" alt="ContextVault Desktop dashboard" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  First: what is ContextVault?
&lt;/h2&gt;

&lt;p&gt;ContextVault is an open-source, local-first memory layer for AI work.&lt;/p&gt;

&lt;p&gt;It preserves useful context from browser LLM conversations, terminals, and coding-agent sessions, then makes that context searchable and reusable in later sessions.&lt;/p&gt;

&lt;p&gt;Think of the distinction this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git:          what changed in the code?
ContextVault: why did we change it, what failed, and what should happen next?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trigger for building it was specifically the agent-switching problem: whenever one agent ran out of credits or hit a limit, I needed the next one to pick up exactly where the last one left off, instead of restarting the investigation.&lt;/p&gt;

&lt;p&gt;ContextVault has three user-facing surfaces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Browser Capture&lt;/strong&gt; — a Chrome extension that stores supported LLM conversations locally and exports Markdown or ZIP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vault Terminal&lt;/strong&gt; — an npm CLI for recording agent work, decisions, tasks, problems, and notes inside a project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ContextVault Desktop&lt;/strong&gt; — a visual app for recording, browsing, retrieving, preparing, and exporting that project context.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is no required account or ContextVault backend. Browser data stays in the browser. Project sessions stay in local Markdown.&lt;/p&gt;




&lt;h2&gt;
  
  
  A concrete example
&lt;/h2&gt;

&lt;p&gt;Initialize ContextVault inside a repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @aliabdm/contextvault init
contextvault record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the session, preserve only the context that may matter later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/title Fix authentication callback
/source codex
/user The login redirects back to the sign-in page.
/agent The session cookie is missing during the callback.
/decision Keep authentication checks in middleware.
/problem The previous SameSite change did not fix the callback.
/task Add a regression test for the redirect loop.
/end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is readable Markdown under:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.contextvault/sessions/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, a developer or agent can ask for evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault &lt;span class="nb"&gt;history&lt;/span&gt; &lt;span class="nt"&gt;--since&lt;/span&gt; 2w
contextvault decisions auth &lt;span class="nt"&gt;--source&lt;/span&gt; codex
contextvault problems auth &lt;span class="nt"&gt;--since&lt;/span&gt; 30d
contextvault retrieve &lt;span class="s2"&gt;"authentication callback"&lt;/span&gt;
contextvault prepare &lt;span class="s2"&gt;"fix authentication callback"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;retrieve&lt;/code&gt; ranks relevant local events. &lt;code&gt;prepare&lt;/code&gt; creates a focused Markdown package for the next agent.&lt;/p&gt;

&lt;p&gt;The current engine is deterministic and lexical. It does not send the project to an LLM or generate an ungrounded answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why build a Desktop app?
&lt;/h2&gt;

&lt;p&gt;The CLI proved the model, but it limited the audience.&lt;/p&gt;

&lt;p&gt;Someone who simply wants "authentication decisions from the last month" should not need to know this syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault decisions auth &lt;span class="nt"&gt;--source&lt;/span&gt; codex &lt;span class="nt"&gt;--since&lt;/span&gt; 30d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I built an Electron app over the package.&lt;/p&gt;

&lt;p&gt;The first version exposed command buttons and a raw arguments field.&lt;/p&gt;

&lt;p&gt;Technically, this preserved package compatibility. From a UX perspective, it was still asking users to think like a shell parser.&lt;/p&gt;

&lt;p&gt;The app was a GUI, but not yet a Desktop product.&lt;/p&gt;

&lt;p&gt;The redesign goal became similar to Docker CLI and Docker Desktop:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Share the engine and data model, but give each surface a complete experience.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The dangerous shortcut: implementing everything twice
&lt;/h2&gt;

&lt;p&gt;The easiest way to build the GUI would have been to give Desktop its own recorder and database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLI      -&amp;gt; Markdown
Desktop  -&amp;gt; SQLite or custom JSON
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would immediately create two versions of ContextVault.&lt;/p&gt;

&lt;p&gt;Sessions, migrations, bug fixes, and indexing behavior would eventually drift. Existing CLI users would need imports or conversions before using Desktop.&lt;/p&gt;

&lt;p&gt;Instead, the architecture keeps one source of truth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser exports       CLI / agents       Desktop recorder
       \                   |                    /
        \                  |                   /
                 .contextvault Markdown
                           |
                    local Context Engine
                           |
       History · Search · Retrieve · Prepare · Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desktop is a GUI over the same engine and files—not a second implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  How recording works inside Electron
&lt;/h2&gt;

&lt;p&gt;When the user clicks &lt;strong&gt;Start recording&lt;/strong&gt;, the Electron main process launches the bundled package recorder with the selected project as its working directory.&lt;/p&gt;

&lt;p&gt;The renderer only receives a narrow preload API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;startRecorder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nf"&gt;sendRecorderCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recorderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;finishRecorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recorderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;cancelRecorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recorderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An entry created in the GUI is sent to the real recorder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contextVault&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRecorderCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;recorderId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`/decision &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package writes the final session Markdown.&lt;/p&gt;

&lt;p&gt;This means a session created in Desktop is visible to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault list
contextvault show &amp;lt;session-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No conversion step is required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0y2t20sk3rwth0relqm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0y2t20sk3rwth0relqm9.png" alt="ContextVault Desktop recorder" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How CLI sessions appear live in Desktop
&lt;/h2&gt;

&lt;p&gt;Compatibility also needs to work in the opposite direction.&lt;/p&gt;

&lt;p&gt;The main process watches the active project's session directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;vaultWatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionsPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vaultRefreshTimer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vaultRefreshTimer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;vaultRefreshTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getEngine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildContextIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;mainWindow&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contextvault:vault-changed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The delay debounces bursts of file events. After rebuilding the index, open renderer views refresh.&lt;/p&gt;

&lt;p&gt;The UI exposes the watcher state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Watching project&lt;/li&gt;
&lt;li&gt;Last updated&lt;/li&gt;
&lt;li&gt;Events found&lt;/li&gt;
&lt;li&gt;Sources detected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the integration test, I kept Desktop open and recorded a session from the external CLI. Without reopening the app, the session count increased from 3 to 4, the event count increased from 14 to 16, and &lt;code&gt;terminal&lt;/code&gt; appeared as a detected source.&lt;/p&gt;

&lt;p&gt;That was the moment the CLI and GUI stopped feeling like separate products.&lt;/p&gt;




&lt;h2&gt;
  
  
  Turning commands into actual workflows
&lt;/h2&gt;

&lt;p&gt;The redesign replaced the default arguments field with screens based on user intent.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What the user wants&lt;/th&gt;
&lt;th&gt;Desktop workflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Capture project context&lt;/td&gt;
&lt;td&gt;Recorder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browse or export a session&lt;/td&gt;
&lt;td&gt;Sessions / Session Detail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Understand recent activity&lt;/td&gt;
&lt;td&gt;History&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Find previous choices&lt;/td&gt;
&lt;td&gt;Decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review bugs and failed attempts&lt;/td&gt;
&lt;td&gt;Problems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review follow-up work&lt;/td&gt;
&lt;td&gt;Tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rank evidence for a question&lt;/td&gt;
&lt;td&gt;Retrieve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Find matching text&lt;/td&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build context for another agent&lt;/td&gt;
&lt;td&gt;Prepare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connect related sessions&lt;/td&gt;
&lt;td&gt;Link Sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintain the local vault&lt;/td&gt;
&lt;td&gt;Index, Memory, Timeline, Export&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;History, for example, supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since: 24 hours, 7, 14, or 30 days, all time, or a custom date&lt;/li&gt;
&lt;li&gt;Source: Codex, Claude Code, Cursor, ChatGPT, manual, terminal, or browser&lt;/li&gt;
&lt;li&gt;Event type: decision, problem, task, note, user, or agent&lt;/li&gt;
&lt;li&gt;Maximum results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Results are grouped, readable, copyable, and exportable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1khv2ui3kgmqxrv69cq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1khv2ui3kgmqxrv69cq5.png" alt="History filters and results" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The raw runner still exists inside collapsed &lt;strong&gt;Advanced CLI Mode&lt;/strong&gt; for uncommon flags. It is no longer the normal experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Search, Retrieve, and Prepare are different
&lt;/h2&gt;

&lt;p&gt;These features can sound interchangeable, so the UI and documentation separate them:&lt;/p&gt;

&lt;h3&gt;
  
  
  Search
&lt;/h3&gt;

&lt;p&gt;Find matching events and sessions using text and filters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retrieve
&lt;/h3&gt;

&lt;p&gt;Rank the local evidence most relevant to a task. The deterministic scorer considers exact phrases, tokens, event importance, recency, and filters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prepare
&lt;/h3&gt;

&lt;p&gt;Turn retrieved evidence into a portable Markdown context package for the next model or agent.&lt;/p&gt;

&lt;p&gt;ContextVault does not currently pretend to answer a project question using an AI model. It retrieves inspectable evidence and lets the user decide where to send it next.&lt;/p&gt;




&lt;h2&gt;
  
  
  What "automatic" does and does not mean
&lt;/h2&gt;

&lt;p&gt;ContextVault Desktop automatically notices compatible sessions written into the watched vault.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; silently intercept every unrelated Codex, Claude Code, Cursor, VS Code, terminal, screen, clipboard, or microphone process.&lt;/p&gt;

&lt;p&gt;An external tool currently appears automatically only if it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Records through the ContextVault CLI, or&lt;/li&gt;
&lt;li&gt;Writes a compatible session file into &lt;code&gt;.contextvault&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Direct agent adapters and an MCP server are future integrations.&lt;/p&gt;

&lt;p&gt;This boundary is intentional. Local-first software should not hide its capture behavior behind vague marketing language.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification beyond "it builds"
&lt;/h2&gt;

&lt;p&gt;The release was checked across the entire compatibility story:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Package and extension tests          63 passed
Browser extension production build  passed
Desktop renderer type-check          passed
Desktop production build            passed
Windows installer packaging         passed
GitHub Actions Windows build         passed
GitHub Actions Linux build           passed
CLI -&amp;gt; open Desktop live refresh     passed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Desktop release became v1.8.0. The npm package remained v1.3.0 because the Desktop-only changes did not modify the published package code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next: collaborative context repositories
&lt;/h2&gt;

&lt;p&gt;The next phase is Git-like collaboration for context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push a selected vault to a repository&lt;/li&gt;
&lt;li&gt;Invite collaborators&lt;/li&gt;
&lt;li&gt;Pull shared context&lt;/li&gt;
&lt;li&gt;Review diffs and history&lt;/li&gt;
&lt;li&gt;Edit locally&lt;/li&gt;
&lt;li&gt;Push reviewed changes&lt;/li&gt;
&lt;li&gt;Resolve conflicts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difficult part is not remote storage. It is preserving provenance, reviewability, and user ownership while several humans and agents modify shared project memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try ContextVault
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @aliabdm/contextvault init
contextvault record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/aliabdm/ContextVault" rel="noopener noreferrer"&gt;https://github.com/aliabdm/ContextVault&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Desktop: &lt;a href="https://context-vault-two.vercel.app/download" rel="noopener noreferrer"&gt;https://context-vault-two.vercel.app/download&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Product walkthrough: &lt;a href="https://context-vault-two.vercel.app/" rel="noopener noreferrer"&gt;https://context-vault-two.vercel.app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/@aliabdm/contextvault" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@aliabdm/contextvault&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Technical FAQ: &lt;a href="https://context-vault-two.vercel.app/faq" rel="noopener noreferrer"&gt;https://context-vault-two.vercel.app/faq&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Portfolio: &lt;a href="https://senior-mohammad-ali.vercel.app/" rel="noopener noreferrer"&gt;https://senior-mohammad-ali.vercel.app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn : &lt;a href="https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>electron</category>
      <category>node</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>ContextVault: Own Your AI Context Across Models, Agents, and Time</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Sat, 27 Jun 2026 20:00:42 +0000</pubDate>
      <link>https://dev.to/maliano63717738/contextvault-own-your-ai-context-across-models-agents-and-time-555i</link>
      <guid>https://dev.to/maliano63717738/contextvault-own-your-ai-context-across-models-agents-and-time-555i</guid>
      <description>&lt;h2&gt;
  
  
  From Conversation Recorder to Context Engine: Building Local-First Memory for AI Development
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How ContextVault 1.3 unifies browser conversations, terminal sessions, and coding-agent decisions in one searchable local context engine — without a backend, tracking, or hidden AI calls.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;You spend forty-five minutes walking a coding agent through a Redis connection bug. Together, you find the root cause, test a fix, and uncover a configuration detail that is not documented anywhere. Then the context window fills up. Two weeks later, the same bug appears in staging. The original session is gone, the browser conversation is buried, and the next agent knows nothing about what you already discovered. You start again. This is context fragmentation: project knowledge scattered across ChatGPT conversations, coding-agent sessions, terminals, accounts, models, and limited context windows. It creates a quiet tax on every AI-assisted workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjrogvi2fu8y9mc9wxz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjrogvi2fu8y9mc9wxz7.png" alt="Diagram: Context fragmentation across browser chats, terminal sessions, coding agents, and context windows" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exporting conversations helps, but only partially. A directory full of Markdown exports is still a directory full of disconnected files. The information is preserved, but it is not organized as project memory. That distinction changed the direction of ContextVault. What began as a browser conversation recorder evolved into a local-first context engine designed around a broader idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Git tracks code. ContextVault tracks context.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Exporting Conversations Is Not Enough
&lt;/h2&gt;

&lt;p&gt;I originally built ContextVault as a Chrome extension for capturing conversations across multiple LLM platforms. The extension solved an immediate problem: preserving complete conversations locally and exporting them in portable formats.&lt;/p&gt;

&lt;p&gt;But capturing browser conversations addressed only one surface.&lt;/p&gt;

&lt;p&gt;The decisions that shaped a project were also happening inside Codex sessions, Claude Code investigations, Cursor workflows, terminal debugging, human notes, failed experiments, and task discussions. Those sessions often disappeared when a terminal closed or an agent reached its context limit.&lt;/p&gt;

&lt;p&gt;I did not need another folder of exports. I needed a way to preserve what happened, classify it, search it, and prepare it for the next agent.&lt;/p&gt;

&lt;p&gt;That led to three connected layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Browser Capture&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vault Terminal&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Unified Context Engine&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fye58u9dj943rfivu9s0y.png" alt="Context Fragmentation" width="800" height="450"&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Layer One: Building Browser Capture
&lt;/h2&gt;

&lt;p&gt;Browser Capture is the original ContextVault surface. It is a Chrome Manifest V3 extension that captures conversations from ChatGPT, Claude, Gemini, Perplexity, Poe, DeepSeek, and Copilot.&lt;/p&gt;

&lt;p&gt;The extension uses a hybrid DOM and network capture strategy. It watches provider DOM mutations, observes supported network responses, assembles streamed messages in the content-capture layer, and sends finalized messages to the background service worker for local storage.&lt;/p&gt;

&lt;p&gt;This hybrid approach matters because LLM interfaces are dynamic. Assistant responses arrive incrementally, DOM elements change while streaming, and provider implementations differ.&lt;/p&gt;

&lt;p&gt;Once captured, conversations remain in IndexedDB by default. Users can export them as individual Markdown files or bulk ZIP archives. Each exported conversation includes YAML frontmatter containing metadata such as platform, model, date, conversation ID, and tags.&lt;/p&gt;

&lt;p&gt;The data flow is intentionally contained:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provider page
    ↓
DOM and supported network capture
    ↓
Stream assembly
    ↓
Background service worker
    ↓
Local IndexedDB storage
    ↓
Explicit Markdown or ZIP export
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension does not send captured conversations to a ContextVault server because no ContextVault server exists. It does not require an account, collect telemetry, or call an external AI API.&lt;/p&gt;

&lt;p&gt;Browser Capture solved the first problem: preserving conversations. It did not yet solve project memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer Two: Building Vault Terminal
&lt;/h2&gt;

&lt;p&gt;Browser conversations are only part of an AI development workflow. Important context also appears while working with coding agents and terminals: a failed authentication fix, a decision about middleware boundaries, an unresolved production problem, a task discovered during debugging, a note explaining why one approach was rejected.&lt;/p&gt;

&lt;p&gt;Vault Terminal provides an explicit way to record those moments. It is a Node.js CLI published on npm as &lt;code&gt;@aliabdm/contextvault&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run it directly without installing anything globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @aliabdm/contextvault init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @aliabdm/contextvault
contextvault init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start recording:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the recorder, context is entered using typed commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/source codex
/title Fix auth middleware

/user The login redirect is broken.

/agent I found the issue in middleware order.

/decision Keep auth checks in middleware and policy checks in controllers.

/task Add a regression test for the redirect loop.

/problem The session cookie is missing on callback.

/end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands become structured context events. Each session is saved as a local Markdown file under &lt;code&gt;.contextvault/sessions/&lt;/code&gt;. The files are human-readable, inspectable, searchable with standard tools, easy to archive, and ignored by Git by default.&lt;/p&gt;

&lt;p&gt;There is no automatic summarization, rewriting, or external model call. Vault Terminal records what you explicitly provide. It does not intercept every terminal process or automatically capture complete Codex, Claude Code, or Cursor sessions. That limitation is deliberate and visible.&lt;/p&gt;

&lt;p&gt;The CLI also supports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault list
contextvault search &lt;span class="s2"&gt;"Redis"&lt;/span&gt;
contextvault &lt;span class="nb"&gt;export&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vault Terminal solved the second problem: preserving agent work, decisions, tasks, problems, and notes outside the browser.&lt;/p&gt;

&lt;p&gt;The next challenge was connecting both capture surfaces.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer Three: Building the Unified Context Engine
&lt;/h2&gt;

&lt;p&gt;The Unified Context Engine turns separate captures into searchable project context. It imports Browser Capture exports, reads Vault Terminal sessions, normalizes both sources into shared models, and builds a local index.&lt;/p&gt;

&lt;p&gt;Browser exports can be imported from Markdown files, ZIP archives, or directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault import ./chatgpt-export.md
contextvault import ./contextvault-export.zip
contextvault import ./browser-exports/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The importer reads Markdown entries in memory, validates ContextVault frontmatter, sanitizes filenames, prevents unsafe archive extraction, applies deterministic duplicate detection, and enforces safety limits.&lt;/p&gt;

&lt;p&gt;Current limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100 MB per archive&lt;/li&gt;
&lt;li&gt;10 MB per Markdown file&lt;/li&gt;
&lt;li&gt;1,000 files per import
ZIP entries are processed in memory rather than extracted to arbitrary disk paths. If the same export is imported twice, the duplicate is skipped. If an updated export shares the same &lt;code&gt;conversation_id&lt;/code&gt;, the existing source is updated rather than duplicated.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Normalizing Different Context Sources
&lt;/h3&gt;

&lt;p&gt;Browser chats and terminal sessions do not begin with the same structure. The normalization layer maps both into two shared models: &lt;code&gt;ContextSession&lt;/code&gt; and &lt;code&gt;ContextEvent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Browser messages are mapped as user and agent events, with platform and role metadata preserved. Terminal events retain their explicit types: &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;agent&lt;/code&gt;, &lt;code&gt;decision&lt;/code&gt;, &lt;code&gt;task&lt;/code&gt;, &lt;code&gt;problem&lt;/code&gt;, and &lt;code&gt;note&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The normalizer also supports legacy &lt;code&gt;snake_case&lt;/code&gt; metadata fields — &lt;code&gt;started_at&lt;/code&gt;, &lt;code&gt;ended_at&lt;/code&gt;, &lt;code&gt;git_branch&lt;/code&gt; — alongside current camelCase fields. This keeps existing Markdown sessions readable without requiring a destructive migration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0vim0xjr9sxno853fjcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0vim0xjr9sxno853fjcy.png" alt="Context Model" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the Local Index
&lt;/h3&gt;

&lt;p&gt;After importing or recording context, rebuild the index with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engine reads terminal sessions and imported browser conversations, normalizes them, and writes a local JSON index to &lt;code&gt;.contextvault/index/context-index.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Markdown remains the source of truth. The JSON index is derived data. If it becomes corrupted or outdated, delete it and rebuild from the original Markdown files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local Markdown
    ↓
Normalize
    ↓
Rebuildable JSON index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no proprietary database format and no dependency on a hosted service. Users can inspect, edit, archive, or process their context without ContextVault.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retrieving Evidence Across Capture Surfaces
&lt;/h3&gt;

&lt;p&gt;Once indexed, context can be queried across both surfaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault &lt;span class="nb"&gt;history&lt;/span&gt; &lt;span class="nt"&gt;--since&lt;/span&gt; 2w
contextvault decisions auth &lt;span class="nt"&gt;--source&lt;/span&gt; codex
contextvault problems redis &lt;span class="nt"&gt;--since&lt;/span&gt; 30d
contextvault retrieve &lt;span class="s2"&gt;"auth middleware"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; decision,task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supported filters: &lt;code&gt;--type&lt;/code&gt;, &lt;code&gt;--source&lt;/code&gt;, &lt;code&gt;--since&lt;/code&gt;, &lt;code&gt;--limit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Retrieval is local and deterministic. Ranking considers phrase matches, token matches, event-type boosts, and recency. It does not use embeddings, vector databases, semantic search, external models, or hidden AI calls.&lt;/p&gt;

&lt;p&gt;The engine answers: &lt;em&gt;What have I captured about this topic?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It does not claim to answer: &lt;em&gt;What does all my project data mean?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The first question is grounded and testable. The second requires a semantic retrieval layer that ContextVault does not currently include.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparing Context for the Next Agent
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;prepare&lt;/code&gt; command creates a focused context package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault prepare &lt;span class="s2"&gt;"auth middleware"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated file is written to &lt;code&gt;.contextvault/exports/prepared-context.md&lt;/code&gt;. It can include project memory, relevant sessions, decisions, tasks, problems, and source metadata — portable Markdown that can be handed directly to Codex, Claude Code, Cursor, or another AI tool.&lt;/p&gt;

&lt;p&gt;ContextVault does not call those tools. It prepares grounded context for the user to move explicitly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm2ty3wt19m1q8u6m4oq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm2ty3wt19m1q8u6m4oq0.png" alt="Context Engine" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The architecture separates four responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capture&lt;/strong&gt; preserves browser or terminal context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normalization&lt;/strong&gt; converts sources into shared records&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indexing and retrieval&lt;/strong&gt; make those records searchable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preparation&lt;/strong&gt; produces portable context for another agent
This separation creates boundaries for future adapters without changing the core storage model.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Integrations are adapters. The engine is the product.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Markdown Remains the Source of Truth
&lt;/h2&gt;

&lt;p&gt;Project context should remain usable without the application that created it. A proprietary database can be fast, but it also creates dependency and obscures the raw material.&lt;/p&gt;

&lt;p&gt;Markdown provides different guarantees: it opens in any editor, works with standard search tools, can be archived directly, remains readable if ContextVault disappears, and can be transformed with scripts or moved between tools.&lt;/p&gt;

&lt;p&gt;The JSON index exists for retrieval performance. It is disposable. The Markdown is not.&lt;/p&gt;

&lt;p&gt;Git tracks code history. ContextVault preserves the discussions, failed attempts, decisions, and discoveries surrounding that code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Privacy by Design
&lt;/h2&gt;

&lt;p&gt;ContextVault follows a local-first model. No captured data is sent to a ContextVault backend because there is no backend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No backend&lt;/strong&gt; — data remains on the local machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No accounts&lt;/strong&gt; — users control their own context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No telemetry&lt;/strong&gt; — no usage tracking of any kind&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No external AI calls&lt;/strong&gt; — terminal capture and retrieval work entirely locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No automatic cloud sync&lt;/strong&gt; — files stay where you put them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No hidden model calls&lt;/strong&gt; — retrieval stays deterministic
The &lt;code&gt;.contextvault/&lt;/code&gt; directory is ignored by Git by default. This matters because raw sessions may contain prompts, local paths, environment details, logs, debugging output, and potential secrets. Automatically committing that material would be an irresponsible default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users can choose how to archive or back up their files. ContextVault does not make that choice for them.&lt;/p&gt;




&lt;h2&gt;
  
  
  What ContextVault Does Not Do Yet
&lt;/h2&gt;

&lt;p&gt;A useful technical project should make its boundaries as visible as its features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No automatic terminal-agent interception.&lt;/strong&gt; Vault Terminal captures what the user explicitly records. It does not hook into every shell process or capture complete Codex, Claude Code, or Cursor sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No semantic search.&lt;/strong&gt; Retrieval is lexical and deterministic. Optional local semantic indexing is future work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No built-in natural-language answers.&lt;/strong&gt; ContextVault retrieves evidence and prepares context packages. It does not synthesize answers. Users provide the prepared Markdown to the model they choose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No automatic IndexedDB synchronization.&lt;/strong&gt; Browser conversations enter the Context Engine through explicit Markdown or ZIP export and import. The extension does not automatically synchronize with &lt;code&gt;.contextvault/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser adapters can change.&lt;/strong&gt; LLM providers regularly modify their interfaces. Provider changes may require adapter updates, and the generic adapter remains best-effort.&lt;/p&gt;

&lt;p&gt;These are not hidden limitations. They are the honest boundaries of ContextVault 1.3.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who ContextVault Is For
&lt;/h2&gt;

&lt;p&gt;ContextVault is useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You switch between ChatGPT, Codex, Claude Code, Cursor, or other tools&lt;/li&gt;
&lt;li&gt;Coding-agent context windows reset during ongoing work&lt;/li&gt;
&lt;li&gt;You need to revisit what an agent attempted several days ago&lt;/li&gt;
&lt;li&gt;You want a searchable record of project decisions and problems&lt;/li&gt;
&lt;li&gt;You need portable context packages that can move explicitly between tools&lt;/li&gt;
&lt;li&gt;You want local ownership without accounts or telemetry
It is especially relevant for developers whose AI workflow has grown larger than any single conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Not Just Use a Notes App?
&lt;/h3&gt;

&lt;p&gt;Notes applications are useful for polished summaries. They are less effective at preserving raw working context: the failed attempt before the fix, the partial command output that revealed the bug, the agent response that influenced a decision, the unresolved problem discovered during another task, the reason an architectural approach was rejected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7cnjthlaaez7gsqwf7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg7cnjthlaaez7gsqwf7m.png" alt="Note App VS ContextVault" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ContextVault preserves that intermediate state. An &lt;code&gt;/agent&lt;/code&gt; event records what the agent said — not what you later remember. A &lt;code&gt;/decision&lt;/code&gt; event captures an explicit project decision. A &lt;code&gt;/problem&lt;/code&gt; event keeps an unresolved issue available for future retrieval.&lt;/p&gt;

&lt;p&gt;ContextVault is not a replacement for documentation. It is the context layer that makes future documentation easier to produce because the underlying evidence remains searchable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;p&gt;The Unified Context Engine now exists. The next phase is reducing manual handoffs and improving retrieval without weakening the local-first model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server&lt;/strong&gt; — Expose project context through the Model Context Protocol so compatible agents can query it through an explicit integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VS Code Extension&lt;/strong&gt; — Surface project decisions, tasks, problems, and related sessions directly inside the editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent Integrations&lt;/strong&gt; — Build adapters for Codex, Claude Code, Cursor, and similar tools that can emit the shared context structure automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional Local Semantic Indexing&lt;/strong&gt; — Improve ranking with optional local embeddings while preserving the existing deterministic retrieval path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encrypted Backups and Optional Self-Hosted Sync&lt;/strong&gt; — Support off-machine durability without requiring a third-party hosted service.&lt;/p&gt;

&lt;p&gt;These are roadmap items, not implemented features. The current architecture provides the shared models, normalization layer, index schema, and adapter boundaries needed to build them incrementally.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try ContextVault
&lt;/h2&gt;

&lt;p&gt;ContextVault is fully open source and available today under the MIT License.&lt;/p&gt;

&lt;p&gt;Initialize Vault Terminal directly from npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @aliabdm/contextvault init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install it globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @aliabdm/contextvault
contextvault init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start recording:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build and query the local context index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contextvault index
contextvault &lt;span class="nb"&gt;history&lt;/span&gt; &lt;span class="nt"&gt;--since&lt;/span&gt; 2w
contextvault retrieve &lt;span class="s2"&gt;"auth middleware"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Capture browser conversations, record coding-agent sessions, build a local context index, and prepare grounded context packages — all while keeping your data on your own machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aliabdm/ContextVault" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@aliabdm/contextvault" rel="noopener noreferrer"&gt;npm Package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://context-vault-two.vercel.app/" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://context-vault-two.vercel.app/faq" rel="noopener noreferrer"&gt;Technical FAQ&lt;/a&gt;
If you try ContextVault, I'd genuinely appreciate technical feedback. Does retrieval surface the context you expected? Is there a command or workflow you think is missing? How would you improve the developer experience?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to open an issue, submit a pull request, or connect with me on &lt;a href="https://www.linkedin.com/in/mohammad-ali-abdul-wahed/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  About the Author
&lt;/h2&gt;

&lt;p&gt;Mohammad Ali Abdul Wahed is a Senior Software Engineer specializing in backend systems, Laravel, distributed applications, and AI developer tooling. He is the creator of ContextVault, an open-source local-first context platform that combines a Chrome Extension and an npm CLI to preserve browser conversations, coding-agent sessions, project decisions, and developer workflows across AI tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aliabdm" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://www.linkedin.com/in/mohammad-ali-abdul-wahed/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; · &lt;a href="https://senior-mohammad-ali.vercel.app/" rel="noopener noreferrer"&gt;Portfolio&lt;/a&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>opensource</category>
      <category>npm</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your AI Chats Are Locked in Corporate Silos. I Built an Open-Source Vault to Rescue Them</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Tue, 26 May 2026 18:47:10 +0000</pubDate>
      <link>https://dev.to/maliano63717738/your-ai-chats-are-locked-in-corporate-silos-i-built-an-open-source-vault-to-rescue-them-3nhk</link>
      <guid>https://dev.to/maliano63717738/your-ai-chats-are-locked-in-corporate-silos-i-built-an-open-source-vault-to-rescue-them-3nhk</guid>
      <description>&lt;h1&gt;
  
  
  I Kept Losing Context Switching Between AI Tools — So I Built a Browser Extension That Remembers Everything
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cvuf736i09mdxasfhg2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7cvuf736i09mdxasfhg2.gif" alt="ContextVault Demo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your AI conversations should not be trapped inside platforms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;By 2025, most developers use multiple AI tools every day.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT for quick questions&lt;/li&gt;
&lt;li&gt;Claude for long reasoning&lt;/li&gt;
&lt;li&gt;Gemini for research&lt;/li&gt;
&lt;li&gt;Perplexity for analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But every platform stores conversations separately.&lt;/p&gt;

&lt;p&gt;That creates a frustrating workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conversations get cut when context windows fill up&lt;/li&gt;
&lt;li&gt;Switching platforms destroys continuity&lt;/li&gt;
&lt;li&gt;Exporting chats is painful or incomplete&lt;/li&gt;
&lt;li&gt;Your history is tied to accounts you don’t control&lt;/li&gt;
&lt;li&gt;There’s no unified search across platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The knowledge you build with AI is trapped inside isolated silos.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Existing Solutions Didn’t Feel Right
&lt;/h2&gt;

&lt;p&gt;Some tools try solving this problem, but they usually require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paid APIs&lt;/li&gt;
&lt;li&gt;Backend servers&lt;/li&gt;
&lt;li&gt;Account linking&lt;/li&gt;
&lt;li&gt;Cloud syncing&lt;/li&gt;
&lt;li&gt;Monthly subscriptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something simpler.&lt;/p&gt;

&lt;p&gt;A question kept bothering me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if every AI conversation stayed entirely inside the browser?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No backend. No accounts. No tracking.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: ContextVault
&lt;/h2&gt;

&lt;p&gt;ContextVault is an open-source Chrome extension that captures AI conversations locally while you use platforms like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;Perplexity&lt;/li&gt;
&lt;li&gt;Poe&lt;/li&gt;
&lt;li&gt;DeepSeek&lt;/li&gt;
&lt;li&gt;Grok&lt;/li&gt;
&lt;li&gt;Microsoft Copilot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything stays on your machine.&lt;/p&gt;

&lt;p&gt;No telemetry. No external storage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F309keyjzqzhcaaqo7oy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F309keyjzqzhcaaqo7oy2.png" alt="ContextVault Screenshot" width="394" height="686"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  How It Works
&lt;/h1&gt;

&lt;p&gt;Capturing AI conversations reliably turned out to be harder than expected.&lt;/p&gt;

&lt;p&gt;There were two major problems:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Every platform has a different DOM structure
&lt;/h3&gt;

&lt;p&gt;Selectors, layouts, and rendering logic differ completely between ChatGPT, Claude, Gemini, and others.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AI responses stream in real time
&lt;/h3&gt;

&lt;p&gt;Messages arrive token-by-token instead of all at once.&lt;/p&gt;

&lt;p&gt;To solve this, ContextVault uses a 6-layer architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Adapters → Capture → Stream Assembler → Background Worker → Storage → Export
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  1. Adapters Layer
&lt;/h2&gt;

&lt;p&gt;Each platform has its own adapter implementing a shared interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;LLMAdapter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt;
  &lt;span class="nx"&gt;urlPattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;
  &lt;span class="nx"&gt;messageContainer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;userSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;assistantSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each adapter knows how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect the platform&lt;/li&gt;
&lt;li&gt;Locate messages&lt;/li&gt;
&lt;li&gt;Handle UI differences&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Capture Layer (DOM + Network)
&lt;/h2&gt;

&lt;p&gt;This is the core system.&lt;/p&gt;

&lt;h3&gt;
  
  
  DOM Observer
&lt;/h3&gt;

&lt;p&gt;A MutationObserver watches the conversation UI in real time.&lt;/p&gt;

&lt;p&gt;It detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New messages&lt;/li&gt;
&lt;li&gt;Streaming updates&lt;/li&gt;
&lt;li&gt;Edited content&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Network Monitor
&lt;/h3&gt;

&lt;p&gt;The extension also patches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetch&lt;/li&gt;
&lt;li&gt;XMLHttpRequest&lt;/li&gt;
&lt;li&gt;WebSocket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This provides early access to streaming responses directly from network traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why both?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;DOM reflects exactly what the user sees&lt;/li&gt;
&lt;li&gt;Network capture improves streaming accuracy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using both together dramatically reduced missed messages.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Stream Assembler
&lt;/h2&gt;

&lt;p&gt;AI responses arrive in chunks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hel"
"lo "
"world"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Stream Assembler rebuilds complete messages while handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chunk merging&lt;/li&gt;
&lt;li&gt;Duplicate removal&lt;/li&gt;
&lt;li&gt;Completion detection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Background Worker
&lt;/h2&gt;

&lt;p&gt;The background worker manages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Active sessions&lt;/li&gt;
&lt;li&gt;Conversation lifecycle&lt;/li&gt;
&lt;li&gt;Deduplication&lt;/li&gt;
&lt;li&gt;Streaming updates&lt;/li&gt;
&lt;li&gt;Conversation linking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also prevents duplicate saves during rapid streaming events.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Storage Layer (IndexedDB)
&lt;/h2&gt;

&lt;p&gt;Everything is stored locally using IndexedDB.&lt;/p&gt;

&lt;p&gt;Stored data includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conversations&lt;/li&gt;
&lt;li&gt;Drafts&lt;/li&gt;
&lt;li&gt;Settings&lt;/li&gt;
&lt;li&gt;Projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each conversation stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Platform&lt;/li&gt;
&lt;li&gt;Messages&lt;/li&gt;
&lt;li&gt;Timestamps&lt;/li&gt;
&lt;li&gt;Model information&lt;/li&gt;
&lt;li&gt;Tags&lt;/li&gt;
&lt;li&gt;Conversation chains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No external database is used.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Export Layer
&lt;/h2&gt;

&lt;p&gt;Conversations can be exported as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown&lt;/li&gt;
&lt;li&gt;ZIP archives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## User&lt;/span&gt;
How do I design a secure API?

&lt;span class="gu"&gt;## Assistant&lt;/span&gt;
Start with authentication, validation, and rate limiting...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1gu15b3qp35uhx9xfn23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1gu15b3qp35uhx9xfn23.png" alt="Markdown Export" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Privacy First
&lt;/h1&gt;

&lt;p&gt;ContextVault was designed around one principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your conversations belong to you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has no backend server&lt;/li&gt;
&lt;li&gt;Uses no analytics or telemetry&lt;/li&gt;
&lt;li&gt;Works fully offline&lt;/li&gt;
&lt;li&gt;Only activates on supported AI domains&lt;/li&gt;
&lt;li&gt;Never sends your conversations anywhere&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Tech Stack
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Manifest V3&lt;/li&gt;
&lt;li&gt;CRXJS + Vite&lt;/li&gt;
&lt;li&gt;IndexedDB&lt;/li&gt;
&lt;li&gt;MutationObserver&lt;/li&gt;
&lt;li&gt;JSZip&lt;/li&gt;
&lt;li&gt;Vitest&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;AI tools are becoming part of how we think, not just how we code.&lt;/p&gt;

&lt;p&gt;But memory between tools is still broken.&lt;/p&gt;

&lt;p&gt;Every platform acts like a closed silo where conversations disappear the moment you switch workflows.&lt;/p&gt;

&lt;p&gt;ContextVault is my attempt to fix that.&lt;/p&gt;

&lt;p&gt;A lightweight browser extension that keeps your AI conversations portable, searchable, and fully yours.&lt;/p&gt;




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

&lt;p&gt;GitHub: &lt;a href="https://github.com/aliabdm/ContextVault" rel="noopener noreferrer"&gt;https://github.com/aliabdm/ContextVault&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://context-vault-two.vercel.app/" rel="noopener noreferrer"&gt;https://context-vault-two.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://senior-mohammad-ali.vercel.app/" rel="noopener noreferrer"&gt;https://senior-mohammad-ali.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/&lt;/a&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>typescript</category>
      <category>opensource</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Building with Gemma 4: What I Learned From Turning Job Posts into AI Decisions</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Fri, 08 May 2026 20:03:55 +0000</pubDate>
      <link>https://dev.to/maliano63717738/building-with-gemma-4-what-i-learned-from-turning-job-posts-into-ai-decisions-30gg</link>
      <guid>https://dev.to/maliano63717738/building-with-gemma-4-what-i-learned-from-turning-job-posts-into-ai-decisions-30gg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Write About Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Building with Gemma 4: What I Learned From Turning Job Posts into AI Decisions
&lt;/h1&gt;

&lt;p&gt;I didn’t start this project to “explore AI”.&lt;/p&gt;

&lt;p&gt;I started it because job posts are messy.&lt;/p&gt;

&lt;p&gt;Some are vague. Some are misleading. Some look real but feel off once you read them twice.&lt;/p&gt;

&lt;p&gt;So I built something simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A tool that tells you what a job post actually means.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  The idea
&lt;/h1&gt;

&lt;p&gt;Ghost Job Detector takes a job description and returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this a real job?&lt;/li&gt;
&lt;li&gt;Is it a ghost job?&lt;/li&gt;
&lt;li&gt;Is it a scam?&lt;/li&gt;
&lt;li&gt;Or just a suspicious listing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But more importantly, it explains &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Gemma 4
&lt;/h1&gt;

&lt;p&gt;I used Gemma 4 because I needed something that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understand messy human-written job posts&lt;/li&gt;
&lt;li&gt;detect weak signals (not just keywords)&lt;/li&gt;
&lt;li&gt;reason about intent&lt;/li&gt;
&lt;li&gt;return structured output reliably&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ran it through OpenRouter using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gemma 4 26B MoE (primary)&lt;/li&gt;
&lt;li&gt;Gemma 4 31B Dense (fallback)&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  How people can actually use Gemma 4
&lt;/h1&gt;

&lt;p&gt;One thing that surprised me while working with Gemma 4 is how accessible it actually is.&lt;/p&gt;

&lt;p&gt;There are a few practical ways to use it depending on your setup:&lt;/p&gt;




&lt;h2&gt;
  
  
  1. OpenRouter (fastest way to start)
&lt;/h2&gt;

&lt;p&gt;This is what I used in this project.&lt;/p&gt;

&lt;p&gt;You can access Gemma models directly through OpenRouter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no infrastructure setup&lt;/li&gt;
&lt;li&gt;no local GPU needed&lt;/li&gt;
&lt;li&gt;just API calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s the easiest way to integrate Gemma 4 into a real application.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Google AI Studio
&lt;/h2&gt;

&lt;p&gt;Google also provides access through AI Studio.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;test prompts directly in the browser&lt;/li&gt;
&lt;li&gt;experiment with models&lt;/li&gt;
&lt;li&gt;generate API keys for integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s more of a playground for prototyping than production.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Running locally (fully free option)
&lt;/h2&gt;

&lt;p&gt;Gemma models are also open enough to run locally depending on size.&lt;/p&gt;

&lt;p&gt;Typical setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download model from Hugging Face or Kaggle&lt;/li&gt;
&lt;li&gt;Run using tools like:

&lt;ul&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;LM Studio&lt;/li&gt;
&lt;li&gt;Transformers (Python)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;full control&lt;/li&gt;
&lt;li&gt;no API limits&lt;/li&gt;
&lt;li&gt;no cost per request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But requires more setup and compute power.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;What I realized is that Gemma 4 isn’t tied to a single platform.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prototype fast with OpenRouter&lt;/li&gt;
&lt;li&gt;experiment with Google AI Studio&lt;/li&gt;
&lt;li&gt;or run fully offline locally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That flexibility is what makes it practical for real-world projects.&lt;/p&gt;

&lt;h1&gt;
  
  
  What actually matters in real usage
&lt;/h1&gt;

&lt;p&gt;One thing I learned quickly:&lt;/p&gt;

&lt;p&gt;The model is not the hard part.&lt;/p&gt;

&lt;p&gt;The hard part is making it behave consistently inside a product.&lt;/p&gt;

&lt;p&gt;That meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;forcing JSON structure&lt;/li&gt;
&lt;li&gt;validating outputs&lt;/li&gt;
&lt;li&gt;handling API failures&lt;/li&gt;
&lt;li&gt;retry logic for rate limits&lt;/li&gt;
&lt;li&gt;fallback between models&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Real example
&lt;/h1&gt;

&lt;p&gt;Here’s how the system behaves:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We are looking for a self-starter in a fast-paced environment."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verdict: Suspicious&lt;/li&gt;
&lt;li&gt;Reasoning: vague expectations + pressure signals&lt;/li&gt;
&lt;li&gt;HR translation: high workload, unclear structure, limited support&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  HR language is the real problem
&lt;/h1&gt;

&lt;p&gt;A lot of job descriptions don’t lie directly.&lt;/p&gt;

&lt;p&gt;They just hide meaning behind corporate phrases.&lt;/p&gt;

&lt;p&gt;So I added a “translation layer”:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Fast-paced environment” → high pressure, overtime likely
&lt;/li&gt;
&lt;li&gt;“Wear many hats” → multiple roles, single salary
&lt;/li&gt;
&lt;li&gt;“Self-starter required” → little onboarding or guidance
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This part turned out to be more useful than the classification itself.&lt;/p&gt;




&lt;h1&gt;
  
  
  The biggest engineering lesson
&lt;/h1&gt;

&lt;p&gt;The most important thing I learned:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;LLM behavior is mostly a product of constraints, not just model size.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gemma 4 became much more reliable when I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;strictly defined output schema&lt;/li&gt;
&lt;li&gt;reduced ambiguity in prompts&lt;/li&gt;
&lt;li&gt;enforced structure in responses&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Reliability matters more than intelligence
&lt;/h1&gt;

&lt;p&gt;Since I used free-tier API access, rate limits happened frequently.&lt;/p&gt;

&lt;p&gt;Instead of treating that as a blocker, I added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retry logic&lt;/li&gt;
&lt;li&gt;fallback between Gemma models&lt;/li&gt;
&lt;li&gt;graceful UI handling when AI is busy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result: the app never feels “broken”, even when the API is.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why I built this
&lt;/h1&gt;

&lt;p&gt;Not to replace recruiters.&lt;/p&gt;

&lt;p&gt;Not to automate hiring.&lt;/p&gt;

&lt;p&gt;But to help people avoid wasting time on job posts that don’t make sense.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final thought
&lt;/h1&gt;

&lt;p&gt;Building with Gemma 4 felt less like “using AI”&lt;/p&gt;

&lt;p&gt;and more like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;designing how AI should behave inside a real product.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That shift is what made this project interesting for me.&lt;/p&gt;




&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://ghost-job-detector-rlcx.vercel.app/" rel="noopener noreferrer"&gt;https://ghost-job-detector-rlcx.vercel.app/&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Code
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/aliabdm/Ghost-Job-Detector" rel="noopener noreferrer"&gt;https://github.com/aliabdm/Ghost-Job-Detector&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
      <category>ai</category>
    </item>
    <item>
      <title>Ghost Job Detector: An AI Tool Built With Gemma 4 to Decode Suspicious Job Posts</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Fri, 08 May 2026 18:55:49 +0000</pubDate>
      <link>https://dev.to/maliano63717738/ghost-job-detector-an-ai-tool-built-with-gemma-4-to-decode-suspicious-job-posts-3gof</link>
      <guid>https://dev.to/maliano63717738/ghost-job-detector-an-ai-tool-built-with-gemma-4-to-decode-suspicious-job-posts-3gof</guid>
      <description>&lt;p&gt;This is a submission for the &lt;br&gt;
Gemma 4 Challenge: Build with Gemma 4&lt;/p&gt;

&lt;p&gt;What I Built&lt;br&gt;
I built Ghost Job Detector, a simple web app that helps job seekers analyze suspicious job postings before they apply.&lt;/p&gt;

&lt;p&gt;The idea came from a real frustration: many job posts look legitimate at first glance, but they can be vague, recycled, misleading, or even scams. Job seekers often spend time tailoring resumes and applying before realizing the opportunity may not be real.&lt;/p&gt;

&lt;p&gt;Ghost Job Detector lets a user paste any job description and get a structured AI report that classifies the post as:&lt;/p&gt;

&lt;p&gt;Legit job&lt;br&gt;
Ghost job&lt;br&gt;
Scam&lt;br&gt;
Suspicious job posting&lt;br&gt;
The app also explains why it reached that verdict, highlights red flags, translates coded HR language into plain English, and recommends who should or should not apply.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;"Fast-paced environment" becomes "Expect pressure, shifting priorities, and possible overtime."&lt;br&gt;
"Wear many hats" becomes "You may be covering multiple roles without matching compensation."&lt;br&gt;
"Self-starter" becomes "There may be little onboarding, structure, or management support."&lt;br&gt;
The goal is not to replace human judgment. The goal is to give job seekers a fast, practical second opinion before they share personal information or invest time in a questionable listing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwymqu2c3ke9xm3zp20aq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwymqu2c3ke9xm3zp20aq.png" alt=" " width="800" height="1280"&gt;&lt;/a&gt;&lt;br&gt;
Demo&lt;br&gt;
Live demo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ghost-job-detector-rlcx.vercel.app/" rel="noopener noreferrer"&gt;https://ghost-job-detector-rlcx.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app flow is simple:&lt;/p&gt;

&lt;p&gt;Paste a job description.&lt;br&gt;
Click Analyze Job.&lt;br&gt;
Review the verdict, confidence score, red flags, HR translation, and candidate-fit advice.&lt;br&gt;
Key sections in the result:&lt;/p&gt;

&lt;p&gt;Verdict: legit, ghost job, scam, or suspicious&lt;br&gt;
Risk Signals: red flags and reasoning&lt;br&gt;
HR Reality Translator: corporate phrases decoded into real meaning&lt;br&gt;
Who Should Apply: inferred seniority, recommended roles, apply-if guidance, and do-not-apply-if guidance&lt;br&gt;
Code&lt;br&gt;
GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/aliabdm/Ghost-Job-Detector" rel="noopener noreferrer"&gt;https://github.com/aliabdm/Ghost-Job-Detector&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tech stack:&lt;/p&gt;

&lt;p&gt;Next.js App Router&lt;br&gt;
TypeScript&lt;br&gt;
Vanilla CSS&lt;br&gt;
OpenRouter API&lt;br&gt;
Gemma 4 models&lt;br&gt;
Vercel deployment&lt;br&gt;
Vercel Analytics&lt;br&gt;
Optional Docker setup for local development&lt;br&gt;
How I Used Gemma 4&lt;br&gt;
Gemma 4 is the reasoning engine at the center of this project.&lt;/p&gt;

&lt;p&gt;I used:&lt;/p&gt;

&lt;p&gt;google/gemma-4-26b-a4b-it:free as the primary model&lt;br&gt;
google/gemma-4-31b-it:free as the fallback model&lt;br&gt;
I chose the 26B MoE Gemma 4 model as the primary model because this project needs more than basic classification. The model has to read a messy job description, reason about intent, identify weak hiring signals, decode HR language, and return a consistent structured JSON response.&lt;/p&gt;

&lt;p&gt;The app asks Gemma 4 to return this normalized structure:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "verdict": "legit | ghost_job | scam | suspicious",&lt;br&gt;
  "confidence": 0.8,&lt;br&gt;
  "reasons": [],&lt;br&gt;
  "red_flags": [],&lt;br&gt;
  "summary": "",&lt;br&gt;
  "advice": "",&lt;br&gt;
  "hr_translation": [&lt;br&gt;
    {&lt;br&gt;
      "original": "",&lt;br&gt;
      "meaning": ""&lt;br&gt;
    }&lt;br&gt;
  ],&lt;br&gt;
  "who_should_apply": {&lt;br&gt;
    "recommended_roles": [],&lt;br&gt;
    "skill_level": "",&lt;br&gt;
    "apply_if": [],&lt;br&gt;
    "do_not_apply_if": []&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
Gemma 4 powers these parts of the product:&lt;/p&gt;

&lt;p&gt;Detecting ghost-job and scam signals&lt;br&gt;
Classifying the post with a clear verdict&lt;br&gt;
Explaining the reasoning in plain language&lt;br&gt;
Translating vague HR phrases into practical meaning&lt;br&gt;
Inferring the real seniority level behind the role&lt;br&gt;
Recommending who should apply and who should avoid the post&lt;br&gt;
I also added resilience around the model calls. If the primary Gemma 4 model is rate-limited or temporarily unavailable, the API silently retries once and then falls back to the Gemma 4 31B Dense model. If all Gemma 4 options are busy, the user gets a clean message instead of a broken UI.&lt;/p&gt;

&lt;p&gt;That model choice was intentional: the 26B MoE model gives the app strong practical reasoning for user-facing analysis, while the 31B Dense model provides a stronger fallback path while keeping the whole project inside the Gemma 4 ecosystem.&lt;/p&gt;

&lt;p&gt;What I Learned&lt;br&gt;
The most interesting part of this build was designing the prompt and response handling.&lt;/p&gt;

&lt;p&gt;A useful AI app needs more than a clever prompt. It needs:&lt;/p&gt;

&lt;p&gt;A strict schema&lt;br&gt;
Defensive JSON parsing&lt;br&gt;
Fallback behavior&lt;br&gt;
Clear UX when the model is busy&lt;br&gt;
A result format that normal users can understand quickly&lt;br&gt;
Gemma 4 was especially useful because the task depends on nuance. A suspicious job post is rarely suspicious because of one keyword. It is usually a combination of vague language, missing details, unrealistic requirements, odd application instructions, and implied working conditions.&lt;/p&gt;

&lt;p&gt;That made this a good fit for a reasoning model instead of a simple rules engine.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;br&gt;
Ghost Job Detector is a small project, but it solves a real problem: helping job seekers protect their time, attention, and personal information.&lt;/p&gt;

&lt;p&gt;The job market is noisy. Gemma 4 made it possible to turn unstructured job descriptions into clear, actionable guidance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/maliano63717738"&gt;https://dev.to/maliano63717738&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
      <category>ai</category>
    </item>
    <item>
      <title>I'm a Recruitment Professional, and This Is Best Way To Get A 100% Safe And High Payin Remote Job Now A day</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Fri, 08 May 2026 16:46:48 +0000</pubDate>
      <link>https://dev.to/maliano63717738/im-a-recruitment-professional-and-this-is-best-way-to-get-a-100-safe-and-high-payin-remote-job-4538</link>
      <guid>https://dev.to/maliano63717738/im-a-recruitment-professional-and-this-is-best-way-to-get-a-100-safe-and-high-payin-remote-job-4538</guid>
      <description>&lt;p&gt;Years in hiring taught me what wastes job seekers' time and what doesn't. micro1 doesn't. Here's an honest breakdown of how it works and why it matters for anyone struggling to find remote work.&lt;br&gt;
tags: career, remote, jobs, ai&lt;br&gt;
cover_image: &lt;a href="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=1200" rel="noopener noreferrer"&gt;https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=1200&lt;/a&gt;&lt;br&gt;
The Jobs Are Right Here — Start If You're Ready&lt;br&gt;
👉 [micro1 Open Roles — Remote, All Fields]&lt;br&gt;
&lt;a href="https://refer.micro1.ai/referral/jobs?referralCode=f8ce80b3-c190-4f22-815c-dee4a6457153&amp;amp;utm_source=referral&amp;amp;utm_medium=share&amp;amp;utm_campaign=job_referral" rel="noopener noreferrer"&gt;https://refer.micro1.ai/referral/jobs?referralCode=f8ce80b3-c190-4f22-815c-dee4a6457153&amp;amp;utm_source=referral&amp;amp;utm_medium=share&amp;amp;utm_campaign=job_referral&lt;/a&gt;&lt;br&gt;
Disclosure: I earn a referral reward if you get hired and complete 10+ hours of work. What follows is my honest professional opinion — I only recommend things I'd stand behind.&lt;/p&gt;

&lt;p&gt;Why I'm Writing This&lt;br&gt;
I work in recruitment. I've spent years watching talented people — motivated, skilled, willing to work — get chewed up by a hiring system that's inefficient by design.&lt;br&gt;
The problem I see most often, especially with younger professionals looking for remote opportunities, isn't a lack of talent. It's a lack of access and visibility. They don't know which platforms are worth their time. They apply to five job boards, hear nothing back for weeks, lose confidence, and repeat the cycle.&lt;br&gt;
I share resources when I find something that genuinely helps. micro1 is one of those resources.&lt;/p&gt;

&lt;p&gt;What Is micro1?&lt;br&gt;
micro1 is a Silicon Valley talent marketplace connecting global professionals with remote roles at AI companies and enterprises.&lt;br&gt;
Fields covered:&lt;/p&gt;

&lt;p&gt;Software engineering &amp;amp; QA&lt;br&gt;
Finance &amp;amp; data analysis&lt;br&gt;
Healthcare &amp;amp; legal&lt;br&gt;
AI training, annotation &amp;amp; review&lt;br&gt;
Audio, content &amp;amp; creative&lt;/p&gt;

&lt;p&gt;What immediately stood out: every listing includes the salary upfront. No vague "competitive pay." For anyone who's spent time negotiating blind, that's not a small thing.&lt;/p&gt;

&lt;p&gt;The Process — And Why It Actually Saves Time&lt;br&gt;
Most job platforms waste months of your life. Apply → silence → maybe a screen call in three weeks → more silence → repeat.&lt;br&gt;
micro1 compresses the whole cycle into ~48 hours.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Browse Jobs&lt;br&gt;
   ↓&lt;br&gt;
Apply + Upload Resume&lt;br&gt;
   ↓&lt;br&gt;
Skills Assessment (timed, domain-specific)&lt;br&gt;
   ↓&lt;br&gt;
AI Interview with Zara&lt;br&gt;
   ↓&lt;br&gt;
Human Recruiter Review&lt;br&gt;
   ↓&lt;br&gt;
Offer in Your Inbox&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zara Interview
&lt;/h2&gt;

&lt;p&gt;Zara is their AI recruiting agent. You do a structured video interview with it instead of waiting for a human calendar slot.&lt;br&gt;
As someone who understands recruiting from the inside, here's what I think they got right:&lt;/p&gt;

&lt;p&gt;Practice session first — identical format, zero stakes, just to understand how it works&lt;br&gt;
Domain-specific questions — they're testing real knowledge, not generic HR questions&lt;br&gt;
Consistent and location-neutral — same process whether you're in New York or Amman&lt;/p&gt;

&lt;p&gt;Pass Zara → human review → offer email with clear next steps if there's a fit.&lt;br&gt;
Payments for contractors: biweekly via Deel, PayPal, or bank transfer.&lt;/p&gt;

&lt;p&gt;A Word for Young Professionals Searching for Remote Work&lt;br&gt;
If you're skilled, motivated, and spending your evenings scrolling through job boards that go nowhere — I want you to read this part carefully.&lt;br&gt;
Remote work has opened up real opportunities across the world. But most platforms still favor people in the right networks and the right cities. The infrastructure to actually access those opportunities hasn't kept pace.&lt;br&gt;
micro1 doesn't ask where you're from. It evaluates you on your skills through a standardized, structured process — and gives you an answer in 48 hours. That's what genuine access looks like. I think it's worth your time.&lt;/p&gt;

&lt;p&gt;The Honest Caveats&lt;br&gt;
I give people complete information. Here's what to know before applying:&lt;br&gt;
WhatDetails🪪 ID verificationGovernment ID required during onboarding — for contractor verification and fraud prevention. Non-standard but not a red flag.📭 Rejection feedbackLimited — you may not find out why you didn't pass the assessment📄 Contract modelContractors, not traditional FTEs. Great for flexibility, less ideal if you need immediate local employment benefits⏳ Some roles = talent poolA few listings are building a pipeline for upcoming projects. Your profile stays active regardless.&lt;/p&gt;

&lt;p&gt;My Take&lt;br&gt;
I recommend micro1 if you're a mid-to-senior professional in tech, finance, healthcare, legal, or AI-adjacent work, looking for flexible remote income through a fair and transparent process.&lt;br&gt;
Go browse the listings. Apply to what fits. You'll have your answer within 48 hours — which is more than most platforms will ever give you.&lt;br&gt;
👉 Browse micro1 Open Roles&lt;br&gt;
&lt;a href="https://refer.micro1.ai/referral/jobs?referralCode=f8ce80b3-c190-4f22-815c-dee4a6457153&amp;amp;utm_source=referral&amp;amp;utm_medium=share&amp;amp;utm_campaign=job_referral" rel="noopener noreferrer"&gt;https://refer.micro1.ai/referral/jobs?referralCode=f8ce80b3-c190-4f22-815c-dee4a6457153&amp;amp;utm_source=referral&amp;amp;utm_medium=share&amp;amp;utm_campaign=job_referral&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Questions about the process or remote job searching in general? Drop them in the comments — happy to help.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>hiring</category>
      <category>remote</category>
      <category>career</category>
    </item>
    <item>
      <title>I Built an AI Agent Showcase with Laravel AI SDK — Here’s How You Can Do It</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Fri, 06 Feb 2026 20:41:47 +0000</pubDate>
      <link>https://dev.to/maliano63717738/i-built-an-ai-agent-showcase-with-laravel-ai-sdk-heres-how-you-can-do-it-13ld</link>
      <guid>https://dev.to/maliano63717738/i-built-an-ai-agent-showcase-with-laravel-ai-sdk-heres-how-you-can-do-it-13ld</guid>
      <description>&lt;p&gt;How Laravel’s new AI SDK makes building production-ready AI features surprisingly simple (with mock mode for instant demos)&lt;br&gt;
Yesterday, Laravel released their official AI SDK. As someone who’s been watching the AI integration space closely, I knew this was going to be a game-changer for PHP developers.&lt;br&gt;
So I did what any excited developer would do at 11 PM: I built a complete showcase application in one night.&lt;/p&gt;

&lt;p&gt;The result? A fully functional AI agent with chat, image generation, text-to-speech, and vector search — all working in your browser right now, no API keys required.&lt;/p&gt;

&lt;p&gt;🔗 Live Demo: &lt;a href="https://laravel-ai-showcase.onrender.com/" rel="noopener noreferrer"&gt;https://laravel-ai-showcase.onrender.com/&lt;/a&gt;&lt;br&gt;
💻 GitHub: &lt;a href="https://github.com/aliabdm/laravel-ai-showcase" rel="noopener noreferrer"&gt;https://github.com/aliabdm/laravel-ai-showcase&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s exactly how I built it, and how you can do the same.&lt;/p&gt;

&lt;p&gt;The Problem with AI Integration&lt;br&gt;
Let me be honest: integrating AI into applications has traditionally been a pain. You’re juggling multiple SDKs, managing API credentials, handling streaming responses, dealing with rate limits, and building fallback systems.&lt;/p&gt;

&lt;p&gt;Most developers want to experiment with AI features, but the barrier to entry is high. You need API keys, credit cards, and often hours of setup before you can even see your first result.&lt;/p&gt;

&lt;p&gt;Laravel’s AI SDK solves this brilliantly.&lt;/p&gt;

&lt;p&gt;What We’re Building&lt;br&gt;
A complete AI showcase with:&lt;/p&gt;

&lt;p&gt;✨ AI Chat with real-time streaming&lt;br&gt;
🎨 Image Generation&lt;br&gt;
🔊 Text-to-Speech&lt;br&gt;
🔍 Vector Search with embeddings&lt;br&gt;
🎯 Mock Mode — try everything without API keys&lt;br&gt;
🔄 Session-based mode switching for instant demos&lt;br&gt;
Step 1: Project Setup &amp;amp; Installation&lt;br&gt;
Let’s start fresh:&lt;/p&gt;

&lt;h1&gt;
  
  
  Create new Laravel project
&lt;/h1&gt;

&lt;p&gt;laravel new ai-showcase&lt;br&gt;
cd ai-showcase&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Laravel AI SDK
&lt;/h1&gt;

&lt;p&gt;composer require laravel/ai&lt;/p&gt;

&lt;h1&gt;
  
  
  Publish configuration
&lt;/h1&gt;

&lt;p&gt;php artisan vendor:publish --tag=ai-config&lt;br&gt;
The configuration is beautifully simple:&lt;/p&gt;

&lt;p&gt;// config/ai.php&lt;br&gt;
return [&lt;br&gt;
    'mode' =&amp;gt; env('AI_MODE', 'mock'), // 'mock' or 'real'&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'providers' =&amp;gt; [
    'gemini' =&amp;gt; [
        'api_key' =&amp;gt; env('GEMINI_API_KEY'),
    ],
    'openai' =&amp;gt; [
        'api_key' =&amp;gt; env('OPENAI_API_KEY'),
    ],
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;];&lt;br&gt;
Step 2: The Secret Sauce — Mock Provider&lt;br&gt;
Here’s what makes this project special: a Mock Provider that lets anyone try the app instantly.&lt;/p&gt;

&lt;p&gt;Become a member&lt;br&gt;
No API keys. No setup. Just immediate results.&lt;/p&gt;

&lt;p&gt;// app/Ai/Providers/MockProvider.php&lt;br&gt;
namespace App\Ai\Providers;&lt;br&gt;
class MockProvider&lt;br&gt;
{&lt;br&gt;
    public function text(string $prompt): string&lt;br&gt;
    {&lt;br&gt;
        return "Hello! I'm a mock AI assistant. You asked: {$prompt}";&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function streamText(string $prompt): \Generator
{
    $response = $this-&amp;gt;text($prompt);
    $words = explode(' ', $response);

    foreach ($words as $word) {
        yield $word . ' ';
        usleep(100000); // 100ms delay for realistic streaming
    }
}

public function image(string $prompt): object
{
    return (object) [
        'url' =&amp;gt; 'https://placehold.co/600x400?text=' . urlencode($prompt),
        'prompt' =&amp;gt; $prompt,
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
This simple class saves hours of API setup and makes the app instantly demoable.&lt;/p&gt;

&lt;p&gt;Step 3: Smart Mode Switching&lt;br&gt;
Users need to switch between Mock and Real modes seamlessly. Here’s how:&lt;/p&gt;

&lt;p&gt;// app/Http/Middleware/AiModeMiddleware.php&lt;br&gt;
namespace App\Http\Middleware;&lt;br&gt;
class AiModeMiddleware&lt;br&gt;
{&lt;br&gt;
    public function handle($request, $next)&lt;br&gt;
    {&lt;br&gt;
        if ($request-&amp;gt;session()-&amp;gt;has('ai_mode')) {&lt;br&gt;
            config(['ai.mode' =&amp;gt; $request-&amp;gt;session()-&amp;gt;get('ai_mode')]);&lt;br&gt;
        }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    return $next($request);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
And the controller:&lt;/p&gt;

&lt;p&gt;// app/Http/Controllers/ModeController.php&lt;br&gt;
class ModeController extends Controller&lt;br&gt;
{&lt;br&gt;
    public function switch(Request $request)&lt;br&gt;
    {&lt;br&gt;
        $request-&amp;gt;validate(['mode' =&amp;gt; 'required|in:mock,real']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    $request-&amp;gt;session()-&amp;gt;put('ai_mode', $request-&amp;gt;mode);

    return response()-&amp;gt;json([
        'success' =&amp;gt; true,
        'mode' =&amp;gt; $request-&amp;gt;mode,
        'message' =&amp;gt; "Switched to {$request-&amp;gt;mode} mode"
    ]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Users can now toggle modes with a single click. No server restart needed.&lt;/p&gt;

&lt;p&gt;Step 4: Building AI Features&lt;br&gt;
Chat Feature&lt;br&gt;
public function chat(Request $request)&lt;br&gt;
{&lt;br&gt;
    $request-&amp;gt;validate(['message' =&amp;gt; 'required|string']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (config('ai.mode') === 'mock') {
    $response = $this-&amp;gt;mockProvider-&amp;gt;text($request-&amp;gt;message);
} else {
    $response = \Laravel\Ai\Facades\Ai::text($request-&amp;gt;message);
}

return response()-&amp;gt;json([
    'response' =&amp;gt; (string) $response,
    'mode' =&amp;gt; config('ai.mode')
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Image Generation&lt;br&gt;
public function generateImage(Request $request)&lt;br&gt;
{&lt;br&gt;
    $request-&amp;gt;validate(['prompt' =&amp;gt; 'required|string']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (config('ai.mode') === 'mock') {
    $image = $this-&amp;gt;mockProvider-&amp;gt;image($request-&amp;gt;prompt);
} else {
    $image = \Laravel\Ai\Facades\Ai::image($request-&amp;gt;prompt)
        -&amp;gt;landscape()
        -&amp;gt;generate();
}

return response()-&amp;gt;json(['url' =&amp;gt; $image-&amp;gt;url]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Text-to-Speech&lt;br&gt;
public function textToSpeech(Request $request)&lt;br&gt;
{&lt;br&gt;
    $request-&amp;gt;validate(['text' =&amp;gt; 'required|string']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (config('ai.mode') === 'mock') {
    $audio = $this-&amp;gt;mockProvider-&amp;gt;audio($request-&amp;gt;text);
} else {
    $audio = \Laravel\Ai\Facades\Ai::audio($request-&amp;gt;text)
        -&amp;gt;female()
        -&amp;gt;generate();
}

return response()-&amp;gt;json(['url' =&amp;gt; $audio-&amp;gt;url]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Notice the pattern? Every feature checks the mode and gracefully switches between mock and real AI.&lt;/p&gt;

&lt;p&gt;Step 5: Real-Time Streaming (The Highlight!)&lt;br&gt;
This is where it gets exciting. Real-time streaming makes AI responses feel instant and modern:&lt;/p&gt;

&lt;p&gt;// app/Http/Controllers/StreamingController.php&lt;br&gt;
public function streamWords(Request $request)&lt;br&gt;
{&lt;br&gt;
    $request-&amp;gt;validate(['prompt' =&amp;gt; 'required|string']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return response()-&amp;gt;stream(function () use ($request) {
    $provider = config('ai.mode') === 'mock' 
        ? $this-&amp;gt;mockProvider 
        : null;

    if ($provider) {
        foreach ($provider-&amp;gt;streamText($request-&amp;gt;prompt) as $chunk) {
            echo "data: " . json_encode(['chunk' =&amp;gt; $chunk]) . "\n\n";
            ob_flush();
            flush();
        }
    } else {
        $stream = \Laravel\Ai\Facades\Ai::stream($request-&amp;gt;prompt);
        foreach ($stream as $chunk) {
            echo "data: " . json_encode(['chunk' =&amp;gt; (string) $chunk]) . "\n\n";
            ob_flush();
            flush();
        }
    }

    echo "data: " . json_encode(['done' =&amp;gt; true]) . "\n\n";
}, 200, [
    'Content-Type' =&amp;gt; 'text/event-stream',
    'Cache-Control' =&amp;gt; 'no-cache',
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Frontend JavaScript to consume the stream:&lt;/p&gt;

&lt;p&gt;async function streamResponse(prompt) {&lt;br&gt;
    const response = await fetch('/streaming/words', {&lt;br&gt;
        method: 'POST',&lt;br&gt;
        headers: { &lt;br&gt;
            'Content-Type': 'application/json',&lt;br&gt;
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content&lt;br&gt;
        },&lt;br&gt;
        body: JSON.stringify({ prompt })&lt;br&gt;
    });&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reader = response.body.getReader();
const decoder = new TextDecoder();
let output = document.getElementById('output');
output.textContent = '';

while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const chunk = decoder.decode(value);
    const lines = chunk.split('\n');

    lines.forEach(line =&amp;gt; {
        if (line.startsWith('data: ')) {
            const data = JSON.parse(line.slice(6));
            if (data.chunk) {
                output.textContent += data.chunk;
            }
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Users see responses appear word-by-word in real-time. The UX improvement is dramatic.&lt;/p&gt;

&lt;p&gt;Step 6: Vector Search with Embeddings&lt;br&gt;
For semantic search capabilities:&lt;/p&gt;

&lt;p&gt;// Migration&lt;br&gt;
Schema::create('articles', function (Blueprint $table) {&lt;br&gt;
    $table-&amp;gt;id();&lt;br&gt;
    $table-&amp;gt;string('title');&lt;br&gt;
    $table-&amp;gt;text('content');&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if ($this-&amp;gt;vectorAvailable()) {
    $table-&amp;gt;vector('embedding', dimensions: 768)-&amp;gt;index();
} else {
    $table-&amp;gt;text('embedding')-&amp;gt;nullable();
}

$table-&amp;gt;timestamps();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;});&lt;br&gt;
Search implementation:&lt;/p&gt;

&lt;p&gt;public function semanticSearch(Request $request)&lt;br&gt;
{&lt;br&gt;
    $request-&amp;gt;validate(['query' =&amp;gt; 'required|string']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (config('ai.mode') === 'mock') {
    return response()-&amp;gt;json([
        'results' =&amp;gt; [
            ['title' =&amp;gt; 'Mock Result', 'content' =&amp;gt; 'Related to: ' . $request-&amp;gt;query],
        ]
    ]);
}

$results = Article::query()
    -&amp;gt;whereVectorSimilarTo('embedding', $request-&amp;gt;query)
    -&amp;gt;limit(10)
    -&amp;gt;get();

return response()-&amp;gt;json(['results' =&amp;gt; $results]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Step 7: Bulletproof Error Handling&lt;br&gt;
Production apps need graceful degradation:&lt;/p&gt;

&lt;p&gt;private function shouldUseMock(): bool&lt;br&gt;
{&lt;br&gt;
    return config('ai.mode') === 'mock' &lt;br&gt;
        || !class_exists('Laravel\Ai\Facades\Ai')&lt;br&gt;
        || !$this-&amp;gt;hasApiKeys();&lt;br&gt;
}&lt;br&gt;
private function hasApiKeys(): bool&lt;br&gt;
{&lt;br&gt;
    return !empty(env('GEMINI_API_KEY')) &lt;br&gt;
        || !empty(env('OPENAI_API_KEY'));&lt;br&gt;
}&lt;br&gt;
// In controllers&lt;br&gt;
try {&lt;br&gt;
    if ($this-&amp;gt;shouldUseMock()) {&lt;br&gt;
        $response = $this-&amp;gt;mockProvider-&amp;gt;text($prompt);&lt;br&gt;
    } else {&lt;br&gt;
        $response = \Laravel\Ai\Facades\Ai::text($prompt);&lt;br&gt;
    }&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return response()-&amp;gt;json([
    'success' =&amp;gt; true,
    'response' =&amp;gt; $response,
    'mode' =&amp;gt; $this-&amp;gt;shouldUseMock() ? 'mock' : 'real'
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;} catch (\Exception $e) {&lt;br&gt;
    return response()-&amp;gt;json([&lt;br&gt;
        'success' =&amp;gt; false,&lt;br&gt;
        'error' =&amp;gt; $e-&amp;gt;getMessage(),&lt;br&gt;
    ], 500);&lt;br&gt;
}&lt;br&gt;
The app never breaks. It always falls back gracefully.&lt;/p&gt;

&lt;p&gt;Step 8: Testing Everything&lt;br&gt;
// tests/Feature/AiShowcaseTest.php&lt;br&gt;
class AiShowcaseTest extends TestCase&lt;br&gt;
{&lt;br&gt;
    /** &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt; */&lt;br&gt;
    public function mock_mode_works_without_api_keys()&lt;br&gt;
    {&lt;br&gt;
        config(['ai.mode' =&amp;gt; 'mock']);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    $response = $this-&amp;gt;postJson('/chat/demo', [
        'message' =&amp;gt; 'Hello world'
    ]);

    $response-&amp;gt;assertStatus(200)
        -&amp;gt;assertJson(['success' =&amp;gt; true, 'mode' =&amp;gt; 'mock']);
}

/** @test */
public function mode_switching_works_via_session()
{
    $response = $this-&amp;gt;postJson('/ai/mode/switch', ['mode' =&amp;gt; 'real']);

    $response-&amp;gt;assertStatus(200);
    $this-&amp;gt;assertEquals('real', session('ai_mode'));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Run tests:&lt;/p&gt;

&lt;p&gt;php artisan test --filter AiShowcaseTest&lt;br&gt;
Key Lessons Learned&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mock Mode is Essential
Lets anyone try your app instantly
Zero API costs during development
Deterministic responses for testing
Perfect for demos and documentation&lt;/li&gt;
&lt;li&gt;Session-Based Switching is Powerful
Users toggle modes without server restart
Great for A/B testing
Clear visual feedback builds trust&lt;/li&gt;
&lt;li&gt;Streaming Transforms UX
Users see responses immediately
Perceived performance is dramatically better
Modern users expect real-time feedback&lt;/li&gt;
&lt;li&gt;Graceful Degradation is Non-Negotiable
Always have a fallback
Never break the user experience
Clear error messages help debugging
What We Built
✅ Complete AI Showcase with 4 core features
✅ Dual Mode System (Mock/Real) for flexibility
✅ Real-time Streaming with Server-Sent Events
✅ Session-based Switching for instant demos
✅ Comprehensive Testing with full coverage
✅ Production Ready with proper error handling&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Try It Yourself&lt;br&gt;
git clone &lt;a href="https://github.com/aliabdm/laravel-ai-showcase.git" rel="noopener noreferrer"&gt;https://github.com/aliabdm/laravel-ai-showcase.git&lt;/a&gt;&lt;br&gt;
cd laravel-ai-showcase&lt;br&gt;
composer install&lt;br&gt;
cp .env.example .env&lt;br&gt;
php artisan key:generate&lt;br&gt;
php artisan serve&lt;/p&gt;

&lt;h1&gt;
  
  
  Visit &lt;a href="http://localhost:8000" rel="noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  All features work immediately in Mock Mode!
&lt;/h1&gt;

&lt;p&gt;Live Demo: &lt;a href="https://laravel-ai-showcase.onrender.com/" rel="noopener noreferrer"&gt;https://laravel-ai-showcase.onrender.com/&lt;/a&gt;&lt;br&gt;
(Note: It’s on Render free tier, so first load may take a minute)&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
The Laravel AI SDK makes building AI-powered applications incredibly simple. What would have taken days of integration work now takes hours.&lt;/p&gt;

&lt;p&gt;By implementing Mock Mode, session-based switching, and real-time streaming, we’ve created a showcase that:&lt;/p&gt;

&lt;p&gt;Works instantly for demos&lt;br&gt;
Scales to production&lt;br&gt;
Provides excellent developer experience&lt;br&gt;
Teaches best practices&lt;br&gt;
The key lesson? Always build with both development and production in mind. Mock modes and graceful fallbacks aren’t just nice-to-have — they’re essential for professional AI applications.&lt;/p&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
I’m planning follow-up articles on:&lt;/p&gt;

&lt;p&gt;Deploying with Docker&lt;br&gt;
Performance optimization techniques&lt;br&gt;
Extending with custom AI tools&lt;br&gt;
Production security considerations&lt;br&gt;
Monitoring and logging AI usage&lt;br&gt;
Want the complete code? Check out the repository and star it if you find it useful!&lt;/p&gt;

&lt;p&gt;Questions? Drop them in the comments — I’d love to help you build your own AI showcase!&lt;/p&gt;

&lt;p&gt;Built with ❤️ using Laravel AI SDK&lt;br&gt;
GitHub: &lt;br&gt;
Mohammad Ali Abdul Wahed&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>ai</category>
      <category>agentaichallenge</category>
    </item>
    <item>
      <title>Firebase vs Supabase: Why I Switched for PostgreSQL and Cheaper Real-time</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Fri, 16 Jan 2026 14:19:58 +0000</pubDate>
      <link>https://dev.to/maliano63717738/firebase-vs-supabase-why-i-switched-for-postgresql-and-cheaper-real-time-2h4e</link>
      <guid>https://dev.to/maliano63717738/firebase-vs-supabase-why-i-switched-for-postgresql-and-cheaper-real-time-2h4e</guid>
      <description>&lt;p&gt;If you’re a developer, you’ve definitely heard of Firebase—Google’s powerhouse Backend-as-a-Service (BaaS). It has been the industry standard for years. However, as projects scale, many developers (myself included) start looking for something more flexible and, frankly, more affordable.&lt;/p&gt;

&lt;p&gt;Recently, I hit a wall with a project. I had two non-negotiable requirements: I needed a robust PostgreSQL database without the "cloud tax," and I needed a real-time solution that wouldn't bankrupt me as my user base grew. This led me straight to Supabase.&lt;/p&gt;

&lt;p&gt;Here is my honest comparison and the reasons why I believe Supabase is winning the battle for modern developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Database: NoSQL vs. The Power of SQL
&lt;/h2&gt;

&lt;p&gt;The biggest shift when moving from Firebase to Supabase is the underlying architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firebase (Firestore):&lt;/strong&gt;&lt;br&gt;
 It’s a NoSQL document store. While it's great for simple data, it becomes a nightmare when you need complex relations. You often end up "denormalizing" data or doing multiple nested queries that increase your costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supabase (PostgreSQL):&lt;/strong&gt; &lt;br&gt;
This was the primary reason I made the switch. Supabase gives you a full PostgreSQL instance. For my project, getting a high-performance relational database for free (on the basic tier) was a game-changer. I could use joins, views, and complex filters that are simply impossible or too expensive in Firestore.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Real-Time: Better, Faster, and Significantly Cheaper
&lt;/h2&gt;

&lt;p&gt;There is a common misconception that Firebase is the only king of Real-time. In my experience, Supabase Real-time is not only a viable alternative but often a better one.&lt;/p&gt;

&lt;p&gt;Why Supabase Real-time impressed me:&lt;br&gt;
The Cost Factor: In Firebase, every real-time listener and every data sync counts as a "document read." If you have 1,000 users watching a list, your bill explodes. In Supabase, you aren't charged per "read" operation. You pay for bandwidth, which is significantly cheaper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postgres Changes:&lt;/strong&gt; Supabase listens to the PostgreSQL Write-Ahead Log (WAL). This means you can subscribe to specific events (INSERT, UPDATE, DELETE) directly on your database tables.&lt;/p&gt;

&lt;p&gt;**Broadcast &amp;amp; Presence: **This is where I saved the most. Supabase allows you to send messages between clients (Broadcast) and track who is online (Presence) without writing any data to the database. It’s low-latency and incredibly cost-effective.&lt;/p&gt;

&lt;p&gt;JavaScript&lt;/p&gt;

&lt;p&gt;// Supabase Real-time is clean and efficient&lt;br&gt;
&lt;code&gt;const channel = supabase&lt;br&gt;
  .channel('room-1')&lt;br&gt;
  .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, &lt;br&gt;
    payload =&amp;gt; {&lt;br&gt;
      console.log('New message received!', payload.new.text)&lt;br&gt;
  })&lt;br&gt;
  .subscribe()&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Pricing: Escaping the "Success Tax"
&lt;/h2&gt;

&lt;p&gt;We’ve all heard the horror stories of Firebase "Bill Shocks." Firebase’s pay-per-read model means that if your app goes viral, you might wake up to a $5,000 bill.&lt;/p&gt;

&lt;p&gt;The Comparison:&lt;br&gt;
Firebase: You pay for every single operation. Read a document? Pay. Write a document? Pay. It’s hard to predict your monthly costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supabase:&lt;/strong&gt; They offer a generous Free Tier (which includes that free Postgres DB I needed). Their Pro Plan is a flat &lt;strong&gt;$25/month&lt;/strong&gt;, which covers most of what an MVP needs with very predictable overage costs.&lt;/p&gt;

&lt;p&gt;My real-world experience: For a medium-sized app with high traffic, I found that Supabase can be &lt;strong&gt;75% to 80% cheaper than Firebase&lt;/strong&gt;, mainly because I wasn't being penalized for every database fetch.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. No Vendor Lock-in
&lt;/h2&gt;

&lt;p&gt;One of the most liberating things about Supabase is that it’s Open Source.&lt;/p&gt;

&lt;p&gt;Firebase is a closed Google product. If they raise prices or shut down a service (like they have in the past), you are stuck.&lt;/p&gt;

&lt;p&gt;Supabase is built on open tools. If you ever decide to leave their cloud platform, you can take your PostgreSQL database and self-host it anywhere. That peace of mind is priceless.&lt;/p&gt;

&lt;p&gt;Final Verdict: Which should you choose?&lt;br&gt;
Stick with Firebase if:&lt;/p&gt;

&lt;p&gt;You are building a mobile-first app that requires extremely complex offline-syncing out of the box.&lt;/p&gt;

&lt;p&gt;You are deeply integrated into the Google Cloud ecosystem.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Switch to Supabase if:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
You want PostgreSQL: You need the reliability and power of a relational database.&lt;/p&gt;

&lt;p&gt;You need "Cheap" Real-time: You want to scale your real-time features without worrying about "per-operation" costs.&lt;/p&gt;

&lt;p&gt;You want predictable billing: You prefer a flat monthly fee over a "guessing game" bill.&lt;/p&gt;

&lt;p&gt;My Experience?&lt;br&gt;
I came for the free PostgreSQL, but I stayed for the Real-time performance and the fair pricing. Supabase has proven that you don't have to sacrifice power for price.&lt;/p&gt;

&lt;p&gt;Have you tried Supabase yet, or are you still loyal to Firebase? Let’s discuss in the comments!&lt;/p&gt;

</description>
      <category>supabase</category>
      <category>firebase</category>
      <category>realtime</category>
      <category>postgressql</category>
    </item>
    <item>
      <title>AI Orchestration: The Microservices Approach to Large Language Models</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Sat, 03 Jan 2026 13:01:28 +0000</pubDate>
      <link>https://dev.to/maliano63717738/ai-orchestration-the-microservices-approach-to-large-language-models-4bj6</link>
      <guid>https://dev.to/maliano63717738/ai-orchestration-the-microservices-approach-to-large-language-models-4bj6</guid>
      <description>&lt;p&gt;Stop Asking “Which AI is Best?” Start Asking “How Do I Orchestrate Them?”&lt;br&gt;
As engineers building AI systems in 2025, we’re witnessing a fundamental shift in how we approach artificial intelligence integration. The question is no longer “Should I use GPT, Claude, or Gemini?” but rather “How do I orchestrate multiple specialized models to build robust AI systems?”&lt;/p&gt;

&lt;p&gt;This article explores why AI orchestration is the future of intelligent systems and how to implement it effectively.&lt;/p&gt;

&lt;p&gt;The Monolithic AI Fallacy&lt;br&gt;
Remember when we built monolithic applications? Everything in one massive codebase, tightly coupled, hard to scale, and impossible to maintain. Then microservices revolutionized software architecture by breaking systems into specialized, independent services.&lt;/p&gt;

&lt;p&gt;We’re at that exact inflection point with AI systems.&lt;/p&gt;

&lt;p&gt;The industry has been caught in a trap: comparing models head-to-head as if one must reign supreme. “GPT-5 beats Claude!” or “Claude is better at coding!” These comparisons miss the point entirely.&lt;/p&gt;

&lt;p&gt;The Reality Check&lt;br&gt;
No single model excels at everything. Each Large Language Model (LLM) has been optimized for different tasks, trained on different data, and architected with different trade-offs. Trying to find one “best” model is like trying to find the one “best” database — it doesn’t exist because the answer depends on your use case.&lt;/p&gt;

&lt;p&gt;The 2025 AI Landscape: Specialized Models for Specialized Tasks&lt;br&gt;
Let’s break down the current state of leading AI models and their sweet spots:&lt;/p&gt;

&lt;p&gt;Claude (Sonnet 4.5 / Opus 4)&lt;br&gt;
Strengths:&lt;/p&gt;

&lt;p&gt;Complex code generation: Claude excels at understanding intricate codebases and generating sophisticated solutions&lt;br&gt;
Long-context processing: With context windows up to 200K tokens, it handles extensive documents and conversations&lt;br&gt;
Technical depth: Superior performance on tasks requiring deep technical understanding&lt;br&gt;
Best for:&lt;/p&gt;

&lt;p&gt;Software development and code review&lt;br&gt;
Technical documentation analysis&lt;br&gt;
Long-form content creation&lt;br&gt;
Complex reasoning chains&lt;br&gt;
GPT-5 (OpenAI)&lt;br&gt;
Strengths:&lt;/p&gt;

&lt;p&gt;Advanced reasoning: Exceptional at multi-step logical reasoning and problem decomposition&lt;br&gt;
Mathematical prowess: Superior performance on mathematical and scientific tasks&lt;br&gt;
Analytical depth: Strong at breaking down complex problems into structured solutions&lt;br&gt;
Best for:&lt;/p&gt;

&lt;p&gt;Scientific research and analysis&lt;br&gt;
Mathematical problem-solving&lt;br&gt;
Strategic planning and decision-making&lt;br&gt;
Educational tutoring&lt;br&gt;
Gemini 3 Flash (Google)&lt;br&gt;
Strengths:&lt;/p&gt;

&lt;p&gt;Speed: Fastest inference times among major models&lt;br&gt;
Cost-effectiveness: Significantly lower costs per token&lt;br&gt;
Real-time capabilities: Optimized for streaming and interactive applications&lt;br&gt;
Best for:&lt;/p&gt;

&lt;p&gt;Customer service chatbots&lt;br&gt;
Real-time translation&lt;br&gt;
High-volume, low-complexity tasks&lt;br&gt;
Mobile and edge applications&lt;br&gt;
Open Source (LLaMA 3, DeepSeek, Mixtral)&lt;br&gt;
Strengths:&lt;/p&gt;

&lt;p&gt;Privacy: Complete data control with local deployment&lt;br&gt;
Customization: Fine-tune for specific domains and use cases&lt;br&gt;
Cost control: No per-token fees for self-hosted deployments&lt;br&gt;
Compliance: Meet strict regulatory requirements&lt;br&gt;
Best for:&lt;/p&gt;

&lt;p&gt;Healthcare and financial services&lt;br&gt;
Government and defense applications&lt;br&gt;
Proprietary research&lt;br&gt;
Specialized domain adaptation&lt;br&gt;
Introducing AI Orchestration&lt;br&gt;
AI Orchestration is the practice of intelligently routing tasks to the most appropriate model based on the requirements of each specific task. Think of it as a conductor leading an orchestra — each instrument (model) plays its part when needed to create a harmonious result.&lt;/p&gt;

&lt;p&gt;The Architecture&lt;br&gt;
User Request&lt;br&gt;
     ↓&lt;br&gt;
[Request Analyzer]&lt;br&gt;
     ↓&lt;br&gt;
[Routing Logic]&lt;br&gt;
     ↓&lt;br&gt;
┌────────┬────────┬────────┬────────┐&lt;br&gt;
│ Claude │  GPT   │ Gemini │  Local │&lt;br&gt;
│        │        │        │  Model │&lt;br&gt;
└────────┴────────┴────────┴────────┘&lt;br&gt;
     ↓&lt;br&gt;
[Response Aggregator]&lt;br&gt;
     ↓&lt;br&gt;
Final Response&lt;/p&gt;

&lt;p&gt;Key Components&lt;br&gt;
Request Classification: Analyze incoming requests to determine:&lt;/p&gt;

&lt;p&gt;Complexity level&lt;br&gt;
Domain (code, math, general, etc.)&lt;br&gt;
Latency requirements&lt;br&gt;
Privacy sensitivity&lt;br&gt;
Cost constraints&lt;br&gt;
Intelligent Routing: Direct each request to the optimal model based on:&lt;/p&gt;

&lt;p&gt;Model capabilities and benchmarks&lt;br&gt;
Current load and availability&lt;br&gt;
Cost optimization rules&lt;br&gt;
Privacy and compliance requirements&lt;br&gt;
Response Handling: Process model outputs through:&lt;/p&gt;

&lt;p&gt;Validation and quality checks&lt;br&gt;
Format standardization&lt;br&gt;
Error handling and fallbacks&lt;br&gt;
Caching for efficiency&lt;br&gt;
Feedback Loop: Continuously improve routing decisions based on:&lt;/p&gt;

&lt;p&gt;Response quality metrics&lt;br&gt;
User satisfaction scores&lt;br&gt;
Performance analytics&lt;br&gt;
Cost tracking&lt;br&gt;
Implementation Patterns&lt;br&gt;
Pattern 1: Task-Based Routing&lt;br&gt;
Route based on the nature of the task:&lt;/p&gt;

&lt;p&gt;def route_request(task):&lt;br&gt;
    if task.type == "code_generation":&lt;br&gt;
        return claude_api&lt;br&gt;
    elif task.type == "math_problem":&lt;br&gt;
        return gpt_api&lt;br&gt;
    elif task.type == "quick_query":&lt;br&gt;
        return gemini_api&lt;br&gt;
    elif task.is_sensitive_data:&lt;br&gt;
        return local_model&lt;br&gt;
Pattern 2: Cascading Intelligence&lt;br&gt;
Start with faster/cheaper models, escalate to more powerful ones:&lt;/p&gt;

&lt;p&gt;def cascading_request(query):&lt;br&gt;
    response = gemini_api.query(query)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if response.confidence &amp;lt; 0.7:
    response = gpt_api.query(query)

if response.confidence &amp;lt; 0.9:
    response = claude_api.query(query)

return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Pattern 3: Parallel Processing with Consensus&lt;br&gt;
Query multiple models and aggregate results:&lt;/p&gt;

&lt;p&gt;async def consensus_query(question):&lt;br&gt;
    responses = await asyncio.gather(&lt;br&gt;
        claude_api.query(question),&lt;br&gt;
        gpt_api.query(question),&lt;br&gt;
        gemini_api.query(question)&lt;br&gt;
    )&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return aggregate_responses(responses)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Pattern 4: Specialized Pipelines&lt;br&gt;
Chain models for complex workflows:&lt;/p&gt;

&lt;p&gt;def content_pipeline(raw_data):&lt;br&gt;
    # Fast extraction&lt;br&gt;
    structured_data = gemini_api.extract(raw_data)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Deep analysis
insights = gpt_api.analyze(structured_data)

# Technical implementation
code = claude_api.generate_code(insights)

return code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Real-World Use Cases&lt;br&gt;
Case Study 1: Customer Support Platform&lt;br&gt;
Challenge: Handle 10,000+ daily support tickets with varying complexity&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;Gemini Flash: Handle 80% of simple queries (password resets, status checks)&lt;br&gt;
GPT-5: Process 15% of medium complexity issues (troubleshooting, explanations)&lt;br&gt;
Claude Opus: Resolve 5% of complex technical problems (bug analysis, system integration)&lt;br&gt;
Results:&lt;/p&gt;

&lt;p&gt;70% cost reduction compared to single-model approach&lt;br&gt;
40% faster average response time&lt;br&gt;
25% improvement in customer satisfaction&lt;br&gt;
Case Study 2: Healthcare AI Assistant&lt;br&gt;
Challenge: Provide medical information while maintaining HIPAA compliance&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;Local LLaMA model: Process all patient data on-premises&lt;br&gt;
Claude: Generate detailed medical documentation&lt;br&gt;
GPT-5: Analyze research papers and clinical guidelines&lt;br&gt;
Gemini: Handle appointment scheduling and basic queries&lt;br&gt;
Results:&lt;/p&gt;

&lt;p&gt;Full HIPAA compliance with local data processing&lt;br&gt;
Comprehensive medical knowledge through specialized routing&lt;br&gt;
Scalable system handling 100K+ monthly interactions&lt;br&gt;
Case Study 3: Development Environment&lt;br&gt;
Challenge: Create an AI coding assistant that handles diverse tasks&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;Claude: Primary code generation and review&lt;br&gt;
GPT-5: Explain complex algorithms and architectural decisions&lt;br&gt;
DeepSeek: Fast code completion and suggestions&lt;br&gt;
Gemini: Quick documentation lookups&lt;br&gt;
Results:&lt;/p&gt;

&lt;p&gt;60% increase in developer productivity&lt;br&gt;
Better code quality through specialized review&lt;br&gt;
Reduced API costs by 50%&lt;br&gt;
Benchmarking and Evaluation&lt;br&gt;
To build effective AI orchestration, you need reliable benchmarks. Here are the essential resources:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;LMSYS Chatbot Arena
URL: &lt;a href="https://lmarena.ai" rel="noopener noreferrer"&gt;https://lmarena.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most comprehensive community-driven benchmark, featuring:&lt;/p&gt;

&lt;p&gt;Head-to-head model comparisons&lt;br&gt;
Real user evaluations&lt;br&gt;
Category-specific rankings (coding, math, creative writing)&lt;br&gt;
Regular updates with new models&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Artificial Analysis
URL: &lt;a href="https://artificialanalysis.ai" rel="noopener noreferrer"&gt;https://artificialanalysis.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Focuses on practical metrics:&lt;/p&gt;

&lt;p&gt;Response speed comparisons&lt;br&gt;
Cost per token analysis&lt;br&gt;
Context window capabilities&lt;br&gt;
Quality-price ratio evaluations&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open LLM Leaderboard
URL: &lt;a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard" rel="noopener noreferrer"&gt;https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Become a member&lt;br&gt;
Essential for open-source models:&lt;/p&gt;

&lt;p&gt;Standardized evaluation metrics&lt;br&gt;
Academic benchmarks (MMLU, HellaSwag, TruthfulQA)&lt;br&gt;
Model size and efficiency data&lt;br&gt;
Fine-tuning information&lt;br&gt;
Key Metrics to Track&lt;br&gt;
When orchestrating models, monitor these metrics:&lt;/p&gt;

&lt;p&gt;Task Success Rate: Percentage of successfully completed tasks per model&lt;br&gt;
Latency: Response time from request to completion&lt;br&gt;
Cost Per Task: Total API costs divided by number of requests&lt;br&gt;
Quality Score: User satisfaction or automated quality metrics&lt;br&gt;
Error Rate: Failed requests or low-confidence responses&lt;br&gt;
Token Efficiency: Average tokens used per successful task&lt;br&gt;
Building Your Orchestration Layer&lt;br&gt;
Step 1: Define Your Use Cases&lt;br&gt;
Map out all AI tasks in your application:&lt;/p&gt;

&lt;p&gt;What types of requests do you handle?&lt;br&gt;
What are the complexity levels?&lt;br&gt;
What are your latency requirements?&lt;br&gt;
What are your cost constraints?&lt;br&gt;
What are your privacy requirements?&lt;br&gt;
Step 2: Establish Baseline Benchmarks&lt;br&gt;
Test each potential model on your actual workload:&lt;/p&gt;

&lt;p&gt;Create a representative test set (100+ examples)&lt;br&gt;
Measure quality, speed, and cost for each model&lt;br&gt;
Identify each model’s strengths and weaknesses&lt;br&gt;
Document decision rules&lt;br&gt;
Step 3: Implement Smart Routing&lt;br&gt;
Start simple, iterate complex:&lt;/p&gt;

&lt;p&gt;class AIOrchestrator:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self):&lt;br&gt;
        self.models = {&lt;br&gt;
            'claude': ClaudeAPI(),&lt;br&gt;
            'gpt': OpenAIAPI(),&lt;br&gt;
            'gemini': GeminiAPI(),&lt;br&gt;
            'local': LocalModel()&lt;br&gt;
        }&lt;br&gt;
        self.router = RequestRouter()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def process(self, request):
    # Classify request
    classification = self.router.classify(request)

    # Select optimal model
    model_name = self.router.select_model(classification)
    model = self.models[model_name]

    # Execute with fallback
    try:
        response = model.generate(request)
        self.log_metrics(model_name, request, response)
        return response
    except Exception as e:
        return self.fallback_chain(request, [model_name])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Step 4: Monitor and Optimize&lt;br&gt;
Implement comprehensive observability:&lt;/p&gt;

&lt;p&gt;Log every request and response&lt;br&gt;
Track costs in real-time&lt;br&gt;
Monitor quality metrics&lt;br&gt;
A/B test routing rules&lt;br&gt;
Continuously refine your decision logic&lt;br&gt;
Common Pitfalls and How to Avoid Them&lt;br&gt;
Pitfall 1: Over-Engineering&lt;br&gt;
Problem: Building overly complex routing logic from day one&lt;/p&gt;

&lt;p&gt;Solution: Start with simple rules based on task type, add complexity only when data shows it’s needed&lt;/p&gt;

&lt;p&gt;Pitfall 2: Ignoring Costs&lt;br&gt;
Problem: Not tracking per-request costs until the bill arrives&lt;/p&gt;

&lt;p&gt;Solution: Implement cost tracking from day one, set budgets per model, use caching aggressively&lt;/p&gt;

&lt;p&gt;Pitfall 3: No Fallback Strategy&lt;br&gt;
Problem: Single point of failure when primary model is down or rate-limited&lt;/p&gt;

&lt;p&gt;Solution: Always have 2–3 fallback models configured with automatic failover&lt;/p&gt;

&lt;p&gt;Pitfall 4: Static Routing Rules&lt;br&gt;
Problem: Set routing rules once and never update them&lt;/p&gt;

&lt;p&gt;Solution: Regularly review performance data, update rules based on new benchmarks, adapt to model improvements&lt;/p&gt;

&lt;p&gt;Pitfall 5: Neglecting Privacy&lt;br&gt;
Problem: Sending sensitive data to external APIs without proper safeguards&lt;/p&gt;

&lt;p&gt;Solution: Classify data sensitivity, use local models for sensitive data, implement proper data anonymization&lt;/p&gt;

&lt;p&gt;The Economics of AI Orchestration&lt;br&gt;
Cost Optimization Strategies&lt;br&gt;
Tiered Routing: Use cheaper models for simpler tasks&lt;/p&gt;

&lt;p&gt;Gemini Flash: $0.10 per 1M tokens&lt;br&gt;
Claude Sonnet: $3.00 per 1M tokens&lt;br&gt;
Claude Opus: $15.00 per 1M tokens&lt;br&gt;
Caching: Store and reuse responses for common queries&lt;/p&gt;

&lt;p&gt;Reduce API calls by 40–60%&lt;br&gt;
Sub-millisecond response times&lt;br&gt;
Minimal infrastructure costs&lt;br&gt;
Batch Processing: Group similar requests for efficiency&lt;/p&gt;

&lt;p&gt;10–30% cost reduction through batching&lt;br&gt;
Better resource utilization&lt;br&gt;
Improved throughput&lt;br&gt;
Hybrid Deployment: Mix cloud and local models&lt;/p&gt;

&lt;p&gt;Zero marginal cost for local inference&lt;br&gt;
Control over data and privacy&lt;br&gt;
Backup during API outages&lt;br&gt;
ROI Analysis&lt;br&gt;
For a typical application processing 1M requests/month:&lt;/p&gt;

&lt;p&gt;Single Model Approach (Claude Opus only):&lt;/p&gt;

&lt;p&gt;Cost: ~$15,000/month&lt;br&gt;
Average latency: 3 seconds&lt;br&gt;
Quality: 95%&lt;br&gt;
Orchestrated Approach:&lt;/p&gt;

&lt;p&gt;Cost: ~$6,000/month (60% reduction)&lt;br&gt;
Average latency: 1.5 seconds (50% faster)&lt;br&gt;
Quality: 96% (through specialized routing)&lt;br&gt;
Break-even: Immediate positive ROI&lt;/p&gt;

&lt;p&gt;Future Trends in AI Orchestration&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automated Model Selection
ML models that learn optimal routing decisions:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reinforcement learning for routing optimization&lt;br&gt;
Automatic A/B testing of model combinations&lt;br&gt;
Adaptive cost-quality trade-offs&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Specialized Model Ecosystems
More domain-specific models emerging:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Legal-specific models&lt;br&gt;
Medical-specific models&lt;br&gt;
Financial analysis models&lt;br&gt;
Code-only models&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Edge AI Orchestration
Extending orchestration to edge devices:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On-device models for privacy&lt;br&gt;
Cloud models for complex tasks&lt;br&gt;
Intelligent data sync&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multimodal Orchestration
Routing across different modalities:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Text models for language tasks&lt;br&gt;
Vision models for image analysis&lt;br&gt;
Audio models for speech processing&lt;br&gt;
Code models for development&lt;br&gt;
Getting Started Today&lt;br&gt;
Immediate Actions&lt;br&gt;
Audit Your Current AI Usage&lt;/p&gt;

&lt;p&gt;What models are you using?&lt;br&gt;
What are your costs?&lt;br&gt;
What are your pain points?&lt;br&gt;
Benchmark Alternatives&lt;/p&gt;

&lt;p&gt;Test 2–3 models on your actual workload&lt;br&gt;
Compare quality, speed, and cost&lt;br&gt;
Identify clear winners for specific tasks&lt;br&gt;
Implement Simple Routing&lt;/p&gt;

&lt;p&gt;Start with if-else rules&lt;br&gt;
Add logging and metrics&lt;br&gt;
Iterate based on data&lt;br&gt;
Set Up Monitoring&lt;/p&gt;

&lt;p&gt;Track costs per model&lt;br&gt;
Measure response quality&lt;br&gt;
Monitor latency&lt;br&gt;
Resources for Learning More&lt;br&gt;
Technical Documentation:&lt;/p&gt;

&lt;p&gt;Claude API: &lt;a href="https://docs.claude.com" rel="noopener noreferrer"&gt;https://docs.claude.com&lt;/a&gt;&lt;br&gt;
OpenAI API: &lt;a href="https://platform.openai.com/docs" rel="noopener noreferrer"&gt;https://platform.openai.com/docs&lt;/a&gt;&lt;br&gt;
Google AI: &lt;a href="https://ai.google.dev/docs" rel="noopener noreferrer"&gt;https://ai.google.dev/docs&lt;/a&gt;&lt;br&gt;
Community Resources:&lt;/p&gt;

&lt;p&gt;r/LocalLLaMA for open-source models&lt;br&gt;
HuggingFace forums for model discussions&lt;br&gt;
AI engineering blogs and newsletters&lt;br&gt;
Tools and Frameworks:&lt;/p&gt;

&lt;p&gt;LangChain for orchestration&lt;br&gt;
LiteLLM for unified APIs&lt;br&gt;
Helicone for observability&lt;br&gt;
Conclusion: The Orchestrated Future&lt;br&gt;
The question “Which AI is best?” is becoming as outdated as “Which database is best?” The answer is always: it depends on your use case.&lt;/p&gt;

&lt;p&gt;The future of AI systems is orchestration. Just as modern software architecture embraces microservices, API gateways, and polyglot persistence, modern AI systems must embrace model diversity, intelligent routing, and specialized capabilities.&lt;/p&gt;

&lt;p&gt;The engineers who will build the most successful AI products aren’t the ones who pick the “best” model — they’re the ones who know how to orchestrate multiple models into cohesive, efficient, and powerful systems.&lt;/p&gt;

&lt;p&gt;Start thinking like an orchestra conductor, not a solo performer.&lt;/p&gt;

&lt;p&gt;The baton is in your hands. What will you create?&lt;/p&gt;

&lt;p&gt;About Benchmarking Resources&lt;br&gt;
Throughout this article, I’ve referenced three critical benchmarking platforms that should be part of every AI engineer’s toolkit:&lt;/p&gt;

&lt;p&gt;LMSYS Chatbot Arena (lmarena.ai): Community-driven, real-world evaluations&lt;br&gt;
Artificial Analysis (artificialanalysis.ai): Cost and performance metrics&lt;br&gt;
Open LLM Leaderboard (huggingface.co): Academic benchmarks and open-source focus&lt;br&gt;
These platforms are continuously updated as new models are released. Make checking them a regular part of your development workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9s4t2xk6pq4famreek7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9s4t2xk6pq4famreek7.jpg" alt=" " width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BTLM&lt;br&gt;
Have you implemented AI orchestration in your systems? Share your experiences in the comments below!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>microservices</category>
      <category>architecture</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>I Built a PDF Chat App in Under an Hour Using RAG- Here's How You Can Too</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Mon, 29 Dec 2025 09:36:33 +0000</pubDate>
      <link>https://dev.to/maliano63717738/i-built-a-pdf-chat-app-in-under-an-hour-using-rag-heres-how-you-can-too-heh</link>
      <guid>https://dev.to/maliano63717738/i-built-a-pdf-chat-app-in-under-an-hour-using-rag-heres-how-you-can-too-heh</guid>
      <description>&lt;p&gt;🔗 Live Demo:&lt;br&gt;
&lt;a href="https://pdf-chat-rag-fx5nczbrwczzpou6qyczmj.streamlit.app/" rel="noopener noreferrer"&gt;https://pdf-chat-rag-fx5nczbrwczzpou6qyczmj.streamlit.app/&lt;/a&gt;&lt;br&gt;
📦 GitHub Repo:&lt;br&gt;
&lt;a href="https://github.com/aliabdm/pdf-chat-rag" rel="noopener noreferrer"&gt;https://github.com/aliabdm/pdf-chat-rag&lt;/a&gt;&lt;br&gt;
🤔 The Idea&lt;br&gt;
Ever wished you could talk to your documents instead of endlessly scrolling through pages?&lt;br&gt;
That’s exactly what I built using Retrieval-Augmented Generation (RAG) and modern GenAI tools.&lt;br&gt;
Upload a PDF → ask questions → get accurate, context-aware answers in seconds.&lt;br&gt;
❌ The Problem&lt;br&gt;
We’ve all been there:&lt;/p&gt;

&lt;p&gt;50-page research papers&lt;br&gt;
Long contracts&lt;br&gt;
Dense technical docs&lt;br&gt;
CVs in recruitment workflows&lt;/p&gt;

&lt;p&gt;Ctrl + F isn’t enough when you need:&lt;/p&gt;

&lt;p&gt;Summaries&lt;br&gt;
Cross-section answers&lt;br&gt;
Simple explanations&lt;br&gt;
Context-aware responses&lt;/p&gt;

&lt;p&gt;✅ The Solution: PDF Chat with RAG&lt;br&gt;
I built a web app that lets you:&lt;/p&gt;

&lt;p&gt;Upload any PDF&lt;br&gt;
Ask questions in natural language&lt;br&gt;
Get answers grounded only in your document&lt;/p&gt;

&lt;p&gt;👉 Try it live:&lt;br&gt;
&lt;a href="https://pdf-chat-rag-fx5nczbrwczzpou6qyczmj.streamlit.app/" rel="noopener noreferrer"&gt;https://pdf-chat-rag-fx5nczbrwczzpou6qyczmj.streamlit.app/&lt;/a&gt;&lt;br&gt;
🧱 Tech Stack (Why Each Tool Matters)&lt;br&gt;
🧩 LangChain — The RAG Backbone&lt;br&gt;
LangChain makes RAG production-ready by handling:&lt;/p&gt;

&lt;p&gt;Document chunking&lt;br&gt;
Embeddings&lt;br&gt;
Retrieval + generation orchestration&lt;/p&gt;

&lt;p&gt;Pythonfrom langchain_text_splitters import RecursiveCharacterTextSplitter&lt;/p&gt;

&lt;p&gt;text_splitter = RecursiveCharacterTextSplitter(&lt;br&gt;
    chunk_size=1000,&lt;br&gt;
    chunk_overlap=200&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;chunks = text_splitter.split_text(text)&lt;br&gt;
⚡ Groq — Lightning-Fast LLM Inference&lt;br&gt;
Groq uses custom LPU hardware and delivers:&lt;/p&gt;

&lt;p&gt;~2s response time&lt;br&gt;
Models like Llama 3.3 70B&lt;br&gt;
Generous free tier&lt;/p&gt;

&lt;p&gt;Pythonfrom langchain_groq import ChatGroq&lt;/p&gt;

&lt;p&gt;llm = ChatGroq(&lt;br&gt;
    model_name="llama-3.3-70b-versatile",&lt;br&gt;
    temperature=0,&lt;br&gt;
    groq_api_key=api_key&lt;br&gt;
)&lt;br&gt;
🔍 FAISS — Vector Similarity Search&lt;br&gt;
When your PDF becomes 100+ chunks, FAISS finds the most relevant ones fast.&lt;br&gt;
Pythonfrom langchain_community.vectorstores import FAISS&lt;/p&gt;

&lt;p&gt;vector_store = FAISS.from_texts(chunks, embeddings)&lt;br&gt;
🎨 Streamlit — UI in Minutes&lt;br&gt;
Why Streamlit?&lt;/p&gt;

&lt;p&gt;No frontend boilerplate&lt;br&gt;
Built-in chat + file upload&lt;br&gt;
Free deployment&lt;/p&gt;

&lt;p&gt;Pythonimport streamlit as st&lt;/p&gt;

&lt;p&gt;uploaded_file = st.file_uploader("Upload PDF", type=["pdf"])&lt;/p&gt;

&lt;p&gt;if question := st.chat_input("Ask a question"):&lt;br&gt;
    pass&lt;br&gt;
🧠 HuggingFace Embeddings&lt;br&gt;
We use all-MiniLM-L6-v2:&lt;/p&gt;

&lt;p&gt;Fast&lt;br&gt;
High quality&lt;br&gt;
Runs locally&lt;br&gt;
No API cost&lt;/p&gt;

&lt;p&gt;Pythonfrom langchain_community.embeddings import HuggingFaceEmbeddings&lt;/p&gt;

&lt;p&gt;embeddings = HuggingFaceEmbeddings(&lt;br&gt;
    model_name="sentence-transformers/all-MiniLM-L6-v2"&lt;br&gt;
)&lt;br&gt;
🔄 How RAG Works (Simple Breakdown)&lt;br&gt;
Phase 1 — Document Processing&lt;/p&gt;

&lt;p&gt;Upload PDF&lt;br&gt;
Extract text&lt;br&gt;
Split into chunks&lt;br&gt;
Generate embeddings&lt;br&gt;
Store in FAISS&lt;/p&gt;

&lt;p&gt;Phase 2 — Question Answering&lt;/p&gt;

&lt;p&gt;Embed the question&lt;br&gt;
Retrieve top 3 relevant chunks&lt;br&gt;
Build context&lt;br&gt;
Send to LLM&lt;br&gt;
Return grounded answer&lt;/p&gt;

&lt;p&gt;Pythondocs = vector_store.similarity_search(question, k=3)&lt;/p&gt;

&lt;p&gt;context = "\n\n".join([doc.page_content for doc in docs])&lt;/p&gt;

&lt;p&gt;prompt = f"""&lt;br&gt;
Context:&lt;br&gt;
{context}&lt;/p&gt;

&lt;p&gt;Question:&lt;br&gt;
{question}&lt;/p&gt;

&lt;p&gt;Answer ONLY based on the context above.&lt;br&gt;
"""&lt;/p&gt;

&lt;p&gt;answer = llm.invoke(prompt)&lt;br&gt;
🧪 Core RAG Logic (That’s It)&lt;br&gt;
Pythondef answer_question(question, vector_store, llm):&lt;br&gt;
    docs = vector_store.similarity_search(question, k=3)&lt;br&gt;
    context = "\n\n".join([doc.page_content for doc in docs])&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prompt = ChatPromptTemplate.from_template("""
Context: {context}
Question: {question}

Provide a detailed answer based on the context.
""")

chain = prompt | llm | StrOutputParser()
return chain.invoke({"context": context, "question": question})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;🧠 Key Design Decisions&lt;/p&gt;

&lt;p&gt;Chunk overlap: avoids cutting context&lt;br&gt;
Temperature = 0: deterministic answers&lt;br&gt;
k = 3 chunks: best speed/accuracy balance&lt;/p&gt;

&lt;p&gt;⚠️ Challenges &amp;amp; Fixes&lt;br&gt;
PDF Text Extraction&lt;br&gt;
Some PDFs return broken text.&lt;br&gt;
✔️ Added validation + clear error messages.&lt;br&gt;
Context Window Limits&lt;br&gt;
Large docs exceeded limits.&lt;br&gt;
✔️ Limited chunk size + retrieval count.&lt;br&gt;
Answer Quality&lt;br&gt;
Early answers were vague.&lt;br&gt;
✔️ Strong prompt constraints.&lt;/p&gt;

&lt;p&gt;📊 Performance&lt;br&gt;
Metric,Value&lt;br&gt;
PDF size,50 pages&lt;br&gt;
Processing time,~15s&lt;br&gt;
Response time,~2s&lt;br&gt;
Chunks,87&lt;br&gt;
Accuracy,⭐ 8.5 / 10&lt;/p&gt;

&lt;p&gt;🚀 What’s Next?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-PDF support&lt;/li&gt;
&lt;li&gt;Conversation memory&lt;/li&gt;
&lt;li&gt;Export chat history&lt;/li&gt;
&lt;li&gt;Word / TXT support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧑‍💻 Run It Locally&lt;br&gt;
&lt;code&gt;Bashgit clone https://github.com/aliabdm/pdf-chat-rag&lt;br&gt;
pip install -r requirements.txt&lt;br&gt;
streamlit run app.py&lt;/code&gt;&lt;br&gt;
Deploy on Streamlit Cloud in one click 🚀&lt;br&gt;
🧠 Lessons Learned&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAG is simpler than it looks&lt;/li&gt;
&lt;li&gt;Speed &amp;gt; model size&lt;/li&gt;
&lt;li&gt;Prompt engineering matters&lt;/li&gt;
&lt;li&gt;Start simple, iterate fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔚 Final Thoughts&lt;br&gt;
Modern AI is about orchestration, not reinventing tools.&lt;br&gt;
If this helped you, consider giving the repo a ⭐&lt;br&gt;
🔗 Connect With Me&lt;/p&gt;

&lt;p&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/aliabdm" rel="noopener noreferrer"&gt;https://github.com/aliabdm&lt;/a&gt;&lt;br&gt;
Dev.to: &lt;a href="https://dev.to/maliano63717738"&gt;https://dev.to/maliano63717738&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding 🚀&lt;/p&gt;

</description>
      <category>rag</category>
      <category>langchain</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built a Free URL Shortener in 4 Hours Using Ruby on Rails - Here's Why Rails Still Rocks in 2025</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Sun, 28 Dec 2025 19:12:12 +0000</pubDate>
      <link>https://dev.to/maliano63717738/i-built-a-free-url-shortener-in-4-hours-using-ruby-on-rails-heres-why-rails-still-rocks-in-2025-p78</link>
      <guid>https://dev.to/maliano63717738/i-built-a-free-url-shortener-in-4-hours-using-ruby-on-rails-heres-why-rails-still-rocks-in-2025-p78</guid>
      <description>&lt;h1&gt;
  
  
  I Built a Free URL Shortener in 48 Hours Using Ruby on Rails — Here's Why Rails Still Rocks in 2025
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Problem That Started It All
&lt;/h2&gt;

&lt;p&gt;Yesterday, I was working on an article about my Elixir project. I needed to share multiple long URLs in the post, so naturally, I reached for a popular URL shortening service.&lt;/p&gt;

&lt;p&gt;Three clicks later, I hit a wall: &lt;strong&gt;"You've reached your limit of 3 short links this month."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a developer, this felt wrong. Why should something as simple as shortening URLs be locked behind paywalls and limits?&lt;/p&gt;

&lt;p&gt;So I did what any developer would do: I built my own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;48 hours later, I had a fully functional, free, open-source URL shortener deployed and running.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Ruby on Rails?
&lt;/h2&gt;

&lt;p&gt;In 2025, with all the new frameworks and tools out there, why would I choose Rails?&lt;/p&gt;

&lt;p&gt;Simple answer: &lt;strong&gt;productivity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rails is built on the principle of "convention over configuration" — which means less time configuring, more time building. Here's what I got out of the box:&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡ Speed of Development
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails new url_shortener &lt;span class="nt"&gt;-d&lt;/span&gt; postgresql
rails generate scaffold Link original_url:text short_code:string clicks:integer
rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three commands. That's it. I had a full CRUD application with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database schema&lt;/li&gt;
&lt;li&gt;RESTful routes&lt;/li&gt;
&lt;li&gt;Controller actions&lt;/li&gt;
&lt;li&gt;View templates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎯 Smart Defaults
&lt;/h3&gt;

&lt;p&gt;Rails made architectural decisions for me, so I could focus on the unique business logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="ss"&gt;:generate_short_code&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_short_code&lt;/span&gt;
    &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;short_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SecureRandom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alphanumeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="no"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;short_code: &lt;/span&gt;&lt;span class="n"&gt;short_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Six lines of code to generate unique short codes. No external libraries needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  📦 The Ruby Ecosystem
&lt;/h3&gt;

&lt;p&gt;Need QR codes? There's a gem for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rqrcode'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One line in the Gemfile, and suddenly I could generate QR codes for every short link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RQRCode&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QRCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;short_url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;as_svg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The URL shortener includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instant Short Links&lt;/strong&gt; - Paste a URL, get a short code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click Analytics&lt;/strong&gt; - Track how many times each link is clicked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QR Code Generation&lt;/strong&gt; - Automatic QR codes for every link&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Registration Required&lt;/strong&gt; - Anyone can use it freely&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean, Responsive UI&lt;/strong&gt; - Built with inline CSS (no framework bloat)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Technical Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Ruby on Rails 8.1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QR Codes:&lt;/strong&gt; rqrcode gem&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; Render (free tier!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to MVP:&lt;/strong&gt; Less than 48 hours&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Rails Made This Possible
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Active Record Is Magic
&lt;/h3&gt;

&lt;p&gt;Rails' ORM (Active Record) turned database operations into elegant Ruby code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;short_code: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:short_code&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="vi"&gt;@link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:clicks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="vi"&gt;@link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;original_url&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No SQL, no boilerplate — just readable, maintainable code.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Database Migrations Are First-Class Citizens
&lt;/h3&gt;

&lt;p&gt;Every schema change is versioned and reversible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreateLinks&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;8.1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="ss"&gt;:links&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt; &lt;span class="ss"&gt;:original_url&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt; &lt;span class="ss"&gt;:short_code&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integer&lt;/span&gt; &lt;span class="ss"&gt;:clicks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timestamps&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;add_index&lt;/span&gt; &lt;span class="ss"&gt;:links&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:short_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;unique: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Convention Over Configuration
&lt;/h3&gt;

&lt;p&gt;Rails assumes sensible defaults. Want a redirect route?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'/:short_code'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s1"&gt;'links#redirect'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One line. Rails handles the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deployment Is a Breeze
&lt;/h3&gt;

&lt;p&gt;With Render, deploying Rails apps is ridiculously simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect GitHub repo&lt;/li&gt;
&lt;li&gt;Add environment variables&lt;/li&gt;
&lt;li&gt;Hit deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rails' convention-based structure means Render knows exactly how to build and run the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live URL:&lt;/strong&gt; [Your Deployed URL]&lt;br&gt;
&lt;strong&gt;Source Code:&lt;/strong&gt; [GitHub Repository]&lt;/p&gt;

&lt;p&gt;The project is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ 100% free to use&lt;/li&gt;
&lt;li&gt;✅ Open source (MIT license)&lt;/li&gt;
&lt;li&gt;✅ Deployable in 10 minutes&lt;/li&gt;
&lt;li&gt;✅ No registration required&lt;/li&gt;
&lt;li&gt;✅ Fully functional with analytics and QR codes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Rails Still Delivers on Its Promise
&lt;/h3&gt;

&lt;p&gt;After nearly 20 years, Rails remains one of the fastest ways to build web applications. The "Rails way" isn't just convention — it's accumulated wisdom from thousands of production apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Choose Boring Technology
&lt;/h3&gt;

&lt;p&gt;Rails isn't trendy. It doesn't make headlines at tech conferences. But it &lt;strong&gt;works&lt;/strong&gt;, and it works consistently.&lt;/p&gt;

&lt;p&gt;When you need to ship fast, reach for boring, proven technology.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Open Source Wins
&lt;/h3&gt;

&lt;p&gt;Instead of paying for limited features, I built exactly what I needed and made it available for everyone. That's the power of open source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The entire project is open source. You can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use the live version&lt;/strong&gt; at [Your Live URL]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy your own&lt;/strong&gt; in under 10 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fork and customize&lt;/strong&gt; to fit your needs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contribute features&lt;/strong&gt; via pull requests&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;In 2025, with AI, microservices, and serverless everything competing for our attention, it's easy to overcomplicate things.&lt;/p&gt;

&lt;p&gt;Sometimes, the best solution is the simplest one.&lt;/p&gt;

&lt;p&gt;Rails gave me superpowers: I went from idea to deployed product in 48 hours, with clean code, zero configuration headaches, and a fully functional app.&lt;/p&gt;

&lt;p&gt;That's the Rails magic that keeps me coming back.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What's your experience with Rails? Or what framework do you reach for when you need to ship fast? Let me know in the comments!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;📂 GitHub Repository: &lt;a href="https://github.com/aliabdm/url-shortener-rails" rel="noopener noreferrer"&gt;https://github.com/aliabdm/url-shortener-rails&lt;/a&gt;&lt;br&gt;
🚀 Live Demo: &lt;a href="https://url-shortener-rails.onrender.com/links" rel="noopener noreferrer"&gt;https://url-shortener-rails.onrender.com/links&lt;/a&gt;&lt;br&gt;
💼 Connect on LinkedIn:&lt;a href="https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/mohammad-ali-abdul-wahed-1533b9171/&lt;/a&gt;&lt;br&gt;
🐙 Follow on GitHub: &lt;a href="https://github.com/aliabdm" rel="noopener noreferrer"&gt;https://github.com/aliabdm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this helpful, give the project a ⭐ on GitHub!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with ❤️ using Ruby on Rails&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 PlainAid: Real-Time AI Text Simplifier Built with Elixir &amp; Phoenix LiveView</title>
      <dc:creator>Mohammad Ali Abdul Wahed</dc:creator>
      <pubDate>Sat, 27 Dec 2025 13:38:49 +0000</pubDate>
      <link>https://dev.to/maliano63717738/plainaid-real-time-ai-text-simplifier-built-with-elixir-phoenix-liveview-435m</link>
      <guid>https://dev.to/maliano63717738/plainaid-real-time-ai-text-simplifier-built-with-elixir-phoenix-liveview-435m</guid>
      <description>&lt;p&gt;I recently explored Elixir, a trending, high-performance language, and paired it with Phoenix LiveView to build PlainAid 🎯, a privacy-first web app that simplifies complex text instantly.&lt;/p&gt;

&lt;p&gt;Why I Chose Elixir &amp;amp; Phoenix LiveView&lt;/p&gt;

&lt;p&gt;Elixir: Runs on Erlang VM → handles millions of concurrent connections&lt;br&gt;
Fault-tolerant &amp;amp; scalable → apps stay reliable under load&lt;br&gt;
Phoenix LiveView: Real-time, interactive UI without heavy JavaScript&lt;br&gt;
Elixir + LiveView lets you build real-time web apps quickly, with clean code and high performance.&lt;/p&gt;

&lt;p&gt;What PlainAid Does&lt;br&gt;
PlainAid turns complex legal, official, or formal documents into clear, actionable insights:&lt;/p&gt;

&lt;p&gt;✅ Simplified Summary&lt;br&gt;
⚠️ Key Actions&lt;br&gt;
⏰ Deadlines&lt;br&gt;
🚨 Risks&lt;br&gt;
✓ Optional Items&lt;br&gt;
All real-time, secure, and privacy-first — no accounts, no data storage.&lt;/p&gt;

&lt;p&gt;flowchart TD&lt;br&gt;
&lt;code&gt;User --&amp;gt; LiveView[Phoenix LiveView UI]&lt;br&gt;
    LiveView --&amp;gt; Simplifier[Text Simplifier Module]&lt;br&gt;
    Simplifier --&amp;gt; AI[Groq API (Llama 3.3)]&lt;br&gt;
    AI --&amp;gt; Simplifier&lt;br&gt;
    Simplifier --&amp;gt; LiveView&lt;br&gt;
    LiveView --&amp;gt; User&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;- User inputs text in the web form&lt;/li&gt;
&lt;li&gt;- LiveView updates instantly&lt;/li&gt;
&lt;li&gt;- Simplifier sends text to AI API&lt;/li&gt;
&lt;li&gt;- Returns structured summary &amp;amp; actionable points&lt;/li&gt;
&lt;li&gt;- Displayed real-time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tech Stack&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;Elixir 1.19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Phoenix 1.7 + LiveView&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Processing&lt;/td&gt;
&lt;td&gt;Groq API (Llama 3.3 70B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Client&lt;/td&gt;
&lt;td&gt;HTTPoison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;Jason&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Render.com&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Try It Yourself&lt;br&gt;
🔗 Live Demo: &lt;a href="https://lnkd.in/dRFc8uMH" rel="noopener noreferrer"&gt;https://lnkd.in/dRFc8uMH&lt;/a&gt;&lt;br&gt;
📂 GitHub Repo (Open Source — MIT): &lt;a href="https://lnkd.in/dPR7YcGC" rel="noopener noreferrer"&gt;https://lnkd.in/dPR7YcGC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why This Matters&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build interactive, real-time apps with minimal front-end code&lt;/li&gt;
&lt;li&gt;Scalable &amp;amp; fault-tolerant → handles growth effortlessly&lt;/li&gt;
&lt;li&gt;Privacy-first design → perfect for sensitive documents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ideas for Contribution&lt;br&gt;
Multi-language support (Arabic, Spanish, French)&lt;br&gt;
Browser extension&lt;br&gt;
Export results to PDF/DOCX&lt;br&gt;
Batch processing of documents&lt;br&gt;
Enhanced AI summarization&lt;br&gt;
📢 PlainAid is live &amp;amp; ready for testing!&lt;/p&gt;

&lt;p&gt;Give it a try, fork the repo, or contribute. Let’s make reading complex text simple for everyone.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
