feat(bd-1cjx): add lore drift command for discussion divergence detection
Implement drift detection using cosine similarity between issue description embedding and chronological note embeddings. Sliding window (size 3) identifies topic drift points. Includes human and robot output formatters. New files: drift.rs, similarity.rs Closes: bd-1cjx
This commit is contained in:
60
src/main.rs
60
src/main.rs
@@ -12,17 +12,17 @@ use lore::cli::autocorrect::{self, CorrectionResult};
|
||||
use lore::cli::commands::{
|
||||
IngestDisplay, InitInputs, InitOptions, InitResult, ListFilters, MrListFilters,
|
||||
SearchCliFilters, SyncOptions, TimelineParams, open_issue_in_browser, open_mr_in_browser,
|
||||
print_count, print_count_json, print_doctor_results, print_dry_run_preview,
|
||||
print_dry_run_preview_json, print_embed, print_embed_json, print_event_count,
|
||||
print_event_count_json, print_generate_docs, print_generate_docs_json, print_ingest_summary,
|
||||
print_ingest_summary_json, print_list_issues, print_list_issues_json, print_list_mrs,
|
||||
print_list_mrs_json, print_search_results, print_search_results_json, print_show_issue,
|
||||
print_show_issue_json, print_show_mr, print_show_mr_json, print_stats, print_stats_json,
|
||||
print_sync, print_sync_json, print_sync_status, print_sync_status_json, print_timeline,
|
||||
print_timeline_json_with_meta, print_who_human, print_who_json, run_auth_test, run_count,
|
||||
run_count_events, run_doctor, run_embed, run_generate_docs, run_ingest, run_ingest_dry_run,
|
||||
run_init, run_list_issues, run_list_mrs, run_search, run_show_issue, run_show_mr, run_stats,
|
||||
run_sync, run_sync_status, run_timeline, run_who,
|
||||
print_count, print_count_json, print_doctor_results, print_drift_human, print_drift_json,
|
||||
print_dry_run_preview, print_dry_run_preview_json, print_embed, print_embed_json,
|
||||
print_event_count, print_event_count_json, print_generate_docs, print_generate_docs_json,
|
||||
print_ingest_summary, print_ingest_summary_json, print_list_issues, print_list_issues_json,
|
||||
print_list_mrs, print_list_mrs_json, print_search_results, print_search_results_json,
|
||||
print_show_issue, print_show_issue_json, print_show_mr, print_show_mr_json, print_stats,
|
||||
print_stats_json, print_sync, print_sync_json, print_sync_status, print_sync_status_json,
|
||||
print_timeline, print_timeline_json_with_meta, print_who_human, print_who_json, run_auth_test,
|
||||
run_count, run_count_events, run_doctor, run_drift, run_embed, run_generate_docs, run_ingest,
|
||||
run_ingest_dry_run, run_init, run_list_issues, run_list_mrs, run_search, run_show_issue,
|
||||
run_show_mr, run_stats, run_sync, run_sync_status, run_timeline, run_who,
|
||||
};
|
||||
use lore::cli::robot::{RobotMeta, strip_schemas};
|
||||
use lore::cli::{
|
||||
@@ -178,6 +178,22 @@ async fn main() {
|
||||
}
|
||||
Some(Commands::Timeline(args)) => handle_timeline(cli.config.as_deref(), args, robot_mode),
|
||||
Some(Commands::Who(args)) => handle_who(cli.config.as_deref(), args, robot_mode),
|
||||
Some(Commands::Drift {
|
||||
entity_type,
|
||||
iid,
|
||||
threshold,
|
||||
project,
|
||||
}) => {
|
||||
handle_drift(
|
||||
cli.config.as_deref(),
|
||||
&entity_type,
|
||||
iid,
|
||||
threshold,
|
||||
project.as_deref(),
|
||||
robot_mode,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Some(Commands::Stats(args)) => handle_stats(cli.config.as_deref(), args, robot_mode).await,
|
||||
Some(Commands::Embed(args)) => handle_embed(cli.config.as_deref(), args, robot_mode).await,
|
||||
Some(Commands::Sync(args)) => {
|
||||
@@ -2445,6 +2461,28 @@ fn handle_who(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_drift(
|
||||
config_override: Option<&str>,
|
||||
entity_type: &str,
|
||||
iid: i64,
|
||||
threshold: f32,
|
||||
project: Option<&str>,
|
||||
robot_mode: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let start = std::time::Instant::now();
|
||||
let config = Config::load(config_override)?;
|
||||
let effective_project = config.effective_project(project);
|
||||
let response = run_drift(&config, entity_type, iid, threshold, effective_project).await?;
|
||||
let elapsed_ms = start.elapsed().as_millis() as u64;
|
||||
|
||||
if robot_mode {
|
||||
print_drift_json(&response, elapsed_ms);
|
||||
} else {
|
||||
print_drift_human(&response);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn handle_list_compat(
|
||||
config_override: Option<&str>,
|
||||
|
||||
Reference in New Issue
Block a user