This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
GhostBASIC is an offline séance with the ghost of a programmer who never left the machine. You can ask it who created FORTRAN, paste a few lines of old BASIC, COBOL, FORTRAN, or C, or ask it who it is. It answers in a dark, eerie voice, but the explanations are meant to be accurate and beginner friendly.
I read the theme as honoring the past. Programs written in the 1960s and 1970s are still running somewhere, and the people who wrote them are mostly forgotten. The ghost is my way of letting that history talk back. The look follows from that: amber text on a dark screen, a boot sequence ("RUNNING SINCE 1964. NEVER SHUT DOWN."), and a typewriter effect, like an old terminal someone forgot to switch off.
Demo
The video was recorded with Wi-Fi turned off.
Code
GhostBASIC
Run it locally
Install Ollama, Python, and Node.js with npm. Then download the local model:
ollama pull qwen2.5:3b
From the project root, create the Python environment and install the backend packages:
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install google-adk litellm
Install the frontend packages:
Set-Location frontend
npm ci
Set-Location ..
Start Ollama, then launch both the ADK server and Vite frontend:
.\start-ghostbasic.ps1
Open http://localhost:5173. After the first setup and model download, GhostBASIC runs locally and works with the internet off.
Troubleshooting
- CONNECTION LOST in the chat: an old server may be using port 8000. Run the start script again and answer Y to stop it.
- CORS error in the browser console: the backend must be started with --allow_origins=http://localhost:5173.
- Slow replies: run
ollama psto see if the model is on the…
How I Built It
- Model: Qwen 2.5 3B, an open-weight model, running locally through Ollama.
- Agent framework: Google's Agent Development Kit (ADK), connected to Ollama through LiteLLM.
-
Two tools:
-
explain_legacy_codedetects the language, walks through the code line by line, and flags infinite loops and jumps to lines that don't exist. It only reads the code and never runs it. -
search_programming_historylooks things up in a small archive written as plain Python data: BASIC, COBOL, FORTRAN, C, punched cards, the GOTO debate, line numbers, Y2K, and the first computer bug.
-
-
Frontend: ** a React app that talks to the ADK API server. It shows `* READING THE ARCHIVE ***
whenever a tool runs, and?TOPIC NOT FOUND IN ARCHIVE` when the archive has nothing.
The hardest part was that a 3B model forgets facts and answers with confidence anyway. My first versions of the ghost got history wrong, for example about which language came first. Piling prompt rules on top made it stiff and still unreliable, so I moved the important parts into code:
- Before the model answers, a callback searches the archive and puts the matching facts in front of it.
- If a history-style question matches nothing, the model is told to say it's not in the archive instead of guessing.
- A second callback adds the eerie opening and closing lines, so the horror voice is guaranteed, and the model can concentrate on a correct explanation.
The limits are real. The archive is small, the wording changes from run to run, and the code tool only analyzes four languages. Adding archive entries is the easiest way to improve it.
Why Does Open Innovation Matter?
- *It works with the internet off. * After the first setup, the model, the agent, and the frontend all run on one laptop. Nothing is sent to a server, and even the fonts are bundled.
- *I could see and fix the failures. * When the ghost got something wrong, I could inspect the prompt, the tool results, and the model settings and change them. That is how the archive and the callbacks came about. With a closed API I would have been guessing.
- *Swapping the model is one line. * The model is a single setting, so I can try another open model, such as Gemma, without rewriting the project.
- It costs nothing to run and doesn't depend on a service that might disappear.
The Spirit of It
My favorite moment was asking about a language that isn't in the archive. The ghost didn't invent a history for it. It said the topic isn't in its archive and listed the ones it does remember. For a ghost story about forgotten code, a ghost that admits what it has forgotten felt right.
Top comments (0)