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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//! Slicing strategies that select items to fit within a token budget.
//!
//! A [`Slicer`] receives items pre-sorted by score (descending) from the Sort
//! stage and returns the subset that fits within the [`ContextBudget`]. Different
//! slicers optimize for different trade-offs between speed and optimality.
//!
//! # Strategies
//!
//! - [`GreedySlice`] — Selects by value density (score/token). Fast, good default.
//! - [`KnapsackSlice`] — 0/1 knapsack DP for globally optimal selection. Slower.
//! - [`QuotaSlice`] — Partitions budget by [`ContextKind`](crate::ContextKind) with require/cap quotas,
//! delegating per-kind selection to an inner slicer.
//!
//! # Example
//!
//! ```
//! use std::collections::HashMap;
//! use cupel::{ContextItemBuilder, ContextBudget, ScoredItem, GreedySlice, Slicer};
//!
//! let items = vec![
//! ScoredItem {
//! item: ContextItemBuilder::new("important", 100).build()?,
//! score: 0.9,
//! },
//! ScoredItem {
//! item: ContextItemBuilder::new("filler", 500).build()?,
//! score: 0.1,
//! },
//! ];
//!
//! let budget = ContextBudget::new(1000, 200, 0, HashMap::new(), 0.0)?;
//! let selected = GreedySlice.slice(&items, &budget)?;
//!
//! assert_eq!(selected.len(), 1);
//! assert_eq!(selected[0].content(), "important");
//! # Ok::<(), cupel::CupelError>(())
//! ```
pub use CountConstrainedKnapsackSlice;
pub use ;
pub use GreedySlice;
pub use KnapsackSlice;
pub use ;
use crateCupelError;
use crate;
// ── QuotaPolicy abstraction ──────────────────────────────────────────────────
/// Whether a quota constraint is expressed as a percentage of the token budget
/// or as an absolute item count.
/// A single per-kind quota constraint describing the require and cap thresholds.
///
/// For [`QuotaConstraintMode::Percentage`], `require` and `cap` are percentages (0–100).
/// For [`QuotaConstraintMode::Count`], they are absolute item counts (as `f64`).
/// A trait for slicers that expose per-kind quota constraints.
///
/// Implemented by [`QuotaSlice`] (percentage-based) and [`CountQuotaSlice`]
/// (count-based). The returned constraints are consumed by analytics functions
/// such as `quota_utilization` to compute how fully each kind's quota is used.
/// A slicer selects items from a sorted list to fit within a token budget.
///
/// Slicers receive items pre-sorted by score descending (from the Sort stage)
/// and return the subset of items that fits within the budget.
///
/// # Examples
///
/// ```
/// use cupel::{GreedySlice, KnapsackSlice, Slicer};
///
/// // All built-in slicers implement this trait
/// let _: Box<dyn Slicer> = Box::new(GreedySlice);
/// let _: Box<dyn Slicer> = Box::new(KnapsackSlice::new(1)?);
/// # Ok::<(), cupel::CupelError>(())
/// ```