opi_coding_agent/
picker.rs1use std::path::Path;
5
6use opi_agent::session_branch::{BranchInfo, SessionTree};
7use opi_tui::select_list::SelectItem;
8
9pub fn model_picker_items(registry: &opi_ai::registry::ProviderRegistry) -> Vec<SelectItem> {
14 registry
15 .all_models()
16 .into_iter()
17 .map(|(provider_id, model)| SelectItem {
18 id: format!("{provider_id}:{}", model.id),
19 display: model.display_name.clone(),
20 metadata: provider_id.to_string(),
21 })
22 .collect()
23}
24
25pub fn model_picker_items_from_provider(
27 provider: &dyn opi_ai::provider::Provider,
28) -> Vec<SelectItem> {
29 let provider_id = provider.id();
30 provider
31 .models()
32 .iter()
33 .map(|model| SelectItem {
34 id: format!("{provider_id}:{}", model.id),
35 display: model.display_name.clone(),
36 metadata: provider_id.to_string(),
37 })
38 .collect()
39}
40
41pub fn branch_picker_items(tree: &SessionTree) -> Vec<SelectItem> {
43 let active_index = tree.active_branch_index();
44 tree.branches()
45 .iter()
46 .enumerate()
47 .map(|(index, branch)| branch_picker_item(branch, index, active_index == Some(index)))
48 .collect()
49}
50
51fn branch_picker_item(branch: &BranchInfo, index: usize, is_active: bool) -> SelectItem {
52 let name = if index == 0 && branch.fork_point.is_none() {
53 "Trunk".to_owned()
54 } else {
55 format!("Branch {}", index + 1)
56 };
57 let display = match branch.summary.as_deref() {
58 Some(summary) if !summary.is_empty() => format!("{name}: {summary}"),
59 _ => name,
60 };
61 let mut metadata = format!(
62 "{} entries, depth {}, tip {}",
63 branch.entry_count, branch.depth, branch.tip_id
64 );
65 if is_active {
66 metadata.push_str(", active");
67 }
68 SelectItem {
69 id: branch.tip_id.clone(),
70 display,
71 metadata,
72 }
73}
74
75pub fn session_picker_items(dir: &Path) -> Result<Vec<SelectItem>, std::io::Error> {
80 let sessions = crate::session_cli::list_sessions(dir).unwrap_or_default();
81 Ok(sessions
82 .into_iter()
83 .map(|s| {
84 let cwd_short = if s.cwd.len() > 40 {
85 let start = s.cwd.floor_char_boundary(s.cwd.len() - 37);
86 format!("...{}", &s.cwd[start..])
87 } else {
88 s.cwd
89 };
90 SelectItem {
91 id: s.id,
92 display: cwd_short,
93 metadata: s.timestamp,
94 }
95 })
96 .collect())
97}