pub struct MessageFilters {Show 19 fields
pub role: Option<Role>,
pub kinds: Option<Vec<MessageKind>>,
pub field: Option<SearchField>,
pub argument_path: Option<String>,
pub providers: Option<Vec<Provider>>,
pub session_id: Option<String>,
pub path_prefix: Option<String>,
pub exclude_path_prefixes: Vec<String>,
pub exclude_session_ids: Vec<String>,
pub since: Option<DateTime<Utc>>,
pub until: Option<DateTime<Utc>>,
pub seq_from: Option<i64>,
pub seq_to: Option<i64>,
pub match_mode: MessageSearchMode,
pub tool: Option<String>,
pub no_compaction: bool,
pub session_kinds: Option<Vec<SessionKind>>,
pub limit: usize,
pub offset: usize,
/* private fields */
}Expand description
Filters for message-level search (messages search, analytics). Exact/regex limit == 0
means unlimited; fuzzy validation requires a positive finite page.
Fields§
§role: Option<Role>§kinds: Option<Vec<MessageKind>>Which semantic message classes to return. None selects the default set
(MessageKind::default_search_set): every class except HarnessNotice, which is
harness output rather than user or model prose.
PATTERN: this set is the ONLY mechanism for class selection. Adding a class means
adding a MessageKind variant, never an include_<class> boolean beside it. A
boolean was tried and reverted: it duplicated this field, needed tie-breaking code so
kind=harness_notice would not self-cancel into an empty result, and would have cost
one parameter per future class. Related: no_compaction below is legacy sugar that
resolves through MessageFilters::effective_kinds, and the is_compaction column in
db.rs is the same redundancy left in the schema.
field: Option<SearchField>The query searches only field: message content, canonical tool_name, or the canonical
tool argument selected by MessageFilters::argument_path.
argument_path: Option<String>RFC 6901 JSON pointer relative to the canonical tool-call args value.
providers: Option<Vec<Provider>>Restrict to these indexed session sources. None selects every provider; callers must not
construct Some(vec![]), because an empty public provider set is rejected before SQL.
session_id: Option<String>Exact session id, used after CLI commands resolve a user-supplied id/prefix.
This avoids substring filters accidentally merging sessions in messages get
and messages timeline.
path_prefix: Option<String>Restrict to messages whose session’s cwd, repo_root, or source transcript starts with this
prefix — the message-level analogue of SearchFilters::path_prefix. Applied
as a subquery against sessions in append_message_filters (the sessions
table is tiny relative to messages, so no dedicated index is needed).
exclude_path_prefixes: Vec<String>Exclude messages whose session’s cwd, repo_root, or source transcript path starts
with any of these normalized prefixes. Applied before limits/context expansion.
exclude_session_ids: Vec<String>Exclude exact session ids. Applied before limits/context expansion.
since: Option<DateTime<Utc>>§until: Option<DateTime<Utc>>§seq_from: Option<i64>Lower inclusive message sequence bound. Only meaningful within one or more scoped
sessions because seq is local to each session.
seq_to: Option<i64>Upper inclusive message sequence bound. Only meaningful within one or more scoped
sessions because seq is local to each session.
match_mode: MessageSearchModeHow the separate query string is interpreted. Literal is case-insensitive; Regex uses Rust regex syntax, and Fuzzy exhaustively scores the structurally filtered corpus with Nucleo’s fzf-style sequence score. Fuzzy is sequence matching, not edit distance.
tool: Option<String>Optional case-insensitive substring filter on a tool message’s canonical tool_name,
independent of field (e.g. exec matches Codex exec_command; edit matches Claude
Edit and MultiEdit).
no_compaction: boolDrop Compaction from the effective class set. Retained as a convenience over
MessageFilters::kinds; both resolve through MessageFilters::effective_kinds, so
they cannot disagree.
session_kinds: Option<Vec<SessionKind>>Which session classes the messages may come from. None = every class, matching what
messages search and list already return by default.
Mirrors SearchFilters::session_kinds rather than introducing a second spelling, and is
a SET for the reason stated on SessionKind: an include_subagent boolean was the
shape explicitly rejected there. Some(vec![]) selects no class and therefore matches
nothing, exactly as it already does on search.
corrections is the one operation that narrows this by default – see
crate::db::Db::find_corrections, which forces User for the same reason it forces
Role::User.
limit: usize§offset: usizeImplementations§
Source§impl MessageFilters
impl MessageFilters
Sourcepub fn validate(&self, query: &str) -> Result<()>
pub fn validate(&self, query: &str) -> Result<()>
Validate invariants shared by CLI, MCP, Rust, and language bindings.
query is interpreted according to MessageFilters::match_mode.
Sourcepub fn narrows_corpus(&self) -> bool
pub fn narrows_corpus(&self) -> bool
True when at least one structural predicate (role / provider / session ID / path / time window /
tool / no-compaction) restricts the SQL row set BEFORE content matching. regex, rank
and limit are NOT structural — they filter/order content, not the scanned corpus. Used
by search_messages to decide whether the content prefilter/scorer is worth querying:
when a structural filter already narrows the corpus to a small slice, a direct scan of
that slice beats intersecting against the whole-corpus trigram index.
Sourcepub fn effective_kinds(&self) -> Vec<MessageKind>
pub fn effective_kinds(&self) -> Vec<MessageKind>
The message classes this filter actually returns, resolved once so every caller and the
SQL builder agree. kinds names the set (defaulting to
MessageKind::default_search_set); no_compaction then removes one member. Because
both flow through here, a request cannot ask for a class and exclude it at the same
time, which is what made the earlier per-class booleans return silently empty results.
Sourcepub fn kind_predicate(&self) -> KindPredicate
pub fn kind_predicate(&self) -> KindPredicate
How to express class selection in SQL.
PATTERN: naming no set must EXCLUDE the unwanted classes, never INCLUDE the known ones.
An inclusion list silently drops any row whose stored kind is not a current enum
variant, which is every row written by an older or newer build. That was shipped
briefly and caught by a test inserting kind = 'message': it reintroduced the same
silent omission this filter exists to remove. An explicit set is an inclusion because
the caller named exactly what they want.
Trait Implementations§
Source§impl Clone for MessageFilters
impl Clone for MessageFilters
Source§impl Debug for MessageFilters
impl Debug for MessageFilters
Source§impl Default for MessageFilters
impl Default for MessageFilters
Source§impl<'de> Deserialize<'de> for MessageFilterswhere
MessageFilters: Default,
impl<'de> Deserialize<'de> for MessageFilterswhere
MessageFilters: Default,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for MessageFilters
impl RefUnwindSafe for MessageFilters
impl Send for MessageFilters
impl Sync for MessageFilters
impl Unpin for MessageFilters
impl UnsafeUnpin for MessageFilters
impl UnwindSafe for MessageFilters
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more