parser: add composite sort expressions

Adds parsing for weighted sort expressions like:
  sort:degree*0.5+isolation*0.3+recency(organize)*0.2

This fixes organize agent which uses composite scoring.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-12 03:02:32 -04:00
parent c79b415ada
commit c8280ae871

View file

@ -28,7 +28,7 @@ use std::collections::BTreeMap;
// Re-export engine types used by Query
pub use super::engine::{
Stage, Filter, Transform, Generator, SortField,
Stage, Filter, Transform, Generator, SortField, ScoreField,
Algorithm, AlgoStage, Cmp,
};
@ -92,7 +92,7 @@ peg::parser! {
/ "connectivity" { Stage::Transform(Transform::Connectivity) }
/ "dominating-set" { Stage::Transform(Transform::DominatingSet) }
// Pipeline syntax (colon-separated)
/ "sort:" f:field() { Stage::Transform(Transform::Sort(make_sort_field(&f, false))) }
/ "sort:" c:composite_sort() { Stage::Transform(Transform::Sort(c)) }
/ "limit:" n:integer() { Stage::Transform(Transform::Limit(n)) }
/ "select:" f:field_list_colon() { Stage::Transform(Transform::Select(f)) }
/ "type:" t:ident() { make_type_filter(&t) }
@ -111,6 +111,27 @@ peg::parser! {
/ "desc" { false }
/ { false } // default: descending
// Composite sort: degree*0.5+isolation*0.3+recency(organize)*0.2
// Falls back to simple field if no weighted terms found.
rule composite_sort() -> SortField
= t:score_term() ts:("+" t:score_term() { t })+ {
let mut terms = vec![t];
terms.extend(ts);
SortField::Composite(terms)
}
/ f:field() { make_sort_field(&f, false) }
rule score_term() -> (ScoreField, f64)
= "recency(" a:ident() ")" "*" w:number() { (ScoreField::Recency(a), w) }
/ f:score_field_name() "*" w:number() { (f, w) }
rule score_field_name() -> ScoreField
= "isolation" { ScoreField::Isolation }
/ "degree" { ScoreField::Degree }
/ "weight" { ScoreField::Weight }
/ "content-len" { ScoreField::ContentLen }
/ "priority" { ScoreField::Priority }
rule field_list_colon() -> Vec<String>
= f:field() fs:("," f:field() { f })* {
let mut v = vec![f];