Odysseus Portable does not fork the upstream Odysseus repository. Instead, it clones the official source on first launch and pulls updates on every subsequent launch — then immediately applies a set of targeted, idempotent patches to the checked-out files. This architecture lets the portable bundle track upstream bug fixes, new models, and UI improvements automatically, while still injecting the handful of changes required to make Odysseus work from a USB drive on any OS without a system installation.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/techjarves/Odysseus-Portable/llms.txt
Use this file to discover all available pages before exploring further.
Why Patches Instead of a Fork?
Maintaining a fork of an actively developed project requires rebasing onto upstream regularly — a process that introduces merge conflicts, delays, and the risk of accidentally shipping a stale codebase. Patches sidestep that entirely: after eachgit pull --ff-only, the orchestrator re-applies every patch function in sequence. Because each patch checks for its target string before making any change, running them on an already-patched file is completely harmless.
The files modified by patches are listed in generatedPatchFiles in src/start.js:
git pull, ensureOdysseusSource() calls git restore -- <patchFiles> on this list, discarding any modifications from the previous session and returning the files to their upstream state. The pull then applies cleanly, and the patch functions run again immediately afterward.
Patch Reference
patchCookbookHelpers — Windows path support
patchCookbookHelpers — Windows path support
routes/cookbook_helpers.py.Fix 1 — Windows Scripts/ in PATH exportThe upstream _local_tooling_path_export function constructs a export PATH=... string that adds a virtual environment’s root directory to PATH. On Windows, executable scripts installed by pip live in <venv>/Scripts/, not the venv root itself. Without this fix, installed CLI tools are invisible to subshells.The patch detects whether the current platform or the venv path matches a Windows drive pattern and appends /Scripts to the exported PATH:_LOCAL_DIR_REThe upstream regex that validates local directory paths only accepts Unix-style absolute paths (starting with / or ~). Paths like C:\Users\alice\models fail validation and cause download requests to be rejected.The patch extends _LOCAL_DIR_RE to also accept Windows drive paths:\\ to / so the regex matches consistently.patchCookbookRoutes — HF token handling
patchCookbookRoutes — HF token handling
routes/cookbook_routes.py.Fix 1 — Mojibake in Windows log messagesThe upstream source contains a Unicode em-dash (—) inside an echo string that is written to a subprocess shell script. On Windows, the process code page may not be UTF-8, causing the em-dash to be mis-encoded and displayed as garbled characters in logs. The patch replaces it with a plain ASCII hyphen:_load_stored_hf_token() only reads the token from the Cookbook UI state file. If a user already has a token set in the standard HuggingFace CLI location or an environment variable, it is ignored. The patch rewrites the function to check four sources in priority order:patchCookbookStateNormalizer — Portable model directory default
patchCookbookStateNormalizer — Portable model directory default
static/js/cookbookRunning.js to change how the default HuggingFace hub cache is injected into the modelDirs list.The upstream code unconditionally prepends ~/.cache/huggingface/hub to the model directory list on every state normalisation. In portable mode, the canonical model store is the project’s models/ folder and the global HuggingFace cache may not exist or may contain irrelevant downloads.modelDirs configured will still get a sensible fallback, but once configureCookbookState() has written the portable models/ path into state, it is not displaced by the global cache.patchCookbookPortableServeScan — Serve tab scan scope
patchCookbookPortableServeScan — Serve tab scan scope
routes/cookbook_helpers.py to restrict model discovery in the Serve tab to the configured model_dirs only, rather than scanning every known HuggingFace cache path on the host machine.The upstream code always scans all paths returned by hf_cache_paths() (which includes ~/.cache/huggingface/hub, ~/AppData/Local/huggingface/hub, etc.) regardless of what model_dirs is set to. On a USB drive, those global caches may hold partial downloads from unrelated projects and would appear as confusing entries in the Serve tab.The patch makes global HF cache scanning conditional: it only happens when model_dirs is empty. When model directories are configured, the patch instead constructs per-directory scan calls that look inside each configured directory for hub/ and xet/ subdirectories.It also adds a guard inside the generated scan loop to skip hub and xet directory names themselves from appearing as model candidates:patchCookbookWindowsLlamaServer — Native binary on Windows
patchCookbookWindowsLlamaServer — Native binary on Windows
static/js/cookbook.js to use the native llama-server.exe binary on Windows when constructing the Serve tab’s launch command, instead of falling back to python -m llama_cpp.server.The upstream code distinguishes Windows from other platforms and uses the Python package as the Windows path because it cannot assume a native binary is present. Odysseus Portable ships a precompiled llama-server.exe in bin/llama/, so the Python fallback is unnecessary and significantly slower.The patch replaces both the Windows and Unix branches to use the native llama-server command, with the Python module as a fallback only on Unix:--reasoning off to the native server arguments, which suppresses reasoning-mode output that is not used in the standard Cookbook workflow.patchLlamaRouterContext — Context size adjustment
patchLlamaRouterContext — Context size adjustment
src/backends/llama/index.js (inside the Odysseus Portable source, not the Odysseus web app) to lower the default llama-server context size from 16 384 to 12 288 tokens.patchCookbookCachedRoutePortableFallback — /api/model/cached without model_dir
patchCookbookCachedRoutePortableFallback — /api/model/cached without model_dir
routes/cookbook_routes.py to handle GET /api/model/cached requests that arrive without a model_dir query parameter from a local (non-remote) client.In the upstream implementation, a missing model_dir on a local request returns an empty result because there is no configured local directory to scan. In portable mode, the canonical model directory is stored in cookbook_state.json, so the patch reads it from there as a fallback:d != "~/.cache/huggingface/hub" prevents the global HuggingFace cache from being injected as the scan target when it has been left in state as a default value.patchCookbookOllamaDropdown — Ollama engine option in UI
patchCookbookOllamaDropdown — Ollama engine option in UI
static/js/cookbook.js and one to static/js/cookbook-hwfit.js.cookbook.js — Add Ollama option to engine dropdownThe upstream Cookbook UI only lists llama.cpp as a local inference engine option. Odysseus Portable also supports Ollama, so the patch appends an Ollama option immediately after the existing llama.cpp entry:'ollama' backend match, but most GGUF models are detected as 'llamacpp' — and Ollama can serve GGUF models too.The patch adjusts the filter so that when Ollama is the selected engine, both 'ollama' and 'llamacpp' models are shown:patchCookbookLocalServerFix — Local server object resolution
patchCookbookLocalServerFix — Local server object resolution
static/js/cookbook.js to fix two functions that resolve the active server object from the environment state.getServerByVal fixThe upstream implementation returns null when val is 'local' or an empty string, which means the Local server is never resolved by value. The patch replaces the early return with an actual lookup:getSelectedServer fixWhen no remote host is set, the upstream function returns null instead of the Local server object. The patch adds a final fallback that finds the server with an empty, missing, or 'local' host field:patchCookbookRoutesBackendFallback — Download directory fallback
patchCookbookRoutesBackendFallback — Download directory fallback
routes/cookbook_routes.py to inject a fallback download directory when a download request arrives with no local_dir and no remote host.The upstream validation raises an error if local_dir is missing for a local download. The patch inserts a fallback step before validation that reads the download directory from cookbook_state.json:configureCookbookState — Portable model directory initialisation
configureCookbookState — Portable model directory initialisation
configureCookbookState(odysseusDir, projectRoot) writes or updates odysseus/data/cookbook_state.json to ensure the Local server’s model and download directories always point to the portable models/ folder.On first launch, it creates the full state structure. On subsequent launches, it reads the existing file, preserves all user-defined settings (tasks, presets, credentials, remote servers), finds the Local server entry, and updates only the three directory fields:platform field is also refreshed on every launch so the Cookbook frontend uses the correct path separator and shell command format for the current operating system — important when the same drive is used on both Windows and macOS.Patch Execution Order
The orchestrator calls patch functions in a fixed order immediately afterensureOdysseusSource() returns:
configureCookbookState runs later in the startup sequence, after the Python environment is set up and setup.py has initialised the database, to ensure the data/ directory exists before the state file is written.