Skip to main content

pleiades_agent_git/
summary.rs

1use std::path::PathBuf;
2use std::sync::Arc;
3
4use pleiades_agent_core::error::Error;
5use pleiades_agent_core::provider::Provider;
6use pleiades_agent_prompts::BuiltinPrompts;
7
8use crate::common::{generate_from_diff, git_diff, git_output};
9
10/// Generate a pull-request description from commits and a diff.
11pub struct PrSummaryGenerator {
12    provider: Arc<dyn Provider>,
13    model: String,
14    repository: PathBuf,
15    base: String,
16    title: Option<String>,
17}
18
19impl PrSummaryGenerator {
20    pub fn new(provider: Arc<dyn Provider>, model: impl Into<String>) -> Self {
21        Self {
22            provider,
23            model: model.into(),
24            repository: PathBuf::from("."),
25            base: "HEAD~1".to_string(),
26            title: None,
27        }
28    }
29
30    pub fn with_repository(mut self, repository: impl Into<PathBuf>) -> Self {
31        self.repository = repository.into();
32        self
33    }
34
35    pub fn base(mut self, base: impl Into<String>) -> Self {
36        self.base = base.into();
37        self
38    }
39
40    pub fn title(mut self, title: Option<String>) -> Self {
41        self.title = title;
42        self
43    }
44
45    pub async fn generate(&self) -> Result<String, Error> {
46        let range = format!("{}..HEAD", self.base);
47        let diff = git_diff(&self.repository, &["diff", "--no-ext-diff", &range]).await?;
48        let commits = git_output(&self.repository, &["log", "--format=- %s", &range]).await?;
49        let context = format!("Commits:\n{commits}\n\nDiff:\n{diff}");
50        generate_from_diff(
51            self.provider.as_ref(),
52            &self.model,
53            BuiltinPrompts::pr_summary(),
54            &context,
55            self.title.as_deref(),
56        )
57        .await
58    }
59}