lash/prompt_layer.rs
1use lash_core::{PromptContribution, PromptLayer, PromptSlot, PromptTemplate};
2
3/// Builder-agnostic prompt-layer mutation surface.
4///
5/// Every builder that owns a [`PromptLayer`] — [`crate::LashCoreBuilder`] (the
6/// runtime default prompt) and [`crate::SessionBuilder`] (the per-session
7/// prompt) — implements this trait by exposing its layer via
8/// [`prompt_layer_mut`](PromptLayerSink::prompt_layer_mut). The
9/// template/contribution/slot operations are then defined here exactly once,
10/// instead of being copy-pasted per builder.
11///
12/// (The per-turn `TurnBuilder` does not implement this trait: its prompt
13/// operations forward to the turn context, which owns that logic, so there is
14/// nothing to share.)
15pub trait PromptLayerSink: Sized {
16 /// Mutable access to the builder's prompt layer, created on first use.
17 fn prompt_layer_mut(&mut self) -> &mut PromptLayer;
18
19 /// Set the base prompt template.
20 fn prompt_template(mut self, template: PromptTemplate) -> Self {
21 self.prompt_layer_mut().template = Some(template);
22 self
23 }
24
25 /// Add a single prompt contribution to its slot.
26 fn prompt_contribution(mut self, contribution: PromptContribution) -> Self {
27 self.prompt_layer_mut().add_contribution(contribution);
28 self
29 }
30
31 /// Replace all contributions in a slot.
32 fn replace_prompt_slot(
33 mut self,
34 slot: PromptSlot,
35 contributions: impl IntoIterator<Item = PromptContribution>,
36 ) -> Self {
37 self.prompt_layer_mut().replace_slot(slot, contributions);
38 self
39 }
40
41 /// Clear all contributions from a slot.
42 fn clear_prompt_slot(mut self, slot: PromptSlot) -> Self {
43 self.prompt_layer_mut().clear_slot(slot);
44 self
45 }
46
47 /// Replace the whole prompt layer.
48 fn prompt_layer(mut self, layer: PromptLayer) -> Self {
49 *self.prompt_layer_mut() = layer;
50 self
51 }
52}