Skip to content

fork: P0-1 head-bootstrap mode for llama-engine (hydra_vortex #49)#54

Merged
ddvnguyen merged 4 commits into
hydra-forkfrom
engine-head-bootstrap
Jul 13, 2026
Merged

fork: P0-1 head-bootstrap mode for llama-engine (hydra_vortex #49)#54
ddvnguyen merged 4 commits into
hydra-forkfrom
engine-head-bootstrap

Conversation

@hydra-z

@hydra-z hydra-z Bot commented Jul 13, 2026

Copy link
Copy Markdown

Summary

Adds head-bootstrap mode to llama-engine binary so it can start without --model and bootstrap into a full head via CONFIGURE T3 RPC. This reuses the existing first_load_pending / apply_pending_hydra_config() / apply_t3_rebuild() mechanism from PR #48/#53 — no parallel implementation.

Problem

The entire CONFIGURE T3 bootstrap mechanism only existed in server.cpp (llama-server binary). The binary Hydra actually deploys for COMBINED mode (llama-engine) reimplemented its own startup dispatch and had no code path to build a server_context without a model already in hand. Starting llama-engine with no --model made it a compute-only ggml-RPC peer permanently — it could never become a head via CONFIGURE.

Design

Signal: The --rpc-engine flag (has_peer) distinguishes two cases when has_model is false:

  • !has_model && !has_peer: Compute-only peer (unchanged) — bare ggml-RPC backend
  • !has_model && has_peer: Head bootstrap (new) — waits for CONFIGURE T3

Verified: peer-only nodes never have --rpc-engine in their Hydra Head Go configs; head-bootstrap nodes always do.

Changes (4 rounds)

Round 2 (933c97262): Core head-bootstrap mode

  • Split no-model path in llama-engine.cpp into compute-only peer vs head-bootstrap
  • Add bootstrap_init() to server_context (wires queue callbacks without model)
  • Add set_routes_ptr() for refresh_meta() after first load
  • Add set_bootstrap_capabilities() for deferred capability staging
  • Add hydra_rpc::update_backends() for populating compute backends post-load
  • apply_pending_hydra_config() success path now registers local tensors, enables shared-backend compute lock, and updates RPC backends

Round 3 (4f296e996): Three review fixes

  • ctx_http.is_ready set immediately after start() (was never set — /health would 503 forever)
  • Capabilities wired through staged fields applied after first load
  • Initial null-meta guards in handle_completions_impl, post_chat_completions, post_infill

Round 4 (5a59df5b5): Complete null-meta coverage

  • Guards added to all 13 handlers that dereference meta->: get_props, post_responses_oai, post_transcriptions_oai, post_anthropic_messages, post_anthropic_count_tokens, post_apply_template, get_models, get_model_info, post_rerank, handle_embeddings_impl (plus 3 from round 3)

Round 5 (c439f2b43): Missing bootstrap_init() call

  • Added bootstrap_init() public method + implementation (queue callbacks were never wired — std::bad_function_call crash on start_loop())

Smoke test results

/health → 200 {"status":"ok","mode":"bootstrap"}
/v1/chat/completions (pre-CONFIGURE) → 501 {"error":{"code":501,"message":"model not loaded — waiting for CONFIGURE","type":"not_supported_error"}}

Files changed

File Change
tools/server/server-context.h Added bootstrap_init(), set_routes_ptr(), set_bootstrap_capabilities()
tools/server/server-context.cpp Added bootstrap_init(), staged capabilities fields, apply_pending_hydra_config() enhancements, null-meta guards in 13 handlers
tools/llama-engine/llama-engine.cpp Split no-model path, head-bootstrap mode with full scaffolding
tools/llama-engine/hydra_rpc/hydra_rpc.h Added update_backends() API
tools/llama-engine/hydra_rpc/hydra_rpc.cpp Implemented update_backends()

Regression verification

The compute-only peer path (!has_model && !has_peer) is byte-identical in behavior — only a log string changed. All changes are additive to the head-bootstrap branch only.

Hydra Engineering added 4 commits July 13, 2026 16:00
…hanism (hydra_vortex #49)

When llama-engine starts with no --model but with --rpc-engine (indicating
it's a head, not a peer), it now builds server_context + server_routes +
Hydra RPC and waits for CONFIGURE(0x40) T3 to load the model. This reuses
the existing first_load_pending / apply_pending_hydra_config() /
apply_t3_rebuild() mechanism from PR #48/#53 — no parallel implementation.

Key changes:
- Add set_routes_ptr() public method to server_context (for head-bootstrap
  to wire routes_ptr without accessing impl directly)
- Split no-model path in llama-engine.cpp:
  - !has_model && !has_peer: compute-only peer (unchanged)
  - !has_model && has_peer: head-bootstrap mode (new)
- Head-bootstrap creates server_context + server_routes + Hydra RPC
  with empty backends, registers full HTTP inference routes
- CONFIGURE T3 triggers apply_pending_hydra_config() via existing
  first_load_pending mechanism in update_slots()

Verified has_peer signal: peer-only nodes (RTX 3060) never have --rpc-engine
in their config, head-bootstrap nodes always do.
…ra_vortex #49)

Three fixes for head-bootstrap mode:

1. ctx_http.is_ready now set immediately after start() — the server is
   ready from the moment HTTP starts, matching the compute-only-peer
   pattern. Individual routes handle the no-model-yet case themselves.

2. set_hydra_capabilities/set_hydra_combined_static called after deferred
   first-load via bootstrap_* fields staged at startup and applied in
   apply_pending_hydra_config() success path. Also registers local
   tensors, enables shared-backend compute lock, and updates RPC backends.

3. Null-meta guard in handle_completions_impl, post_chat_completions,
   and post_infill — returns 503 with clear message instead of crashing
   when meta is null (bootstrap window before first CONFIGURE).

Also adds hydra_rpc::update_backends() for populating compute backends
after deferred first-load.
…hydra_vortex #49)

Added null-meta guards (returns 503 + clear message) to every handler
that dereferences meta-> under meta_mutex:

  get_props, post_responses_oai, post_transcriptions_oai,
  post_anthropic_messages, post_anthropic_count_tokens,
  post_apply_template, get_models, get_model_info, post_rerank,
  handle_embeddings_impl

Previously covered (round 3): handle_completions_impl,
post_chat_completions, post_infill.

The bootstrap window (is_ready=true, no model loaded yet) is now safe
to expose to real traffic — all endpoints return a clear 503 instead
of crashing on null deref.
…oop() (hydra_vortex #49)

Without bootstrap_init(), the queue callbacks (on_new_task, on_update_slots,
on_sleeping_state) are never wired up in head-bootstrap mode, causing
std::bad_function_call crash when start_loop() tries to invoke them.

bootstrap_init() wires up these callbacks + metrics.init() without requiring
a model (no ctx_tgt/model_tgt assertions). Called before start_loop() in
the head-bootstrap path.

Verified via smoke test:
- /health returns 200 {"status":"ok","mode":"bootstrap"}
- /v1/chat/completions returns 501 "model not loaded — waiting for CONFIGURE"
@ddvnguyen
ddvnguyen merged commit 38bd143 into hydra-fork Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant