DEV Community

Tired Hobo
Tired Hobo

Posted on

0.6.599

Building Jan.ai from Source with a Local LLM

The Goal

I wanted a recent build of Jan.ai. I got a 0.6.599 .deb. That's when I re-read my own prompt.

The Prompt

The model was given a single, generic instruction. Nothing about versions, tags, or checking what was already installed. It said:

Target application: jan.ai desktop application
Container name pattern: [os]-[shortname] (e.g., ubuntu-jan)
Base image: glibc-based (e.g., ubuntu:22.04)


Procedure:
1. Create a container with the specified base image.
2. If the container already exists, enter it and decide whether to continue or recreate.
3. Use web search to find build instructions for the target application on the detected OS.
4. Build the application from source inside the container.
5. No need to install the built application on the host.


Persistent build state:
- Maintain /tmp/build_state.json with fields: status, phase, steps_completed, last_error, progress_log.
- Before any action, read the state file.
- After each major step, update the file.
- If a command fails, record the error, search for a fix, and continue.


Wrapper script (/tmp/run_and_log.sh):
- Execute every build command through this wrapper.
- Append stdout+stderr to /tmp/build_output.log.
- Update the state file automatically.
- Return only a small JSON status (no output in tool response).


Error handling:
- On failure, search the web for the exact error.
- Apply fixes and retry.
- After two failures, stop and report.


General guidelines:
- Prefer git for source.
- Install dependencies via native package manager.
- For missing packages, build from source.
- Avoid unnecessary steps.

Enter fullscreen mode Exit fullscreen mode

 

The Hard Truth

The prompt did not say "check the latest tag". It did not say "compare with your installed version". It did not even say "figure out what version you are building". The model did exactly what I asked. The failure was in the ask.
Attempt 1 – Alpine

The first container was Alpine. Lightweight, fast. The model installed git, gcc, rustup. It cloned the Jan.ai repo. It built the web frontend. Then it tried to compile the Rust backend.

Linking failed. Error after error. Something about musl vs glibc. The model searched. It installed gcompat. It patched pkg-config. It tried cross-compile tricks. Nothing worked. After several hours it wiped the container and started over.
Attempt 2 – Ubuntu 22.04

The second container used Ubuntu 22.04. This time the model searched for "jan.ai build from source ubuntu". It found the official README. It installed build-essential, libgtk-3-dev, libwebkit2gtk, nodejs, yarn, rustup. Each command went through a wrapper script that logged everything to /tmp/build_output.log and updated /tmp/build_state.json.

The state file grew. Step after step.

It ran yarn install – succeeded. yarn build:web – succeeded. cargo build --release – succeeded. A binary appeared: jan.

Then it ran yarn tauri build to make a package. Failed.

Failed to copy binary from "/opt/jan-build/src-tauri/target/release/jan-cli": No such file or directory.
Enter fullscreen mode Exit fullscreen mode

The model built jan. The bundler expected jan-cli. Why? Because src-tauri/Cargo.toml contained a [[bin]] entry for jan-cli with a missing source file.

The model tried a symlink. The bundler ignored it. It copied jan to jan-cli. The bundler complained about missing the "cli" feature. It wrote a dummy jan-cli.rs and compiled it with --features cli. That worked.

The .deb

The .deb was there: Jan_0.6.599_amd64.deb.

I copied it to my host. The filename already said 0.6.599. I was too excited to notice. I ran sudo dpkg -i. The prompt asked for confirmation. I hit y without reading. The warning flashed: downgrading from 0.7.9 to 0.6.599.

The Downgrade

Only then did I check the container's Git log. The model had cloned main at commit f46148e77 – months old, long before the current stable releases. The prompt never mentioned a version. The model never had a reason to care.

The app launched. It loaded models. It responded to prompts. It worked – just older.

Then I noticed the pattern: every time the model hit a missing binary, it tried something, failed, tried something else, failed again. The log file grew. The state file recorded dozens of steps. Two hours of compilation for a downgrade.
Aftermath

I didn't learn any grand lesson. I just watched the machine grind.

The .deb still sits in my downloads folder. I installed it once. Then I removed it. Then I installed it again. It still works – the same old version, still responding to prompts, still unaware that anything is wrong.

I haven't deleted it. I don't know why.


Next time: I'm taking this back to Alpine. We're going to see if I can prompt this machine to handle cross-compilation without it trying to take the easy way out with a .deb again."

Top comments (0)