Entropic 2.11.1
Local-first agentic inference engine
Loading...
Searching...
No Matches
engine.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
24#pragma once
25
26#include <entropic/entropic.h> // for ent_decision_t and ent_delegation_* (gh#29, v2.1.5)
32#include <entropic/core/sandbox.h> // gh#33 (v2.1.6): engine-owned session sandbox
37
38#include <atomic>
39#include <deque>
40#include <filesystem>
41#include <mutex>
42#include <optional>
43#include <string>
44#include <unordered_map>
45#include <unordered_set>
46#include <vector>
47
48#include <nlohmann/json_fwd.hpp> // gh#32 (v2.1.6) resume payload type
49
50namespace entropic {
51
63public:
66 static constexpr int MAX_DELEGATION_DEPTH = 2;
67
75 AgentEngine(const InferenceInterface& inference,
77 const CompactionConfig& compaction_config);
78
90 ent_decision_t (*start)(const ent_delegation_request_t*, void*)
91 = nullptr;
92 ent_decision_t (*complete)(const ent_delegation_result_t*, void*)
93 = nullptr;
94 void* user_data = nullptr;
95 };
96
105 std::vector<Message> run(std::vector<Message> messages,
106 const std::string& tier_override = "");
107
114
120 void set_tool_executor(const ToolExecutionInterface& tool_exec);
121
127 void set_tier_resolution(const TierResolutionInterface& tier_res);
128
135 void set_storage(const StorageInterface& storage);
136
142 void set_hooks(const HookInterface& hooks);
143
163 void set_project_dir(const std::filesystem::path& project_dir);
164
176 void set_stream_observer(TokenCallback observer, void* user_data);
177
193 void set_validation_provider(char* (*provider)(void*),
194 void* user_data);
195
212 ent_decision_t (*on_start)(const ent_delegation_request_t*, void*),
213 ent_decision_t (*on_complete)(const ent_delegation_result_t*, void*),
214 void* user_data);
215
230
243 void set_external_interrupt(void (*cb)(void* user_data),
244 void* user_data);
245
264 void run_loop(LoopContext& ctx, bool inherit_interrupt = false);
265
272
277 void interrupt();
278
283 void reset_interrupt();
284
289 void pause();
290
295 void cancel_pause();
296
303 std::pair<int, int> context_usage(
304 const std::vector<Message>& messages) const;
305
316 EngineCallbacks& callbacks() { return callbacks_; }
317
324 const LoopConfig& loop_config() const { return loop_config_; }
325
332 DirectiveProcessor& directive_processor() { return directive_processor_; }
333
345 LoopMetrics last_loop_metrics() const { return last_metrics_; }
346
359 std::unordered_map<std::string, LoopMetrics>
360 per_tier_metrics() const { return per_tier_metrics_; }
361
362 // ── Conversation state (v2.0.2) ─────────────────────────
363
369 void set_system_prompt(const std::string& prompt);
370
376 void set_session_logger(SessionLogger* logger);
377
388 std::vector<Message> run_turn(const std::string& input);
389
404 std::vector<Message> run_turn_as(const std::string& tier,
405 const std::string& input);
406
427 std::vector<Message> run_turn(std::vector<Message> new_messages);
428
440 void seed_system_prompt(const std::vector<Message>& new_messages);
441
456 std::vector<Message> run_drain_loop(std::string pending,
457 const std::string& tier_override);
458
470 void seed_system_prompt_for_tier(const std::string& tier);
471
483 bool prepare_next_turn(std::vector<Message>& pending);
484
498 int run_streaming(const std::string& input,
499 TokenCallback on_token,
500 void* user_data,
501 int* cancel_flag);
502
518 int run_streaming(std::vector<Message> new_messages,
519 TokenCallback on_token,
520 void* user_data,
521 int* cancel_flag);
522
527 void clear_conversation();
528
534 size_t message_count() const;
535
541 const std::vector<Message>& get_messages() const;
542
543 // ── Mid-generation user-message queue (gh#40, v2.1.10) ──
544
557 bool queue_user_message(const std::string& message);
558
564 size_t user_message_queue_depth() const;
565
572
585 void set_message_queue_capacity(int cap);
586
598 bool is_running() const { return running_flag_.load(); }
599
616 void (*observer)(const char*, size_t, void*),
617 void* user_data);
618
639 void (*observer)(int state, void* user_data),
640 void* user_data);
641
642 // ── Directive hooks (v2.0.2) ────────────────────────────
643
654
655 // ── Tier info (v2.0.2) ──────────────────────────────────
656
667 void set_tier_info(const std::string& name,
668 const ChildContextInfo& info);
669
680 bool has_tier(const std::string& name) const;
681
694 std::vector<std::string> get_tier_allowed_tools(
695 const std::string& name) const;
696
707 const std::string& tier_system_prompt(const std::string& name) const;
708
720 void set_relay_single_delegate(const std::string& name);
721
728 const std::unordered_map<std::string,
729 std::vector<std::string>>& rules);
730
742 const std::string& tier) const;
743
756 const LoopContext& ctx, const std::string& target) const;
757
774 const LoopContext& ctx, const std::string& target) const;
775
789 int64_t seconds_since_last_activity() const;
790
818 LoopContext& ctx, const Message& tool_result_msg) const;
819
842 void defang_meta_action_envelope(Message& msg) const;
843
857 CompactionManager& compaction_manager() { return compaction_manager_; }
858
859private:
871 void init_session_conversation(LoopContext& ctx);
872
883 void accumulate_run_metrics(LoopContext& ctx);
884
890 void loop(LoopContext& ctx);
891
897 void execute_iteration(LoopContext& ctx);
898
906 void evaluate_no_tool_decision(LoopContext& ctx,
907 const std::string& content,
908 const std::string& finish_reason);
909
918 bool handle_terminal_finish_reasons(
919 LoopContext& ctx, const std::string& finish_reason);
920
930 bool record_explicit_completion_failure(
931 LoopContext& ctx, const std::string& finish_reason);
932
945 void finalize_delegation_result(
946 LoopContext& ctx, const struct DelegationResult& result);
947
955 void relay_partial_result(LoopContext& ctx, const std::string& summary);
956
964 void log_relay_status(LoopContext& ctx,
965 const std::string& terminal_reason = {});
966
973 bool should_stop(const LoopContext& ctx) const;
974
989 static bool is_terminal_state(const LoopContext& ctx);
990
997 void set_state(LoopContext& ctx, AgentState state);
998
1004 void reinject_context_anchors(LoopContext& ctx);
1005
1010 void register_directive_handlers();
1011
1012 // ── Directive handlers ───────────────────────────────
1013 void dir_stop(LoopContext&, const Directive&, DirectiveResult&);
1014 void dir_tier_change(LoopContext&, const Directive&, DirectiveResult&);
1015 void dir_delegate(LoopContext&, const Directive&, DirectiveResult&);
1016 void dir_pipeline(LoopContext&, const Directive&, DirectiveResult&);
1017 void dir_complete(LoopContext&, const Directive&, DirectiveResult&);
1018 void dir_clear_todos(LoopContext&, const Directive&, DirectiveResult&);
1019 void dir_inject(LoopContext&, const Directive&, DirectiveResult&);
1020 void dir_prune(LoopContext&, const Directive&, DirectiveResult&);
1021 void dir_anchor(LoopContext&, const Directive&, DirectiveResult&);
1022 void dir_phase(LoopContext&, const Directive&, DirectiveResult&);
1023 void dir_notify(LoopContext&, const Directive&, DirectiveResult&);
1024
1031 std::pair<std::string, std::vector<ToolCall>> parse_tool_calls(
1032 const std::string& raw_content);
1033
1044 bool process_tool_results(LoopContext& ctx,
1045 const std::vector<ToolCall>& tool_calls);
1046
1047 // ── Delegation (v1.8.6) ──────────────────────────────
1048
1054 void execute_pending_delegation(LoopContext& ctx);
1055
1069 bool reject_delegation_if_guarded(LoopContext& ctx,
1070 const PendingDelegation& pending);
1071
1077 void execute_pending_pipeline(LoopContext& ctx);
1078
1087 bool should_auto_chain(const LoopContext& ctx,
1088 const std::string& finish_reason,
1089 const std::string& content);
1090
1099 bool try_auto_chain(LoopContext& ctx,
1100 const std::string& finish_reason,
1101 const std::string& content);
1102
1110 bool fire_pre_hook(entropic_hook_point_t point, int iteration);
1111
1125 void fire_post_generate_hook(GenerateResult& result,
1126 const std::string& tier,
1127 const std::vector<Message>& messages);
1128
1142 void capture_validation_feedback(LoopContext& ctx);
1143
1164 void dispatch_post_generate(LoopContext& ctx,
1165 GenerateResult& result);
1166
1180 void process_generation_result(LoopContext& ctx,
1181 GenerateResult& result);
1182
1194 void dispatch_pending_or_halt(LoopContext& ctx);
1195
1214 void charge_thinking_budget(LoopContext& ctx, size_t content_len,
1215 bool made_tool_call);
1216
1225 int budget_units_consumed(LoopContext& ctx, size_t content_len);
1226
1233 void nudge_budget_completion(LoopContext& ctx);
1234
1241 void hard_cut_budget(LoopContext& ctx);
1242
1255 bool fire_complete_hook(const std::string& summary,
1256 const LoopContext& ctx);
1257
1265 bool fire_delegate_pre_hook(const PendingDelegation& pending,
1266 int depth);
1267
1279 void fire_delegate_complete_hook(const std::string& target,
1280 bool success,
1281 const std::string& summary = "");
1282
1300 std::filesystem::path get_repo_dir();
1301
1322 SandboxManager* ensure_sandbox_manager();
1323
1341 bool resolve_resume_delegation(
1342 LoopContext& ctx,
1343 PendingDelegation& pending,
1344 std::vector<Message>& out_history);
1345
1360 bool fetch_resume_payload(
1361 LoopContext& ctx,
1362 const std::string& id,
1363 nlohmann::json& parsed);
1364
1381 DelegationResult run_pending_delegation(
1382 LoopContext& ctx,
1383 const PendingDelegation& pending,
1384 std::vector<Message> resume_history);
1385
1393 void fire_delegation_start(const LoopContext& ctx,
1394 const std::string& tier,
1395 const std::string& task);
1396
1404 void fire_delegation_complete(const LoopContext& ctx,
1405 const std::string& tier,
1406 const struct DelegationResult& result);
1407
1408 // ── Members ──────────────────────────────────────────
1409 LoopMetrics last_metrics_;
1410 std::unordered_map<std::string, LoopMetrics>
1411 per_tier_metrics_;
1412 InferenceInterface inference_;
1413 LoopConfig loop_config_;
1414 EngineCallbacks callbacks_;
1415 std::atomic<bool> interrupt_flag_{false};
1416 std::atomic<bool> pause_flag_{false};
1417 void (*external_interrupt_cb_)(void*) = nullptr;
1418 void* external_interrupt_data_ = nullptr;
1419 // ── Delegation callbacks (gh#29, v2.1.5) ────────────────
1424 DelegationCallbacks delegation_cb_;
1425 mutable std::mutex delegation_cb_mutex_;
1426 char* (*validation_provider_)(void*) = nullptr;
1427 void* validation_provider_data_ = nullptr;
1428 std::unordered_map<std::string, std::string> context_anchors_;
1429 ToolExecutionInterface tool_exec_;
1430 TierResolutionInterface tier_res_;
1431 StorageInterface storage_;
1432 DirectiveProcessor directive_processor_;
1433 TokenCounter token_counter_;
1434 CompactionManager compaction_manager_;
1435 ContextManager context_manager_;
1436 ResponseGenerator response_generator_;
1437 HookInterface hooks_;
1438 std::optional<std::filesystem::path> cached_repo_dir_;
1439 bool repo_dir_checked_ = false;
1440 std::filesystem::path project_dir_override_;
1441 std::optional<SandboxManager> sandbox_mgr_;
1442
1443 // ── Mid-generation user-message queue (gh#40, v2.1.10) ──
1444 mutable std::mutex queue_mutex_;
1445 std::deque<std::string> user_message_queue_;
1446 std::atomic<bool> running_flag_{false};
1449 std::atomic<int64_t> last_activity_epoch_s_{0};
1450 void (*queue_observer_)(const char*, size_t, void*) = nullptr;
1451 void* queue_observer_data_ = nullptr;
1454 void (*state_observer_)(int, void*) = nullptr;
1455 void* state_observer_data_ = nullptr;
1466 std::optional<std::string> pop_queued_user_message();
1467
1475 void fire_queue_consumed(const std::string& consumed, size_t remaining);
1476
1477 // ── Conversation state (v2.0.2) ─────────────────────────
1478 std::vector<Message> conversation_;
1479 std::string system_prompt_;
1480 SessionLogger* session_logger_ = nullptr;
1481
1482 // ── Pre-resolved tier data (v2.0.2) ─────────────────────
1483 std::unordered_map<std::string, ChildContextInfo> tier_info_;
1484 std::unordered_map<std::string, std::vector<std::string>> handoff_rules_;
1486 std::unordered_set<std::string> relay_single_delegate_tiers_;
1487
1493 void wire_internal_tier_resolution();
1494
1506 void apply_identity_overrides(LoopContext& ctx);
1507
1515 int resolve_max_iterations(const LoopContext& ctx) const;
1516
1524 int resolve_max_tool_calls(const LoopContext& ctx) const;
1525
1526 /* ── TierResolutionInterface trampolines (static — accept void* ud) ── */
1535 static ChildContextInfo tri_resolve_tier(
1536 const std::string& name, void* ud);
1545 static bool tri_tier_exists(
1546 const std::string& name, void* ud);
1555 static std::vector<std::string> tri_get_handoff_targets(
1556 const std::string& name, void* ud);
1566 static std::string tri_get_tier_param(
1567 const std::string& name, const std::string& param, void* ud);
1568};
1569
1570} // namespace entropic
Core agent execution engine.
Definition engine.h:62
void cancel_pause()
Cancel pause and interrupt completely.
Definition engine.cpp:1064
bool queue_user_message(const std::string &message)
Append a user message to the mid-gen queue.
Definition engine.cpp:3223
CompactionManager & compaction_manager()
Borrowed reference to the engine's built-in CompactionManager.
Definition engine.h:857
void set_validation_provider(char *(*provider)(void *), void *user_data)
Register a JSON provider for the validation block in ON_COMPLETE hook context.
Definition engine.cpp:263
bool is_delegation_cycle(const LoopContext &ctx, const std::string &target) const
Check whether pending delegation would close a cycle.
Definition engine.cpp:863
size_t user_message_queue_depth() const
Snapshot of the queue depth.
Definition engine.cpp:3242
std::vector< Message > run(std::vector< Message > messages, const std::string &tier_override="")
Run the engine on a set of messages.
Definition engine.cpp:386
void seed_system_prompt_for_tier(const std::string &tier)
Seed a tier's system prompt on an empty conversation (gh#99).
Definition engine.cpp:2918
void clear_user_message_queue()
Drop all queued user messages.
Definition engine.cpp:3252
const std::vector< Message > & get_messages() const
Get conversation messages (read-only).
Definition engine.cpp:3212
bool prepare_next_turn(std::vector< Message > &pending)
Pull the next queued user message into pending (gh#40).
Definition engine.cpp:3006
void set_callbacks(const EngineCallbacks &callbacks)
Set callback functions for loop events.
Definition engine.cpp:160
void seed_system_prompt(const std::vector< Message > &new_messages)
Prepend the configured system prompt if this turn needs it.
Definition engine.cpp:2984
std::vector< Message > run_turn(const std::string &input)
Run a single conversation turn (stateful).
Definition engine.cpp:2863
DelegationCallbacks delegation_callbacks_snapshot() const
Atomically snapshot the registered delegation callbacks.
Definition engine.cpp:251
void set_stream_observer(TokenCallback observer, void *user_data)
Set the global stream observer.
Definition engine.cpp:221
LoopMetrics last_loop_metrics() const
Get metrics from the most recent completed run.
Definition engine.h:345
const LoopConfig & loop_config() const
Get loop configuration.
Definition engine.h:324
void set_project_dir(const std::filesystem::path &project_dir)
Set the configured project directory (gh#31, v2.1.6).
Definition engine.cpp:2663
bool is_running() const
Whether a top-level run_turn is currently in progress.
Definition engine.h:598
DirectiveProcessor & directive_processor()
Get directive processor for external hook wiring.
Definition engine.h:332
std::vector< Message > run_drain_loop(std::string pending, const std::string &tier_override)
Shared drain loop for run_turn / run_turn_as (gh#99).
Definition engine.cpp:2940
void interrupt()
Interrupt the running loop (thread-safe).
Definition engine.cpp:1010
void pause()
Pause generation (thread-safe).
Definition engine.cpp:1054
bool is_delegation_repeat_blocked(const LoopContext &ctx, const std::string &target) const
Predicate: should this delegation be blocked because the same target has just failed too many times?...
Definition engine.cpp:879
void set_hooks(const HookInterface &hooks)
Set the hook dispatch interface.
Definition engine.cpp:203
void set_tier_resolution(const TierResolutionInterface &tier_res)
Set the tier resolution interface for delegation.
Definition engine.cpp:181
void run_loop(LoopContext &ctx, bool inherit_interrupt=false)
Run the engine loop on a pre-built context.
Definition engine.cpp:348
void set_session_logger(SessionLogger *logger)
Set session logger for model transcript logging.
Definition engine.cpp:2846
const TierResolutionInterface & tier_resolution() const
Get the tier resolution interface.
Definition engine.cpp:275
void set_storage(const StorageInterface &storage)
Set the storage interface for persistence.
Definition engine.cpp:192
std::unordered_map< std::string, LoopMetrics > per_tier_metrics() const
Per-tier aggregated metrics since engine start.
Definition engine.h:360
std::vector< std::string > get_tier_allowed_tools(const std::string &name) const
Return the allowed tool names registered for a tier (gh#121 regression).
Definition engine.cpp:3387
void clear_conversation()
Clear conversation history.
Definition engine.cpp:3191
std::vector< Message > run_turn_as(const std::string &tier, const std::string &input)
Run a single turn under a named tier's grammar/identity (gh#99).
Definition engine.cpp:2897
void set_queue_observer(void(*observer)(const char *, size_t, void *), void *user_data)
Register an observer that fires when a queued user message is consumed and seeded as the next turn.
Definition engine.cpp:3305
std::pair< int, int > context_usage(const std::vector< Message > &messages) const
Get context usage for a message list.
Definition engine.cpp:1077
bool fold_complete_into_assistant(LoopContext &ctx, const Message &tool_result_msg) const
gh#68 (v2.3.4): fold entropic.complete summary into the prior assistant message, suppressing the JSON...
Definition engine.cpp:894
void set_system_prompt(const std::string &prompt)
Set the system prompt for conversation state.
Definition engine.cpp:2836
void set_relay_single_delegate(const std::string &name)
Mark a tier as relay-on-single-delegate.
Definition engine.cpp:3414
void set_state_observer(void(*observer)(int state, void *user_data), void *user_data)
Register a persistent state-transition observer.
Definition engine.cpp:3323
size_t message_count() const
Get conversation message count.
Definition engine.cpp:3202
static constexpr int MAX_DELEGATION_DEPTH
Max delegation nesting depth (0=root, 1=child, 2=max).
Definition engine.h:66
void set_delegation_callbacks(ent_decision_t(*on_start)(const ent_delegation_request_t *, void *), ent_decision_t(*on_complete)(const ent_delegation_result_t *, void *), void *user_data)
Register delegation start/complete callbacks (gh#29, v2.1.5).
Definition engine.cpp:234
ToolExecutorHooks build_directive_hooks()
Build ToolExecutorHooks wired to this engine's DirectiveProcessor.
Definition engine.cpp:3339
void defang_meta_action_envelope(Message &msg) const
gh#88: reshape a meta-tool {"action":...} result so the model is not primed to parrot the call-shaped...
Definition engine.cpp:1444
void set_handoff_rules(const std::unordered_map< std::string, std::vector< std::string > > &rules)
Store handoff rules for tier delegation.
Definition engine.cpp:3425
void set_tier_info(const std::string &name, const ChildContextInfo &info)
Store pre-resolved tier context info.
Definition engine.cpp:3361
int run_streaming(const std::string &input, TokenCallback on_token, void *user_data, int *cancel_flag)
Run a streaming conversation turn (stateful).
Definition engine.cpp:3060
void set_message_queue_capacity(int cap)
Set the runtime capacity of the mid-gen queue.
Definition engine.cpp:3266
const std::string & tier_system_prompt(const std::string &name) const
A tier's resolved system prompt (gh#98).
Definition engine.cpp:3401
EngineCallbacks & callbacks()
Get mutable reference to engine callbacks.
Definition engine.h:316
void reset_interrupt()
Reset interrupt flag for next run.
Definition engine.cpp:1045
bool has_tier(const std::string &name) const
Whether a tier name is known (gh#99).
Definition engine.cpp:3375
void set_external_interrupt(void(*cb)(void *user_data), void *user_data)
Register a callback invoked alongside interrupt().
Definition engine.cpp:1034
bool tier_requires_explicit_completion(const std::string &tier) const
Check if a tier requires an explicit entropic.complete / entropic.delegate tool call to conclude its ...
Definition engine.cpp:842
int64_t seconds_since_last_activity() const
gh#35: seconds since the engine last serviced a run().
Definition engine.cpp:914
void set_tool_executor(const ToolExecutionInterface &tool_exec)
Set the tool execution interface.
Definition engine.cpp:170
Manages automatic context compaction.
Definition compaction.h:117
Processes tool directives via registry-based dispatch.
Definition directives.h:312
Manages session_model.log for raw streaming content.
Auto-compaction for context management.
Context management subsystem for the agentic loop.
Directive processing for tool-to-engine communication.
Types for the agentic loop engine.
Public C API for the Entropic inference engine.
ent_decision_t
Consumer decision returned from delegation callbacks.
Definition entropic.h:1091
entropic_hook_point_t
Hook points in the engine lifecycle.
Definition hooks.h:39
Hook dispatch interface injected into engine subsystems.
Function pointer types for core-to-inference communication.
Activate model on GPU (WARM → ACTIVE).
void(*)(const char *, size_t, void *) TokenCallback
Token callback type matching the C API signature.
AgentState
C++ enum class for agent execution states.
Response generation subsystem for the agentic loop.
Filesystem-based sandbox isolation for delegations.
Session model log — raw streaming transcript.
Streaming filter that strips a model family's reasoning blocks.
Request describing a delegation that is about to run.
Definition entropic.h:1105
Result of a finalized delegation, delivered to the consumer.
Definition entropic.h:1128
Grouped consumer-registered delegation callbacks (gh#29).
Definition engine.h:89
Resolved tier information for building child delegation contexts.
Auto-compaction configuration.
Definition config.h:742
Result returned from a child delegation loop.
Definition delegation.h:33
Callback function pointer types for engine events.
Configuration for the agentic loop.
Mutable state carried through the agentic loop.
Metrics collected during loop execution.
A message in a conversation.
Definition message.h:36
Storage interface for conversation persistence.
Tier resolution callbacks for delegation and auto-chain.
Tool execution interface for the engine.
Engine-level hooks called during tool processing.