claude-flow-novice
Version:
Claude Flow Novice - Advanced orchestration platform for multi-agent AI workflows with CFN Loop architecture Includes Local RuVector Accelerator and all CFN skills for complete functionality.
254 lines (208 loc) ⢠7.26 kB
Markdown
# Example: Backend Developer Fixes Existing Code with Errors
## Scenario
The agent encounters a Rust file with compilation errors during implementation of a user service.
## Step 1: Agent Identifies the Error
```bash
# Agent runs tests and sees errors
AGENT_ID="backend-developer-123"
FILE_PATH="src/services/user_service.rs"
cargo check
```
**Error Output:**
```
error[E0596]: cannot borrow `self.users` as mutable more than once at a time
--> src/services/user_service.rs:42:18
|
40 | let user = self.users.get(&user_id).cloned();
| --------- first mutable borrow occurs here
41 | if let Some(user) = user {
42 | self.users.insert(user_id, updated_user);
| ^^^^^^^^^ second mutable borrow occurs here
```
## Step 2: Agent Runs Fix Coordinator
```bash
./.claude/skills/cfn-cerebras-coordinator/fix-existing-code.sh \
--agent-id "$AGENT_ID" \
--file-path "src/services/user_service.rs" \
--error-message "cannot borrow self.users as mutable more than once" \
--test-command "cargo test user_service" \
--approach "tdd-fix"
```
## Step 3: System Analyzes and Queries Patterns
**Pattern Search Results:**
```
š Querying fix patterns for: rs errors - borrow checker
š Fix patterns from RuVector:
Pattern 1 (95% success rate):
// Rust Borrow Checker Fix:
// Problem: Multiple mutable borrows of HashMap
// Solution: Use entry() API or separate operations
Example fix:
// Instead of:
let user = self.users.get(&user_id);
self.users.insert(user_id, updated_user);
// Use entry API:
self.users.entry(user_id)
.and_modify(|existing| *existing = updated_user)
.or_insert(updated_user);
```
## Step 4: TDD Fix Approach
### 4a: Creates failing test that exposes the error
```rust
// tests/user_service_fix_test.rs
mod tests {
use super::*;
async fn test_update_user_borrow_issue() {
// Given
let mut service = UserService::new();
let user_id = 1;
let initial_user = User {
id: user_id,
email: "test@example.com".to_string(),
name: "Test User".to_string(),
};
// Insert initial user
service.users.insert(user_id, initial_user);
// When - This should trigger the borrow checker error
let updated_user = User {
id: user_id,
email: "updated@example.com".to_string(),
name: "Updated Name".to_string(),
};
let result = service.update_user(user_id, updated_user);
// Then - Should work without borrow errors
assert!(result.is_ok());
let retrieved = service.get_user(user_id).await.unwrap();
assert_eq!(retrieved.email, "updated@example.com");
}
}
```
### 4b: Generates fix using Cerebras
**Original problematic code:**
```rust
// Original code with borrow error
impl UserService {
pub async fn update_user(&mut self, user_id: u32, updated_user: User) -> Result<(), Error> {
// ERROR: Cannot borrow self.users twice
let user = self.users.get(&user_id).cloned();
if let Some(user) = user {
self.users.insert(user_id, updated_user); // Second borrow!
Ok(())
} else {
Err(Error::UserNotFound)
}
}
}
```
**Fixed code generated by Cerebras:**
```rust
impl UserService {
pub async fn update_user(&mut self, user_id: u32, updated_user: User) -> Result<(), Error> {
// Fixed: Use entry() API to avoid multiple borrows
use std::collections::hash_map::Entry;
match self.users.entry(user_id) {
Entry::Occupied(mut entry) => {
// User exists, update it
*entry.get_mut() = updated_user;
Ok(())
}
Entry::Vacant(_) => {
// User doesn't exist
Err(Error::UserNotFound)
}
}
}
}
```
## Step 5: Validation
```bash
cargo test user_service
```
**Output:**
```
test user_service::tests::test_update_user_borrow_issue ... ok
test user_service::tests::test_update_user_success ... ok
test user_service::tests::test_update_user_not_found ... ok
test result: ok. 3 passed; 0 failed
```
## Step 6: Learning Logged
```bash
# Agent logs the successful fix
./.claude/skills/cfn-cerebras-coordinator/feedback-logger.sh \
--agent-id "$AGENT_ID" \
--file-path "src/services/user_service.rs" \
--success true \
--learnings "Fixed borrow checker using HashMap entry() API pattern from RuVector. Pattern had 95% success rate."
```
**Stored in RuVector for future:**
```json
{
"type": "code_fix",
"file_type": "rust",
"error_type": "borrow_checker",
"solution": "Use entry() API for HashMap operations",
"success_rate": "100%",
"agent": "backend-developer-123",
"pattern_confidence": 0.95
}
```
## Alternative: Direct Fix Approach
If agent prefers direct fix:
```bash
./fix-existing-code.sh \
--agent-id "$AGENT_ID" \
--file-path "src/services/user_service.rs" \
--error-message "borrow checker error" \
--approach "direct-fix"
```
**Cerebras provides explanation:**
```
I've fixed the borrow checker error by replacing the problematic code:
The issue was:
```rust
let user = self.users.get(&user_id).cloned(); // First borrow
if let Some(user) = user {
self.users.insert(user_id, updated_user); // Second borrow - ERROR!
}
```
The fix uses the HashMap entry() API:
```rust
match self.users.entry(user_id) {
Entry::Occupied(mut entry) => {
*entry.get_mut() = updated_user; // Single borrow
Ok(())
}
Entry::Vacant(_) => Err(Error::UserNotFound)
}
```
This approach:
1. Avoids multiple borrows
2. Is more idiomatic Rust
3. Is slightly more performant (no cloning)
4. Follows the pattern with 95% success rate
```
## Benefits of This Approach
1. **Pattern-Based Learning**: The system learns which fixes work for specific errors
2. **Multiple Approaches**: TDD (test-first) or direct fix based on preference
3. **Context Awareness**: Uses existing code and imports to generate appropriate fixes
4. **Validation**: Automatically runs tests to verify the fix
5. **Knowledge Sharing**: Success patterns stored for all agents to use
## Complex Error Example: Async Channel
For a more complex error like async channel issues:
```bash
./fix-existing-code.sh \
--agent-id "$AGENT_ID" \
--file-path "src/workers/message_processor.rs" \
--error-message "async channel send error: RecvError" \
--context-files "src/models/message.rs" \
--approach "tdd-fix"
```
The system would:
1. Query for async channel fix patterns
2. Find common solutions (bounded channels, error handling)
3. Generate test that reproduces the error
4. Apply fix with proper error handling
5. Validate with concurrent tests
This shows how the Cerebras backend developer can efficiently fix errors by learning from past successful fixes stored in RuVector, while maintaining TDD discipline.