feat(core): SearchOpts domain type for budget controls (fb-34)
3 optional knobs (max_tokens, snippet_chars, cursor); Default = all None = no enforcement (backwards-compat existing search behavior). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,7 +51,7 @@ pub use metadata::{
|
||||
};
|
||||
pub use search::{
|
||||
DocFilter, DocSummary, RetrievalDetail, SearchFilters, SearchHit,
|
||||
SearchMode, SearchQuery,
|
||||
SearchMode, SearchOpts, SearchQuery,
|
||||
};
|
||||
pub use answer::{
|
||||
Answer, AnswerCitation, AnswerRetrievalSummary, ModelRef, RefusalReason, TokenUsage,
|
||||
|
||||
@@ -96,6 +96,18 @@ pub struct DocSummary {
|
||||
pub chunker_version: ChunkerVersion,
|
||||
}
|
||||
|
||||
/// p9-fb-34: caller-supplied output budget knobs for `App::search_with_opts`.
|
||||
/// All `None` = no enforcement (existing behavior).
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct SearchOpts {
|
||||
/// chars/4 approximation of wire JSON token cost. None = no cap.
|
||||
pub max_tokens: Option<usize>,
|
||||
/// Per-hit snippet character cap. None = use config default.
|
||||
pub snippet_chars: Option<usize>,
|
||||
/// Opaque base64 cursor from a previous response. None = first page.
|
||||
pub cursor: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -135,4 +147,12 @@ mod tests {
|
||||
assert_eq!(v["indexed_at"], "2026-05-09T12:00:00Z");
|
||||
assert_eq!(v["stale"], true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_opts_default_is_all_none() {
|
||||
let opts = SearchOpts::default();
|
||||
assert!(opts.max_tokens.is_none());
|
||||
assert!(opts.snippet_chars.is_none());
|
||||
assert!(opts.cursor.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user