Zenbu

Mrjunejune
Login

Mrjunejune

My personal website where I post my blogs / about me and resume.

Copilot JRPG chat

/jrpg streams stateful turns through Seobeo and Deita to a local Python Copilot SDK/CLI runtime. The SDK uses a loopback LiteLLM Proxy configured with the github_copilot provider.

Python, Copilot CLI, LiteLLM, the web server, and their lockfiles are all managed by Bazel. Do not create a virtualenv or install packages with pip.

Authenticate LiteLLM once with the GitHub Copilot device flow:

export GITHUB_COPILOT_TOKEN_DIR="$HOME/.local/state/mrjunejune/inference/litellm-copilot"
bazel run //mrjunejune/inference:litellm_proxy -- \
  --authenticate \
  --token-dir "$GITHUB_COPILOT_TOKEN_DIR"

Then start the complete local stack with one Bazel command:

LITELLM_MASTER_KEY='<local proxy key>' \
  MRJUNEJUNE_ALLOW_ANONYMOUS_INFERENCE=1 \
  bazel run //mrjunejune:run_inference_stack

For UI work, start the same Seobeo, Deita, inference bridge, and SSE path with deterministic mock responses. This mode does not require Copilot authentication or a LiteLLM key:

bazel run //mrjunejune:run_inference_stack -- --mock

Send !hello, !response, !tool, !plan, or !error to run a scripted event sequence. Edit mrjunejune/inference/mock_responses.json to add commands, ordered SSE event payloads, per-event timing, and response chunks. Custom event types pass through Seobeo and are published by the page as mjj-jrpg-stream-event, ready for future tool-call and plan-view components. Mock conversations use a separate database under the inference state directory.

Keep GITHUB_COPILOT_TOKEN_DIR exported when starting the stack so it reads the same tokens. Without an override, both commands use $XDG_STATE_HOME/mrjunejune/inference/litellm-copilot, or ~/.local/state/mrjunejune/inference/litellm-copilot when XDG_STATE_HOME is unset. MRJUNEJUNE_INFERENCE_STATE moves all service-owned state. Internal processes bind to loopback. Provider keys, OAuth tokens, conversation IDs, prompts, and model output must not be committed or logged.

Anonymous inference is disabled unless MRJUNEJUNE_ALLOW_ANONYMOUS_INFERENCE=1 is explicitly set. Enabling it exposes paid inference without user authentication; keep the Seobeo rate/concurrency limits and LiteLLM budget enabled.

The production bundle includes the pinned Python environment, Copilot CLI, LiteLLM, JRPG assets, and C server:

bazel build -c opt //mrjunejune:mrjunejune_server_bundle

WebP assets

Raster source images live under mrjunejune/assets/png/ and assets/png/. Bazel converts them to WebP before they enter the server runfiles or release bundle:

bazel build //mrjunejune:generated_webp_assets
bazel build //mrjunejune:mrjunejune_server_bundle

The deployed site contains no PNG files. Add new PNG source assets to the corresponding list in mrjunejune/BUILD or assets/BUILD, then reference the generated .webp URL from the site.

HLS player

/tools/hls_player is a dependency-free JavaScript HLS player. It uses native HLS where available and a MediaSource fallback for unencrypted VOD playlists with fragmented MP4 segments. A VP9/Opus HLS sample is bundled at:

/public/hls-sample/master.m3u8

The sample is generated from mrjunejune/assets/video/sample_hls.mp4 through the restored FFmpeg CLI wrapper:

bazel run //mrjunejune:generate_hls_sample
bazel test //mrjunejune/test:hls_player_test
bazel test //mrjunejune/test:theme_and_webp_test

LaTeX editor

/tools/latex_editor sends source to the C server, which compiles it with the offline Tectonic runtime from //third_party/tectonic:runtime and returns the PDF directly to the browser. Bazel pins the static compiler, prewarms common packages, and includes both in the server runfiles and release bundle.

The compiler child uses restricted TeX file access, Linux Landlock, a seccomp network filter, and CPU, memory, file-size, process, and wall-clock limits. Compilation fails closed when the Linux sandbox cannot be applied.

bazel test //mrjunejune/test:latex_renderer_test
bazel test //mrjunejune/test:latex_editor_test

TODO