Entropic 2.14.3
Local-first agentic inference engine
Loading...
Searching...
No Matches
orchestrator.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
23#pragma once
24
34
35#include <chrono>
36#include <functional>
37#include <memory>
38#include <mutex>
39#include <optional>
40#include <string>
41#include <unordered_map>
42#include <unordered_set>
43#include <vector>
44
45struct llama_context; // Forward declaration for adapter management
46struct llama_model; // Forward declaration for speculative compat (v2.1.11)
47
48namespace entropic {
49
50// v2.13.1: `gpu_layers: auto` types. Declared, not included — they live in
51// src/inference/ and the public header must not pull a private one in.
52struct GgufShape;
53struct AutoPlacement;
54
60 std::string tier_name;
61 std::string previous_tier;
62 std::string model_raw;
63 std::string swap_action = "none";
64 double routing_ms = 0.0;
65 std::string adapter_name;
66 double adapter_swap_ms = 0.0;
67};
68
81 std::optional<float> temperature;
82 std::optional<int> max_output_tokens;
83 std::optional<float> top_p;
84 std::optional<int> top_k;
85 std::optional<float> min_p;
86 std::optional<float> presence_penalty;
87 std::optional<float> frequency_penalty;
88 std::optional<float> repeat_penalty;
89 std::optional<bool> enable_thinking;
90 std::optional<std::string> tool_call_mode;
91};
92
106ENTROPIC_EXPORT void apply_tier_sampler_overrides(
108 const TierSamplerOverrides& ov);
109
119public:
126 bool initialize(const ParsedConfig& config);
127
132 void shutdown();
133
157
158 /* ── Generation ──────────────────────────────────────── */
159
169 const std::vector<Message>& messages,
171 const std::string& tier_name = "");
172
183 const std::vector<Message>& messages,
185 std::atomic<bool>& cancel,
186 const std::string& tier_name = "");
187
205 std::vector<GenerationResult> generate_batch(
206 const std::vector<std::vector<Message>>& messages_list,
207 const std::vector<GenerationParams>& params_list,
208 const std::vector<std::string>& tiers,
209 std::atomic<bool>& cancel);
210
216 const std::vector<Message>& messages,
218 std::function<void(std::string_view)> on_token,
219 std::atomic<bool>& cancel,
220 const std::string& tier_name = "");
221
222 /* ── Routing ─────────────────────────────────────────── */
223
230 std::string route(const std::vector<Message>& messages);
231
232 /* ── Queries ─────────────────────────────────────────── */
233
239
244 std::string last_used_tier() const;
245
250 std::vector<std::string> loaded_models() const;
251
256 std::vector<std::string> available_models() const;
257
262 bool can_handoff(const std::string& from, const std::string& to) const;
263
268 ChatAdapter* get_adapter(const std::string& tier_name) const;
269
276 InferenceBackend* get_backend(const std::string& tier_name) const;
277
302 InferenceBackend* ensure_model(const std::string& tier_name);
303
332 entropic_error_t release_models(const std::string& tier_name);
333
350 bool tier_declares_vision(const std::string& tier_name) const;
351
358 AdapterManager& adapter_manager() { return lora_manager_; }
359
366 GrammarRegistry& grammar_registry() { return grammar_registry_; }
367
381 std::vector<GenerationRecord> generation_records() const;
382
385 static constexpr size_t kMaxGenerationRecords = 64;
386
393 ProfileRegistry& profile_registry() { return profile_registry_; }
394
401 ThroughputTracker& throughput_tracker() { return throughput_tracker_; }
402
409 size_t load_grammars_from(const std::filesystem::path& grammar_dir);
410
422
436 bool has_vision_capable_tier() const;
437
444 bool compatible = false;
445 std::string diagnostic;
446 };
447
465
482
483 /* ── VRAM-aware tier residency (v2.2.4, gh#57) ────────── */
484
491 enum class ResidencyEvent : int {
492 Loaded = 0,
493 Evicted = 1,
494 ActivationSwap = 2,
495 };
496
511 using ResidencyObserverFn = std::function<void(
513 const std::string& tier_name,
514 const std::string& model_path,
515 size_t footprint)>;
516
527
539 std::string residency_snapshot_json() const;
540
559 void forget_session_kv(const std::string& session_key);
560
572 size_t vram_budget_bytes() const { return vram_budget_bytes_; }
573
585 size_t tier_footprint_bytes(const std::string& tier_name) const;
586
598 entropic_error_t last_residency_error() const { return last_residency_error_; }
599
605 void clear_last_residency_error() { last_residency_error_ = ENTROPIC_OK; }
606
622 std::string select_vision_tier() const;
623
643 const std::string& tier_name) {
644 apply_tier_sampler_defaults(params, tier_name);
645 }
646
647private:
662 void record_generation(GenerationResult& result,
664 const InferenceBackend* model);
665
685 void finish_generation(GenerationResult& result,
686 InferenceBackend* model,
688 const std::string& selected,
689 double routing_ms,
690 double swap_ms,
691 std::chrono::steady_clock::time_point t_start);
692
693 /* ── gh#154: bounded per-generation metric ring ──────── */
694 mutable std::mutex records_mutex_;
695 std::vector<GenerationRecord> generation_records_;
696
697 /* ── Model pool (one backend per unique path) ────────── */
698 std::unordered_map<std::string, std::shared_ptr<InferenceBackend>> model_pool_;
699
700 /* ── Tier → backend mapping (many-to-one) ────────────── */
701 std::unordered_map<std::string, std::shared_ptr<InferenceBackend>> tiers_;
702
703 /* ── Per-tier adapters (one-to-one, identity-specific) ── */
704 std::unordered_map<std::string, std::unique_ptr<ChatAdapter>> adapters_;
705
706 /* ── Secondary models (router, draft, future thinking) ── */
717 SecondaryModelLoader secondary_loader_;
718
719 /* ── Routing state ───────────────────────────────────── */
720 std::unordered_map<std::string, std::string> tier_map_;
721 std::unordered_map<std::string, std::unordered_set<std::string>> handoff_rules_;
722 std::string default_tier_;
723 std::string loaded_main_tier_;
724 RoutingResult last_routing_result_;
725 std::vector<std::string> tier_history_;
726
727 mutable std::mutex swap_mutex_;
728
769 mutable std::recursive_mutex generation_mutex_;
770
771 ParsedConfig config_;
772
773 /* ── Residency tracking (v2.2.4, gh#57) ──────────────── */
774
784 mutable std::unordered_map<std::string, size_t> tier_footprint_bytes_;
785
792 std::unordered_map<std::string, long long> tier_last_activation_ms_;
793
798 std::chrono::steady_clock::time_point start_time_{std::chrono::steady_clock::now()};
799
811 size_t vram_budget_bytes_{0};
812
816 bool vram_budget_resolved_{false};
817
822 bool vram_budget_deferred_{false};
823
828 ResidencyObserverFn residency_observer_;
829
834 entropic_error_t last_residency_error_{ENTROPIC_OK};
835
844 std::string last_residency_message_;
845
866 size_t estimate_footprint_bytes(const std::string& tier_name) const;
867
876 void log_fit_recommendation(const std::string& tier_name) const;
877
902 static size_t resolve_vram_budget_bytes();
903
915 void ensure_vram_budget();
916
927 static bool budget_resolves_at_init(const ParsedConfig& config);
928
935 static void route_ggml_logs(const ParsedConfig& config);
936
947 void fire_residency_observer(
949 const std::string& tier_name,
950 const std::string& model_path,
951 size_t footprint);
952
953 /* ── LoRA adapter management (v1.9.2) ────────────────── */
954 AdapterManager lora_manager_;
955
956 /* ── Grammar registry (v1.9.3) ────────────────────────── */
957 GrammarRegistry grammar_registry_;
958
959 /* ── Profile registry (v2.0.0) ───────────────────────── */
960 ProfileRegistry profile_registry_;
961
962 /* ── Throughput tracker (v2.0.0) ─────────────────────── */
963 ThroughputTracker throughput_tracker_;
964
965 /* ── Internal ────────────────────────────────────────── */
966
971 InferenceBackend* get_model(const std::string& tier_name);
972
980 void record_activation_reuse(const std::string& tier_name);
981
995 bool residency_admits(const std::string& tier_name);
996
1004 void resolve_auto_gpu_layers(const std::string& tier_name);
1005
1012 uint64_t resident_draft_bytes() const;
1013
1022 void fall_back_to_weights_estimate(const std::string& tier_name,
1023 uint64_t file_bytes, const char* why);
1024
1041 static uint64_t host_expert_bytes_for(const ModelConfig& cfg);
1042
1043 void log_auto_placement(const std::string& tier_name,
1044 const GgufShape& shape,
1045 const AutoPlacement& placement,
1046 uint64_t file_bytes) const;
1047
1056 bool config_admits(const std::string& tier_name);
1057
1067 void refuse_residency(const std::string& tier_name,
1069 const std::string& why);
1070
1077 InferenceBackend* activate_and_track(
1078 const std::string& tier_name,
1079 const std::shared_ptr<InferenceBackend>& backend);
1080
1088 GenerationResult build_no_model_error(const std::string& tier_name);
1089
1094 void deactivate_current_if_needed(InferenceBackend* incoming);
1095
1108 void ensure_tier_lora(const std::string& tier_name,
1109 InferenceBackend* result);
1110
1121 void unload_or_warm_current(InferenceBackend* current);
1122
1127 std::pair<std::string, std::string> classify_task(
1128 const std::vector<Message>& messages);
1129
1136 bool deactivate_if_active(llama_context* ctx);
1137
1149 double ensure_adapter_for_tier(
1150 const std::string& tier_name, llama_context* ctx);
1151
1159 void release_backend(InferenceBackend* backend);
1160
1169 void announce_eviction(const InferenceBackend* backend);
1170
1185 void ensure_secondary_roles();
1186
1200 void preload_adapters_for_model(InferenceBackend* backend);
1201
1209 bool create_tier_backends(const ParsedConfig& config);
1210
1217 void build_routing_tables(const ParsedConfig& config);
1218
1226 bool activate_default_tier(const ParsedConfig& config);
1227
1234 void activate_router(const ParsedConfig& config);
1235
1251 void activate_draft(const ParsedConfig& config);
1252
1257 void load_bundled_grammars();
1258
1265 void resolve_grammar_key(GenerationParams& params,
1266 const std::string& tier_name);
1267
1295 std::optional<GenerationResult> refuse_unresolved_tier_grammar(
1296 GenerationParams& params, const std::string& tier_name);
1297
1315 std::optional<GenerationResult> refuse_unresolved_batch_grammars(
1316 const std::vector<GenerationParams>& params_list,
1317 const std::vector<std::string>& tiers,
1318 const std::string& lead,
1319 std::vector<GenerationParams>& out);
1320
1335 void stage_batch_arms(InferenceBackend* model,
1336 const std::vector<std::string>& tiers,
1337 const std::string& lead,
1338 std::vector<GenerationParams>& resolved);
1339
1352 void apply_tier_sampler_defaults(GenerationParams& params,
1353 const std::string& tier_name);
1354
1377 GenerationParams resolve_and_stage(InferenceBackend* model,
1378 const GenerationParams& params,
1379 const std::string& tier_name);
1380
1391 std::string resolve_speculative_pair(
1393
1403 bool try_speculative_route(
1404 InferenceBackend* model,
1405 const std::vector<Message>& messages,
1406 const GenerationParams& params,
1407 const std::string& tier_name,
1408 GenerationResult& result);
1409
1420 GenerationResult run_generate_dispatch(
1421 InferenceBackend* model,
1422 const std::vector<Message>& messages,
1423 const GenerationParams& params,
1424 const std::string& tier_name);
1425
1435 bool try_speculative_route_streaming(
1436 InferenceBackend* model,
1437 const std::vector<Message>& messages,
1438 const GenerationParams& params,
1439 const std::string& tier_name,
1440 std::function<void(std::string_view)> on_token,
1441 std::atomic<bool>& cancel,
1442 GenerationResult& result);
1443
1454 bool try_mtp_route(
1455 InferenceBackend* model,
1456 const std::vector<Message>& messages,
1457 const GenerationParams& params,
1458 std::function<void(std::string_view)> on_token,
1459 std::atomic<bool>& cancel,
1460 GenerationResult& result);
1461
1471 bool resolve_mtp_effective(const std::string& tier_name) const;
1472};
1473
1474} // namespace entropic
ChatAdapter concrete base class.
AdapterManager — LoRA adapter lifecycle and hot-swap.
LoRA adapter lifecycle manager.
Concrete base class for chat format adapters (80% logic).
Centralized grammar registry for named GBNF grammars.
Concrete base class for inference backends (80% logic).
Definition backend.h:69
Multi-model lifecycle and routing orchestrator.
size_t vram_budget_bytes() const
Engine-tracked VRAM budget in bytes (0 = unknown).
SpeculativeCompatInfo check_speculative_compat() const
Check whether the currently-configured target/draft pair is compatible for speculative decoding.
std::vector< std::string > available_models() const
All configured tier names.
size_t load_grammars_from(const std::filesystem::path &grammar_dir)
Load grammars from an explicit directory path.
GrammarRegistry & grammar_registry()
Access the grammar registry.
GenerationResult generate_streaming(const std::vector< Message > &messages, const GenerationParams &params, std::function< void(std::string_view)> on_token, std::atomic< bool > &cancel, const std::string &tier_name="")
Streaming generation.
entropic_error_t release_models(const std::string &tier_name)
Release resident model(s), keeping every registration (gh#164).
void apply_tier_sampler_defaults_for_test(GenerationParams &params, const std::string &tier_name)
Test-only forwarder to the private per-tier sampler default application (gh#94, audit task #71).
std::vector< std::string > loaded_models() const
Currently loaded model tier names.
bool initialize(const ParsedConfig &config)
Initialize from parsed config.
bool has_vision_capable_tier() const
Return true if any configured tier declares the "vision" capability (gh#41, v2.1.8).
void forget_session_kv(const std::string &session_key)
Drop one session's resident KV on every loaded tier (gh#165).
size_t tier_footprint_bytes(const std::string &tier_name) const
Estimated VRAM footprint for a given tier in bytes.
AdapterManager & adapter_manager()
Access the LoRA adapter manager.
void shutdown()
Shutdown — unload all models.
RoutingResult last_routing_result() const
Last routing result.
std::vector< GenerationRecord > generation_records() const
Per-generation metric records, oldest first (gh#154).
std::function< void(ResidencyEvent event, const std::string &tier_name, const std::string &model_path, size_t footprint)> ResidencyObserverFn
Residency observer callback type (internal C++ form).
GenerationResult generate(const std::vector< Message > &messages, const GenerationParams &params, const std::string &tier_name="")
Generate using routed or explicit tier.
void clear_last_residency_error()
Clear last_residency_error().
void clear_all_prompt_caches()
Invalidate prompt/KV caches across every pooled backend.
static constexpr size_t kMaxGenerationRecords
Ring capacity for generation_records().
entropic_error_t last_residency_error() const
Last residency-related error code, or ENTROPIC_OK if none.
std::string route(const std::vector< Message > &messages)
Route to tier using router model.
ChatAdapter * get_adapter(const std::string &tier_name) const
Get adapter for a tier.
void set_residency_observer(ResidencyObserverFn cb)
Register a residency observer.
std::string last_used_tier() const
Last used tier name.
bool tier_declares_vision(const std::string &tier_name) const
Whether a tier is configured for vision, per CONFIG (gh#157).
~ModelOrchestrator()
Destructor — invokes shutdown() and AdapterManager::unload_all().
std::vector< GenerationResult > generate_batch(const std::vector< std::vector< Message > > &messages_list, const std::vector< GenerationParams > &params_list, const std::vector< std::string > &tiers, std::atomic< bool > &cancel)
Same-prefix batch generation on a shared resident model (gh#98).
InferenceBackend * ensure_model(const std::string &tier_name)
Get a tier's backend, loading it if it is not resident (gh#157).
std::string select_vision_tier() const
Pick the canonical vision-capable tier name (gh#41).
ProfileRegistry & profile_registry()
Access the GPU resource profile registry.
ThroughputTracker & throughput_tracker()
Access the throughput tracker.
void set_speculative_enabled(bool enabled)
Runtime toggle for the speculative-decoding path.
bool can_handoff(const std::string &from, const std::string &to) const
Check if handoff is permitted.
std::string residency_snapshot_json() const
Serialize the current residency set as a JSON string.
ResidencyEvent
Residency observer event codes — mirror the C ABI enum entropic_residency_event_t exactly (LOADED=0,...
InferenceBackend * get_backend(const std::string &tier_name) const
Get the inference backend for a tier (for evaluation APIs).
Centralized registry for named GPU resource profiles.
Role-keyed lifecycle manager for non-primary models.
EWMA-based throughput tracker for generation budgeting.
Configuration structs with defaults.
int * cancel
Consumer's cancel flag, nullable.
Definition engine.cpp:4074
Error types for cross-.so error reporting.
entropic_error_t
Error codes returned by all C API functions.
Definition error.h:37
@ ENTROPIC_OK
Success.
Definition error.h:38
GrammarRegistry — named grammar management and validation.
InferenceBackend concrete base class.
Activate model on GPU (WARM → ACTIVE).
@ enabled
Named in enabled_mcpjson_servers, or enable-all is set.
@ optional
optional: every escape asks the host's path approver
ENTROPIC_EXPORT void apply_tier_sampler_overrides(GenerationParams &params, const TierSamplerOverrides &ov)
Apply per-tier sampler overrides to params.
ProfileRegistry – named GPU resource profile management.
Unified lifecycle for non-primary inference backends.
std::string config
–config FILE
Definition serve.cpp:38
Generation parameters for a single inference call.
Definition config.h:389
Result of a single generation call.
SpeculativeConfig speculative
Speculative decoding (gh#36)
Definition config.h:1327
Result of a speculative-decoding compatibility check.
bool compatible
true when speculative may proceed
std::string diagnostic
Reason on failure (empty on ok)
Full parsed configuration.
Definition config.h:1338
InferenceConfig inference
Inference-side knobs (currently speculative decoding only).
Definition config.h:1444
Result metadata from a routing decision.
std::string adapter_name
Active adapter (empty = base model) (v1.9.2)
double routing_ms
Total routing time.
std::string model_raw
Raw model output (e.g. "2")
std::string tier_name
Selected tier.
std::string swap_action
"none", "reused", "loaded"
std::string previous_tier
Previous tier (empty if first)
double adapter_swap_ms
Adapter swap latency (v1.9.2)
bool enabled
Master switch (off by default)
Definition config.h:1286
Per-tier sampler overrides parsed from identity frontmatter.
std::optional< float > top_p
gh#85
std::optional< float > temperature
gh#82
std::optional< float > min_p
gh#85
std::optional< float > presence_penalty
gh#85
std::optional< std::string > tool_call_mode
gh#103
std::optional< float > frequency_penalty
gh#85
std::optional< int > top_k
gh#85
std::optional< bool > enable_thinking
gh#86
std::optional< float > repeat_penalty
gh#86
std::optional< int > max_output_tokens
gh#82
ThroughputTracker – real-time throughput measurement and prediction.