Feat/m perf 9 engine model identity#3
Conversation
M-Perf.9 (ggml-org#289) closes the loop on cross-model KV safety: a KV cache built with model A is incompatible with model B, and the Coordinator must never silently restore a cross-model cache. Three changes: * llama_model_hash() — public API + impl that returns the SHA-256 of the GGUF file the model was loaded from. Computed once in llama_model_load_from_file after construction; stored on the llama_model struct as hash_hex. New self-contained SHA-256 helper in src/llama-hash.cpp (no OpenSSL/libcrypto). * State META / GET now carry model_alias + model_hash + model_path so the Coordinator can record which model built each KV. STATE_META (0x32) and STATE_GET (0x30) responses populate these from impl->model_name / impl->params_base.model.path / llama_model_hash(). * Engine PREFILL (0x42) now accepts an optional 'model' key in the request JSON. The C++ side swaps to the requested alias when the preset registry knows it, falls back to the resident model with model_fallback: true in the response when the alias is unknown (or no preset is configured), and behaves as before when 'model' is absent. The engine uses the existing common_preset_context::load_from_ini (common/preset.cpp:315-365) — same INI format llama-server router mode already uses. * Engine INFO (0x41) now advertises the new capabilities ('preset', 'model_hash') and lists preset_aliases. * Engine PIPELINE_ATTACH (0x46) is now defined as a real opcode (previously referenced in WIP that referenced 0x33-0x38 which collides with C# OpCode.GetManifest=0x33) and stubbed to return HYDRA_STATUS_NOT_IMPLEMENTED (new status 0x06) so the Coordinator can distinguish 'not yet built' (issue ggml-org#287) from a real error and fall back to solo mode. The dispatch in hydra_handle_connection routes 0x46 to hydra_handle_pipeline_attach. * server_task_result_hydra_state and server_task_result_hydra_engine gained the model_* fields; to_json() emits them. Refs: ggml-org#289, advances ggml-org#287 Closes: M-Perf.9
…reset alias registry Closes the 4 P0 review blockers from PR ggml-org#290. P0.1 — Add the missing SERVER_TASK_TYPE_HYDRA_ENGINE_PIPELINE_ATTACH entry to the task enum. The PR's handler for 0x46 referenced an undefined symbol — the build would not have compiled. P0.2 — Engine PREFILL now parses the optional 'model' key from the request body. When the alias is in the preset registry, the resident model is swapped via load_model() before the prefill runs; when the alias is unknown (or no preset is configured), the prefill runs on the resident model and the response carries model_fallback:true. The handler also re-derives the slot pointer after load_model since it allocates fresh slots. P0.3 — Engine INFO now returns the actual preset_aliases list from the populated preset_alias_to_path map (was hardcoded empty). P0.4 — Add preset_alias_to_path map to server_context_impl, populated at startup from --models-preset PATH (or directory of .ini files). Uses common_preset_context::load_from_ini and extracts LLAMA_ARG_MODEL from each preset section. Also renumbered the dispatch cases from the old WIP SERVER_TASK_TYPE_HYDRA_* names (0x33-0x38) to the new SERVER_TASK_TYPE_HYDRA_ENGINE_* names (0x40-0x46). The old enum entries are removed (the wire now exclusively uses 0x40-0x46 — the 0x33-0x38 range was a collision zone with the live C# OpCode.GetManifest=0x33). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ookup sites The original PR ggml-org#290 used 'model' as the variable name in 3 places (STATE_GET, STATE_META, and the post-PREFILL response site). The actual variable in server_context_impl is 'model_tgt' (declared at server-context.cpp:680). The build failed with 'model was not declared in this scope' at all 3 sites — caught by a fresh sm_120 cmake build of llama-server. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Code review — #3 (feat/m-perf-9-engine-model-identity → hydra-fork)Cross-linked from VerdictReady to merge, but recommend closing this PR in favour of #2's merge because #2 is a strict superset of #3. Why close instead of merge
The natural sequence is: merge #2 first (it fast-forwards What was reviewed (in this PR)
What's good
Cross-repo coordination gaps (carry-overs from the parent issue)Same three as in the #2 review:
What's NOT in this PR (also in #2, but neither has it)
Recommended actionClose this PR as superseded by #2. The merge of #2 contains every commit here plus the COMBINED work. After #2's merge, the parent submodule bump is a single Hydra PR that lands both ggml-org#290 (model identity, covered by this PR) and ggml-org#286 (multi-engine routing, covered by #2) in one go. Tracked at |
Overview
Additional information
Requirements