1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! Placement strategies that determine final item ordering.
//!
//! A [`Placer`] receives the merged set of pinned and sliced items (with their
//! scores) and produces the final ordered list for the context window. Placement
//! is the last stage of the pipeline.
//!
//! # Strategies
//!
//! - [`ChronologicalPlacer`] — Orders items by ascending timestamp, preserving
//! natural temporal flow. Best for chat-style contexts.
//! - [`UShapedPlacer`] — Places highest-scored items at both edges (start and end)
//! of the context window, exploiting primacy/recency bias in LLMs.
//!
//! # Example
//!
//! ```
//! use cupel::{ContextItemBuilder, ScoredItem, ChronologicalPlacer, Placer};
//! use chrono::Utc;
//!
//! let items = vec![
//! ScoredItem {
//! item: ContextItemBuilder::new("first", 5)
//! .timestamp(Utc::now())
//! .build()?,
//! score: 0.5,
//! },
//! ];
//!
//! let placed = ChronologicalPlacer.place(&items);
//! assert_eq!(placed.len(), 1);
//! # Ok::<(), cupel::CupelError>(())
//! ```
pub use ChronologicalPlacer;
pub use UShapedPlacer;
use crate;
/// A placer determines the final presentation order of selected items.
///
/// Placers receive merged items (pinned + sliced) with their scores and
/// produce the final ordered list of context items.
///
/// # Examples
///
/// ```
/// use cupel::{ChronologicalPlacer, UShapedPlacer, Placer};
///
/// // All built-in placers implement this trait
/// let _: Box<dyn Placer> = Box::new(ChronologicalPlacer);
/// let _: Box<dyn Placer> = Box::new(UShapedPlacer);
/// ```