feat: multi-branch template scanning from git repo + manual template selection

- Rewrite template.rs to scan all remote branches via git commands
  (git fetch/branch -r/ls-tree/git show/git archive)
- Add manual template picker dropdown in CreateForm UI
- Remove sentence-transformers/embed.py from Dockerfile (separate container)
- Clean up Gitea API approach, use local git repo instead
- Add chat panel and sidebar layout improvements
This commit is contained in:
Fam Zheng
2026-03-07 16:24:56 +00:00
parent cb81d7eb41
commit 07f1f285b6
14 changed files with 1030 additions and 321 deletions

View File

@@ -22,7 +22,7 @@ pub struct ServiceInfo {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum AgentEvent {
NewRequirement { workflow_id: String, requirement: String },
NewRequirement { workflow_id: String, requirement: String, template_id: Option<String> },
Comment { workflow_id: String, content: String },
}
@@ -172,7 +172,7 @@ async fn agent_loop(
while let Some(event) = rx.recv().await {
match event {
AgentEvent::NewRequirement { workflow_id, requirement } => {
AgentEvent::NewRequirement { workflow_id, requirement, template_id: forced_template } => {
tracing::info!("Processing new requirement for workflow {}", workflow_id);
// Generate project title in background (don't block the agent loop)
{
@@ -206,18 +206,48 @@ async fn agent_loop(
.await;
// Template selection + workspace setup
let template_id = template::select_template(&llm, &requirement).await;
let template_id = if forced_template.is_some() {
tracing::info!("Using forced template: {:?}", forced_template);
forced_template
} else {
template::select_template(&llm, &requirement).await
};
let loaded_template = if let Some(ref tid) = template_id {
tracing::info!("Template selected for workflow {}: {}", workflow_id, tid);
let _ = tokio::fs::create_dir_all(&workdir).await;
if let Err(e) = template::apply_template(tid, &workdir).await {
tracing::error!("Failed to apply template {}: {}", tid, e);
}
match LoadedTemplate::load(tid).await {
Ok(t) => Some(t),
Err(e) => {
tracing::error!("Failed to load template {}: {}", tid, e);
None
if template::is_repo_template(tid) {
// Repo template: extract from git then load
match template::extract_repo_template(tid).await {
Ok(template_dir) => {
if let Err(e) = template::apply_template(&template_dir, &workdir).await {
tracing::error!("Failed to apply repo template {}: {}", tid, e);
}
match LoadedTemplate::load_from_dir(tid, &template_dir).await {
Ok(t) => Some(t),
Err(e) => {
tracing::error!("Failed to load repo template {}: {}", tid, e);
None
}
}
}
Err(e) => {
tracing::error!("Failed to extract repo template {}: {}", tid, e);
None
}
}
} else {
// Local built-in template
let template_dir = std::path::Path::new(template::templates_dir()).join(tid);
if let Err(e) = template::apply_template(&template_dir, &workdir).await {
tracing::error!("Failed to apply template {}: {}", tid, e);
}
match LoadedTemplate::load(tid).await {
Ok(t) => Some(t),
Err(e) => {
tracing::error!("Failed to load template {}: {}", tid, e);
None
}
}
}
} else {