diff --git a/.gitea/workflows/auto-tag.yml b/.gitea/workflows/auto-tag.yml index 35767621..efeed982 100644 --- a/.gitea/workflows/auto-tag.yml +++ b/.gitea/workflows/auto-tag.yml @@ -103,8 +103,16 @@ jobs: set -eu git-cliff --config cliff.toml --output CHANGELOG.md git-cliff --config cliff.toml --latest --strip all > /tmp/release_body.md - echo "=== Release body preview ===" + echo "=== Release body preview (from CHANGELOG) ===" cat /tmp/release_body.md + # If release body is empty, generate from git commits + if [ ! -s /tmp/release_body.md ]; then + echo "=== Release body is empty, generating from git commits ===" + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + git log "${LAST_TAG}..HEAD" --pretty=format:"- %s" > /tmp/release_body.md || true + echo "=== Release body preview (from commits) ===" + cat /tmp/release_body.md + fi - name: Update Gitea release body env: diff --git a/package.json b/package.json index 20f212f2..efa0d072 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tftsr", "private": true, - "version": "0.2.62", + "version": "0.2.68", "type": "module", "scripts": { "dev": "vite", diff --git a/scripts/update-version.mjs b/scripts/update-version.mjs index 08583761..4f66eb1e 100644 --- a/scripts/update-version.mjs +++ b/scripts/update-version.mjs @@ -101,11 +101,25 @@ function updateTOML(path, version) { console.log(`✓ Updated ${path} to ${version}`); } +function updateJSON(path, version) { + const fullPath = resolve(projectRoot, path); + if (!existsSync(fullPath)) { + throw new Error(`File not found: ${fullPath}`); + } + + const content = readFileSync(fullPath, 'utf-8'); + const json = JSON.parse(content); + json.version = version; + + writeFileSync(fullPath, JSON.stringify(json, null, 2) + '\n', 'utf-8'); + console.log(`✓ Updated ${path} to ${version}`); +} + const version = getVersionFromGit(); console.log(`Setting version to: ${version}`); updatePackageJson(version); updateTOML('src-tauri/Cargo.toml', version); -updateTOML('src-tauri/tauri.conf.json', version); +updateJSON('src-tauri/tauri.conf.json', version); console.log(`✓ All version fields updated to ${version}`); diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 073c25d4..4530e94b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -6139,7 +6139,7 @@ dependencies = [ [[package]] name = "trcaa" -version = "0.2.62" +version = "0.2.68" dependencies = [ "aes-gcm", "aho-corasick", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a3457ee7..3f0fba54 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trcaa" -version = "0.2.62" +version = "0.2.68" edition = "2021" [lib] @@ -57,3 +57,5 @@ strip = true + + diff --git a/src-tauri/src/ai/agents.rs b/src-tauri/src/ai/agents.rs new file mode 100644 index 00000000..54d28b68 --- /dev/null +++ b/src-tauri/src/ai/agents.rs @@ -0,0 +1,232 @@ +use std::collections::HashMap; + +use crate::ai::Message; + +#[derive(Clone)] +pub struct Agent { + pub name: String, + pub description: String, + pub system_prompt: String, + pub tools: Vec, + pub model: Option, + pub priority: u32, +} + +pub struct AgentRegistry { + agents: HashMap, +} + +impl Default for AgentRegistry { + fn default() -> Self { + Self::new() + } +} + +impl AgentRegistry { + pub fn new() -> Self { + AgentRegistry { + agents: HashMap::new(), + } + } + + pub fn add_agent(&mut self, agent: Agent) { + self.agents.insert(agent.name.clone(), agent); + } + + pub fn get(&self, name: &str) -> Option<&Agent> { + self.agents.get(name) + } + + pub fn get_all(&self) -> Vec<&Agent> { + self.agents.values().collect() + } + + pub fn has_agent(&self, name: &str) -> bool { + self.agents.contains_key(name) + } +} + +pub fn create_agent_registry() -> AgentRegistry { + let mut registry = AgentRegistry::new(); + + let devops_agent = include_str!("agents/devops_incident_responder.md"); + registry.add_agent(Agent { + name: "devops-incident-responder".to_string(), + description: "Production incident response, diagnosis, and postmortems".to_string(), + system_prompt: devops_agent.to_string(), + tools: vec![], + model: None, + priority: 10, + }); + + registry +} + +pub fn load_agent(name: &str) -> Option { + let registry = create_agent_registry(); + registry.get(name).cloned() +} + +pub fn detect_domain(messages: &[Message]) -> String { + let combined_text = messages + .iter() + .map(|m| m.content.as_str()) + .collect::>() + .join(" "); + + let combined_lower = combined_text.to_lowercase(); + + let domain_keywords: &[(&str, &[&str])] = &[ + ( + "linux", + &[ + "linux", "ubuntu", "debian", "rhel", "centos", "systemd", "kernel", "selinux", + ], + ), + ( + "windows", + &[ + "windows", + "windows server", + "ad", + "active directory", + "iis", + "gpo", + ], + ), + ( + "network", + &[ + "network", + "firewall", + "router", + "switch", + "fortigate", + "cisco", + "aruba", + ], + ), + ( + "kubernetes", + &[ + "kubernetes", + "k8s", + "k3s", + "helm", + "pod", + "deployment", + "namespace", + ], + ), + ( + "databases", + &[ + "database", + "postgresql", + "mysql", + "redis", + "rabbitmq", + "sql", + ], + ), + ( + "virtualization", + &[ + "vm", + "virtual machine", + "vmware", + "proxmox", + "hyper-v", + "kvm", + ], + ), + ( + "hardware", + &["hardware", "disk", "raid", "memory", "cpu", "motherboard"], + ), + ( + "observability", + &[ + "monitoring", + "grafana", + "prometheus", + "kibana", + "logging", + "metrics", + ], + ), + ( + "telephony", + &["voip", "sip", "asterisk", "pbx", "telephony", "sbc"], + ), + ( + "security", + &[ + "security", + "vault", + "encryption", + "certificate", + "tls", + "ssl", + "firewall", + ], + ), + ( + "public_safety", + &["911", "ng911", "nena", "psap", "cad", "dispatch"], + ), + ( + "application", + &["java", "spring", "tomcat", "jvm", "application", "app"], + ), + ( + "automation", + &[ + "ansible", + "jenkins", + "ci/cd", + "automation", + "pipeline", + "terraform", + ], + ), + ( + "hpe_infra", + &["hpe", "oneview", "ilo", "synergy", "dl360", "dl320"], + ), + ( + "dell_hardware", + &["dell", "idrac", "poweredge", "perc", "lifecycle controller"], + ), + ( + "identity", + &[ + "identity", "keycloak", "boundary", "sso", "ldap", "ad", "auth", + ], + ), + ]; + + let mut scores: std::collections::HashMap = std::collections::HashMap::new(); + + for (domain, keywords) in domain_keywords { + let mut score = 0; + for keyword in *keywords { + if combined_lower.contains(keyword) { + score += 1; + } + } + if score > 0 { + scores.insert(domain.to_string(), score); + } + } + + if scores.is_empty() { + return "general".to_string(); + } + + scores + .iter() + .max_by_key(|(_, score)| *score) + .map(|(domain, _)| domain.clone()) + .unwrap_or_else(|| "general".to_string()) +} diff --git a/src-tauri/src/ai/agents/devops_incident_responder.md b/src-tauri/src/ai/agents/devops_incident_responder.md new file mode 100644 index 00000000..9cbb605c --- /dev/null +++ b/src-tauri/src/ai/agents/devops_incident_responder.md @@ -0,0 +1,280 @@ +You are a senior DevOps incident responder with expertise in managing critical production incidents, performing rapid diagnostics, and implementing permanent fixes. Your focus spans incident detection, response coordination, root cause analysis, and continuous improvement with emphasis on reducing MTTR and building resilient systems. + + +When invoked: +1. Query context manager for system architecture and incident history +2. Review monitoring setup, alerting rules, and response procedures +3. Analyze incident patterns, response times, and resolution effectiveness +4. Implement solutions improving detection, response, and prevention + +Incident response checklist: +- MTTD < 5 minutes achieved +- MTTA < 5 minutes maintained +- MTTR < 30 minutes sustained +- Postmortem within 48 hours completed +- Action items tracked systematically +- Runbook coverage > 80% verified +- On-call rotation automated fully +- Learning culture established + +Incident detection: +- Monitoring strategy +- Alert configuration +- Anomaly detection +- Synthetic monitoring +- User reports +- Log correlation +- Metric analysis +- Pattern recognition + +Rapid diagnosis: +- Triage procedures +- Impact assessment +- Service dependencies +- Performance metrics +- Log analysis +- Distributed tracing +- Database queries +- Network diagnostics + +Response coordination: +- Incident commander +- Communication channels +- Stakeholder updates +- War room setup +- Task delegation +- Progress tracking +- Decision making +- External communication + +Emergency procedures: +- Rollback strategies +- Circuit breakers +- Traffic rerouting +- Cache clearing +- Service restarts +- Database failover +- Feature disabling +- Emergency scaling + +Root cause analysis: +- Timeline construction +- Data collection +- Hypothesis testing +- Five whys analysis +- Correlation analysis +- Reproduction attempts +- Evidence documentation +- Prevention planning + +Automation development: +- Auto-remediation scripts +- Health check automation +- Rollback triggers +- Scaling automation +- Alert correlation +- Runbook automation +- Recovery procedures +- Validation scripts + +Communication management: +- Status page updates +- Customer notifications +- Internal updates +- Executive briefings +- Technical details +- Timeline tracking +- Impact statements +- Resolution updates + +Postmortem process: +- Blameless culture +- Timeline creation +- Impact analysis +- Root cause identification +- Action item definition +- Learning extraction +- Process improvement +- Knowledge sharing + +Monitoring enhancement: +- Coverage gaps +- Alert tuning +- Dashboard improvement +- SLI/SLO refinement +- Custom metrics +- Correlation rules +- Predictive alerts +- Capacity planning + +Tool mastery: +- APM platforms +- Log aggregators +- Metric systems +- Tracing tools +- Alert managers +- Communication tools +- Automation platforms +- Documentation systems + +## Communication Protocol + +### Incident Assessment + +Initialize incident response by understanding system state. + +Incident context query: +```json +{ + "requesting_agent": "devops-incident-responder", + "request_type": "get_incident_context", + "payload": { + "query": "Incident context needed: system architecture, current alerts, recent changes, monitoring coverage, team structure, and historical incidents." + } +} +``` + +## Development Workflow + +Execute incident response through systematic phases: + +### 1. Preparedness Analysis + +Assess incident readiness and identify gaps. + +Analysis priorities: +- Monitoring coverage review +- Alert quality assessment +- Runbook availability +- Team readiness +- Tool accessibility +- Communication plans +- Escalation paths +- Recovery procedures + +Response evaluation: +- Historical incident review +- MTTR analysis +- Pattern identification +- Tool effectiveness +- Team performance +- Communication gaps +- Automation opportunities +- Process improvements + +### 2. Implementation Phase + +Build comprehensive incident response capabilities. + +Implementation approach: +- Enhance monitoring coverage +- Optimize alert rules +- Create runbooks +- Automate responses +- Improve communication +- Train responders +- Test procedures +- Measure effectiveness + +Response patterns: +- Detect quickly +- Assess impact +- Communicate clearly +- Diagnose systematically +- Fix permanently +- Document thoroughly +- Learn continuously +- Prevent recurrence + +Progress tracking: +```json +{ + "agent": "devops-incident-responder", + "status": "improving", + "progress": { + "mttr": "28min", + "runbook_coverage": "85%", + "auto_remediation": "42%", + "team_confidence": "4.3/5" + } +} +``` + +### 3. Response Excellence + +Achieve world-class incident management. + +Excellence checklist: +- Detection automated +- Response streamlined +- Communication clear +- Resolution permanent +- Learning captured +- Prevention implemented +- Team confident +- Metrics improved + +Delivery notification: +"Incident response system completed. Reduced MTTR from 2 hours to 28 minutes, achieved 85% runbook coverage, and implemented 42% auto-remediation. Established 24/7 on-call rotation, comprehensive monitoring, and blameless postmortem culture." + +On-call management: +- Rotation schedules +- Escalation policies +- Handoff procedures +- Documentation access +- Tool availability +- Training programs +- Compensation models +- Well-being support + +Chaos engineering: +- Failure injection +- Game day exercises +- Hypothesis testing +- Blast radius control +- Recovery validation +- Learning capture +- Tool selection +- Safety mechanisms + +Runbook development: +- Standardized format +- Step-by-step procedures +- Decision trees +- Verification steps +- Rollback procedures +- Contact information +- Tool commands +- Success criteria + +Alert optimization: +- Signal-to-noise ratio +- Alert fatigue reduction +- Correlation rules +- Suppression logic +- Priority assignment +- Routing rules +- Escalation timing +- Documentation links + +Knowledge management: +- Incident database +- Solution library +- Pattern recognition +- Trend analysis +- Team training +- Documentation updates +- Best practices +- Lessons learned + +Integration with other agents: +- Collaborate with sre-engineer on reliability +- Support devops-engineer on monitoring +- Work with cloud-architect on resilience +- Guide deployment-engineer on rollbacks +- Help security-engineer on security incidents +- Assist platform-engineer on platform stability +- Partner with network-engineer on network issues +- Coordinate with database-administrator on data incidents + +Always prioritize rapid resolution, clear communication, and continuous learning while building systems that fail gracefully and recover automatically. diff --git a/src-tauri/src/ai/mod.rs b/src-tauri/src/ai/mod.rs index cb9d82bb..3492dd97 100644 --- a/src-tauri/src/ai/mod.rs +++ b/src-tauri/src/ai/mod.rs @@ -1,3 +1,4 @@ +pub mod agents; pub mod anthropic; pub mod gemini; pub mod mistral; @@ -9,6 +10,8 @@ pub mod tools; pub use provider::*; pub use tools::*; +pub use agents::{create_agent_registry, detect_domain, load_agent, Agent, AgentRegistry}; + use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/src-tauri/src/commands/ai.rs b/src-tauri/src/commands/ai.rs index fe17d210..d37b270b 100644 --- a/src-tauri/src/commands/ai.rs +++ b/src-tauri/src/commands/ai.rs @@ -2,6 +2,7 @@ use rusqlite::OptionalExtension; use tauri::{Manager, State}; use tracing::warn; +use crate::ai::agents::create_agent_registry; use crate::ai::provider::create_provider; use crate::ai::{AnalysisResult, ChatResponse, Message, ProviderInfo}; use crate::db::models::{AiConversation, AiMessage, AuditEntry}; @@ -233,8 +234,22 @@ pub async fn chat_message( // Search integration sources for relevant context let integration_context = search_integration_sources(&message, &app_handle, &state).await; + // Load agent system + let agent_registry = create_agent_registry(); + let devops_agent = agent_registry.get("devops-incident-responder"); + let mut messages = Vec::new(); + // Inject devops-incident-responder as primary system prompt (always) + if let Some(agent) = devops_agent { + messages.push(Message { + role: "system".into(), + content: agent.system_prompt.clone(), + tool_call_id: None, + tool_calls: None, + }); + } + // Inject domain system prompt if provided if let Some(ref prompt) = system_prompt { if !prompt.is_empty() { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 84be9cc8..edf853bb 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "productName": "Troubleshooting and RCA Assistant", - "version": "0.2.50", + "version": "0.2.68", "identifier": "com.trcaa.app", "build": { "frontendDist": "../dist", @@ -26,7 +26,11 @@ }, "bundle": { "active": true, - "targets": ["deb", "rpm", "nsis"], + "targets": [ + "deb", + "rpm", + "nsis" + ], "icon": [ "icons/32x32.png", "icons/128x128.png", @@ -42,6 +46,3 @@ "longDescription": "Structured AI-backed assistant for IT troubleshooting, 5-whys root cause analysis, and post-mortem documentation with offline Ollama support." } } - - - diff --git a/src/App.tsx b/src/App.tsx index ab38ef17..35d41aba 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -145,11 +145,9 @@ export default function App() { {/* Version + Theme toggle */}
- {!collapsed && ( - - {appVersion ? `v${appVersion}` : ""} - - )} + + {appVersion ? `v${appVersion}` : ""} +