pub trait ContextContributor: Send + Sync {
// Required method
fn contribute(&self, ctx: &ContributorContext<'_>) -> Option<Message>;
}Expand description
Produces an optional message to inject before the next turn’s model call.
Register an implementor on
BareLoop via
add_contributor. The loop
consults every registered contributor at the top of each turn, after
on_turn_start and before
the model is called. Returning None injects nothing for that turn.
The mechanism (when and how to inject) is the framework’s; the policy (what to inject) is the implementor’s. A typical implementor re-emits the agent’s goal or current plan every N turns to keep a small model on-task.
The returned message, if any, is pushed onto the conversation history (so
it is visible to compaction and subsequent turns) and reaches the model as
part of the next request. Returning a message with
Role::System lets providers route the
content correctly.
§Examples
use std::sync::atomic::{AtomicUsize, Ordering};
use loopctl::engine::{ContextContributor, ContributorContext};
use loopctl::message::{Message, MessagePart, Role};
// Re-emit a reminder every 5 turns.
struct GoalReminder { goal: String, calls: AtomicUsize }
impl ContextContributor for GoalReminder {
fn contribute(&self, ctx: &ContributorContext<'_>) -> Option<Message> {
let n = self.calls.fetch_add(1, Ordering::Relaxed);
if n > 0 && n % 5 == 0 {
Some(Message::new(Role::System, vec![
MessagePart::text(format!("Reminder: {}", self.goal)),
]))
} else {
None
}
}
}Required Methods§
Sourcefn contribute(&self, ctx: &ContributorContext<'_>) -> Option<Message>
fn contribute(&self, ctx: &ContributorContext<'_>) -> Option<Message>
Inspect the current turn count and conversation snapshot, returning a message to append to the conversation before the model call.
The returned message is pushed onto the conversation history in registration order alongside any other contributor messages, so it reaches the model this turn and persists into subsequent turns (subject to compaction).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".