Compare commits
2 Commits
v0.2.14
...
83a4b1243d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83a4b1243d | ||
|
|
0b36bec142 |
@@ -8,6 +8,56 @@ REPOS_CONFIG="$KUGETSU_DIR/repos.json"
|
|||||||
INDEX_FILE="$KUGETSU_DIR/index.json"
|
INDEX_FILE="$KUGETSU_DIR/index.json"
|
||||||
NOTIFICATIONS_FILE="$KUGETSU_DIR/notifications.json"
|
NOTIFICATIONS_FILE="$KUGETSU_DIR/notifications.json"
|
||||||
LOGS_DIR="$KUGETSU_DIR/logs"
|
LOGS_DIR="$KUGETSU_DIR/logs"
|
||||||
|
MAX_CONCURRENT_AGENTS="${MAX_CONCURRENT_AGENTS:-3}"
|
||||||
|
AGENT_COUNT_FILE="$KUGETSU_DIR/.agent_count"
|
||||||
|
AGENT_LOCK_FILE="$KUGETSU_DIR/.agent_lock"
|
||||||
|
|
||||||
|
acquire_agent_slot() {
|
||||||
|
local timeout="${1:-300}"
|
||||||
|
local waited=0
|
||||||
|
(
|
||||||
|
flock -w 1 200 || { echo "Error: Could not acquire lock" >&2; exit 1; }
|
||||||
|
local count
|
||||||
|
count=$(cat "$AGENT_COUNT_FILE" 2>/dev/null || echo 0)
|
||||||
|
if [ "$count" -lt "$MAX_CONCURRENT_AGENTS" ]; then
|
||||||
|
echo $((count + 1)) > "$AGENT_COUNT_FILE"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
) 200>"$AGENT_LOCK_FILE"
|
||||||
|
local result=$?
|
||||||
|
if [ $result -ne 0 ]; then
|
||||||
|
local count
|
||||||
|
count=$(cat "$AGENT_COUNT_FILE" 2>/dev/null || echo 0)
|
||||||
|
if [ $waited -ge $timeout ]; then
|
||||||
|
echo "Error: Timeout waiting for agent slot (max: $MAX_CONCURRENT_AGENTS, current: $count)" >&2
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
release_agent_slot() {
|
||||||
|
(
|
||||||
|
flock -w 1 200 || true
|
||||||
|
local count
|
||||||
|
count=$(cat "$AGENT_COUNT_FILE" 2>/dev/null || echo 0)
|
||||||
|
if [ "$count" -gt 0 ]; then
|
||||||
|
echo $((count - 1)) > "$AGENT_COUNT_FILE"
|
||||||
|
fi
|
||||||
|
) 200>"$AGENT_LOCK_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_with_limit() {
|
||||||
|
local log_file="$1"
|
||||||
|
shift
|
||||||
|
local cmd=("$@")
|
||||||
|
(
|
||||||
|
"${cmd[@]}" >> "$log_file" 2>&1
|
||||||
|
release_agent_slot
|
||||||
|
) &
|
||||||
|
disown
|
||||||
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat << 'EOF'
|
cat << 'EOF'
|
||||||
@@ -83,6 +133,7 @@ EOF
|
|||||||
|
|
||||||
ensure_dirs() {
|
ensure_dirs() {
|
||||||
mkdir -p "$SESSIONS_DIR"
|
mkdir -p "$SESSIONS_DIR"
|
||||||
|
[ -f "$AGENT_COUNT_FILE" ] || echo 0 > "$AGENT_COUNT_FILE"
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_worktree_dir() {
|
ensure_worktree_dir() {
|
||||||
@@ -502,7 +553,11 @@ cmd_delegate() {
|
|||||||
|
|
||||||
mkdir -p "$LOGS_DIR"
|
mkdir -p "$LOGS_DIR"
|
||||||
local log_file="$LOGS_DIR/delegate-$(date +%s).log"
|
local log_file="$LOGS_DIR/delegate-$(date +%s).log"
|
||||||
nohup opencode run --continue --session "$pm_session" "$message" > "$log_file" 2>&1 &
|
if ! acquire_agent_slot; then
|
||||||
|
echo "Error: Max concurrent agents ($MAX_CONCURRENT_AGENTS) reached. Try again later." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
nohup sh -c "opencode run --continue --session '$pm_session' '$message' >> '$log_file' 2>&1; release_agent_slot" > /dev/null 2>&1 &
|
||||||
disown
|
disown
|
||||||
echo "Delegated to PM agent (logged to $(basename "$log_file"))"
|
echo "Delegated to PM agent (logged to $(basename "$log_file"))"
|
||||||
}
|
}
|
||||||
@@ -796,11 +851,19 @@ cmd_start() {
|
|||||||
local before_set="${before_sessions//$'\n'/|}"
|
local before_set="${before_sessions//$'\n'/|}"
|
||||||
|
|
||||||
echo "Forking session for '$issue_ref'..."
|
echo "Forking session for '$issue_ref'..."
|
||||||
|
if ! acquire_agent_slot; then
|
||||||
|
echo "Error: Max concurrent agents ($MAX_CONCURRENT_AGENTS) reached. Try again later." >&2
|
||||||
|
remove_worktree_for_issue "$issue_ref"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
trap release_agent_slot EXIT
|
||||||
if [ "$DEBUG_MODE" = true ]; then
|
if [ "$DEBUG_MODE" = true ]; then
|
||||||
opencode run --fork --session "$base_session_id" "$message" --workdir "$worktree_path" 2>&1 | tee "$SESSIONS_DIR/$session_file.debug.log"
|
opencode run --fork --session "$base_session_id" "$message" --workdir "$worktree_path" 2>&1 | tee "$SESSIONS_DIR/$session_file.debug.log"
|
||||||
else
|
else
|
||||||
opencode run --fork --session "$base_session_id" "$message" --workdir "$worktree_path" 2>&1
|
opencode run --fork --session "$base_session_id" "$message" --workdir "$worktree_path" 2>&1
|
||||||
fi
|
fi
|
||||||
|
release_agent_slot
|
||||||
|
trap - EXIT
|
||||||
|
|
||||||
local after_sessions=$(opencode session list 2>/dev/null | grep -oP '^ses_\w+' | sort)
|
local after_sessions=$(opencode session list 2>/dev/null | grep -oP '^ses_\w+' | sort)
|
||||||
local new_session_id=""
|
local new_session_id=""
|
||||||
@@ -869,6 +932,11 @@ cmd_continue() {
|
|||||||
local worktree_path=$(python3 -c "import json; print(json.load(open('$session_path')).get('worktree_path', ''))" 2>/dev/null || echo "")
|
local worktree_path=$(python3 -c "import json; print(json.load(open('$session_path')).get('worktree_path', ''))" 2>/dev/null || echo "")
|
||||||
|
|
||||||
echo "Continuing session for '$session_name'..."
|
echo "Continuing session for '$session_name'..."
|
||||||
|
if ! acquire_agent_slot; then
|
||||||
|
echo "Error: Max concurrent agents ($MAX_CONCURRENT_AGENTS) reached. Try again later." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
trap release_agent_slot EXIT
|
||||||
if [ -n "$worktree_path" ] && [ -d "$worktree_path" ]; then
|
if [ -n "$worktree_path" ] && [ -d "$worktree_path" ]; then
|
||||||
echo "Using worktree: $worktree_path"
|
echo "Using worktree: $worktree_path"
|
||||||
if [ "$DEBUG_MODE" = true ]; then
|
if [ "$DEBUG_MODE" = true ]; then
|
||||||
@@ -883,6 +951,8 @@ cmd_continue() {
|
|||||||
opencode run --continue --session "$opencode_session_id" "$message"
|
opencode run --continue --session "$opencode_session_id" "$message"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
release_agent_slot
|
||||||
|
trap - EXIT
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_list() {
|
cmd_list() {
|
||||||
|
|||||||
@@ -444,7 +444,15 @@ echo ""
|
|||||||
|
|
||||||
# Test 27: delegate when pm-agent missing
|
# Test 27: delegate when pm-agent missing
|
||||||
echo "--- Test: delegate (pm-agent missing) ---"
|
echo "--- Test: delegate (pm-agent missing) ---"
|
||||||
setup_mock_base
|
cleanup
|
||||||
|
mkdir -p ~/.kugetsu/sessions ~/.kugetsu/worktrees
|
||||||
|
cat > ~/.kugetsu/index.json << EOF
|
||||||
|
{
|
||||||
|
"base": "$TEST_BASE_SESSION_ID",
|
||||||
|
"pm_agent": null,
|
||||||
|
"issues": {}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
OUTPUT=$($KUGETSU delegate "test" 2>&1 || true)
|
OUTPUT=$($KUGETSU delegate "test" 2>&1 || true)
|
||||||
if echo "$OUTPUT" | grep -q "Error: PM agent session"; then
|
if echo "$OUTPUT" | grep -q "Error: PM agent session"; then
|
||||||
pass "delegate fails when PM agent not found"
|
pass "delegate fails when PM agent not found"
|
||||||
@@ -486,6 +494,50 @@ else
|
|||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# Test 31: logs when no logs directory
|
||||||
|
echo "--- Test: logs (no directory) ---"
|
||||||
|
cleanup
|
||||||
|
OUTPUT=$($KUGETSU logs 2>&1 || true)
|
||||||
|
if echo "$OUTPUT" | grep -q "No logs found"; then
|
||||||
|
pass "logs returns 'No logs found' when directory missing"
|
||||||
|
else
|
||||||
|
fail "logs no directory: got '$OUTPUT', expected 'No logs found'"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 32: delegate is fire-and-forget (returns immediately)
|
||||||
|
echo "--- Test: delegate is fire-and-forget ---"
|
||||||
|
setup_mock_base
|
||||||
|
mkdir -p ~/.kugetsu/logs
|
||||||
|
START=$(date +%s)
|
||||||
|
OUTPUT=$($KUGETSU delegate "test fire-and-forget" 2>&1 || true)
|
||||||
|
END=$(date +%s)
|
||||||
|
ELAPSED=$((END - START))
|
||||||
|
if echo "$OUTPUT" | grep -q "Delegated to PM agent"; then
|
||||||
|
if [ $ELAPSED -lt 2 ]; then
|
||||||
|
pass "delegate returns immediately (< 2s)"
|
||||||
|
else
|
||||||
|
fail "delegate took ${ELAPSED}s, expected < 2s"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
fail "delegate output unexpected: $OUTPUT"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test 33: delegate creates log file
|
||||||
|
echo "--- Test: delegate creates log file ---"
|
||||||
|
setup_mock_base
|
||||||
|
LOG_COUNT_BEFORE=$(ls ~/.kugetsu/logs/*.log 2>/dev/null | wc -l)
|
||||||
|
$KUGETSU delegate "test log file" 2>&1 || true
|
||||||
|
sleep 1
|
||||||
|
LOG_COUNT_AFTER=$(ls ~/.kugetsu/logs/*.log 2>/dev/null | wc -l)
|
||||||
|
if [ $LOG_COUNT_AFTER -gt $LOG_COUNT_BEFORE ]; then
|
||||||
|
pass "delegate creates log file"
|
||||||
|
else
|
||||||
|
fail "delegate did not create log file"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
cleanup
|
cleanup
|
||||||
|
|
||||||
@@ -495,10 +547,147 @@ echo "Passed: $PASS"
|
|||||||
echo "Failed: $FAIL"
|
echo "Failed: $FAIL"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
ORIGINAL_FAIL=$FAIL
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# CONCURRENCY LIMIT TESTS
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Concurrency Limit Tests ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Create mock opencode that just sleeps briefly and exits
|
||||||
|
MOCK_OPENCODE="/tmp/mock_opencode.sh"
|
||||||
|
cat > "$MOCK_OPENCODE" << 'MOCK'
|
||||||
|
#!/bin/bash
|
||||||
|
sleep 0.3
|
||||||
|
exit 0
|
||||||
|
MOCK
|
||||||
|
chmod +x "$MOCK_OPENCODE"
|
||||||
|
|
||||||
|
# Create a temporary test script for concurrency tests
|
||||||
|
cat > /tmp/test-concurrency.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
KUGETSU="./skills/kugetsu/scripts/kugetsu"
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
test_cleanup() {
|
||||||
|
rm -rf ~/.kugetsu/sessions/* ~/.kugetsu/worktrees/* ~/.kugetsu/index.json ~/.kugetsu/logs/* ~/.kugetsu/.agent_count ~/.kugetsu/.agent_lock 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
pass() {
|
||||||
|
echo "PASS: $1"
|
||||||
|
PASS=$((PASS + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "FAIL: $1"
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_mock_sessions() {
|
||||||
|
mkdir -p ~/.kugetsu/sessions ~/.kugetsu/worktrees ~/.kugetsu/logs
|
||||||
|
cat > ~/.kugetsu/index.json << INDEX
|
||||||
|
{
|
||||||
|
"base": "ses_test_base_123",
|
||||||
|
"pm_agent": "ses_test_pm_456",
|
||||||
|
"issues": {}
|
||||||
|
}
|
||||||
|
INDEX
|
||||||
|
echo '{"type": "base", "opencode_session_id": "ses_test_base_123", "created_at": "2026-03-29T18:00:00+02:00", "state": "idle"}' > ~/.kugetsu/sessions/base.json
|
||||||
|
echo '{"type": "pm_agent", "opencode_session_id": "ses_test_pm_456", "created_at": "2026-03-29T18:00:00+02:00", "state": "idle"}' > ~/.kugetsu/sessions/pm-agent.json
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test C1: Agent count file is initialized to 0
|
||||||
|
echo "--- Test: agent count file initialized ---"
|
||||||
|
test_cleanup
|
||||||
|
mkdir -p ~/.kugetsu/sessions ~/.kugetsu/worktrees
|
||||||
|
$KUGETSU list > /dev/null 2>&1 || true
|
||||||
|
if [ -f ~/.kugetsu/.agent_count ]; then
|
||||||
|
COUNT=$(cat ~/.kugetsu/.agent_count)
|
||||||
|
if [ "$COUNT" = "0" ]; then
|
||||||
|
pass "agent count file initialized to 0"
|
||||||
|
else
|
||||||
|
fail "agent count file initialized to $COUNT, expected 0"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
fail "agent count file not created"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test C2: MAX_CONCURRENT_AGENTS defaults to 3
|
||||||
|
echo "--- Test: MAX_CONCURRENT_AGENTS defaults to 3 ---"
|
||||||
|
# Just grep for it and check if '3' appears
|
||||||
|
if grep -q 'MAX_CONCURRENT_AGENTS="3"' "$KUGETSU" || grep -q "MAX_CONCURRENT_AGENTS='3'" "$KUGETSU" || grep -q 'MAX_CONCURRENT_AGENTS=3' "$KUGETSU"; then
|
||||||
|
pass "MAX_CONCURRENT_AGENTS defaults to 3"
|
||||||
|
else
|
||||||
|
fail "MAX_CONCURRENT_AGENTS default not found"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Test C3: Agent count file increments and decrements properly
|
||||||
|
echo "--- Test: agent count increments and decrements ---"
|
||||||
|
test_cleanup
|
||||||
|
setup_mock_sessions
|
||||||
|
|
||||||
|
# Initialize count to 0
|
||||||
|
echo 0 > ~/.kugetsu/.agent_count
|
||||||
|
|
||||||
|
# Verify initial state
|
||||||
|
INITIAL=$(cat ~/.kugetsu/.agent_count)
|
||||||
|
if [ "$INITIAL" = "0" ]; then
|
||||||
|
pass "agent count starts at 0"
|
||||||
|
else
|
||||||
|
fail "agent count start was $INITIAL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# After any kugetsu command runs, count should be properly managed
|
||||||
|
$KUGETSU list > /dev/null 2>&1
|
||||||
|
|
||||||
|
# Verify count is still 0 (no slot leak)
|
||||||
|
AFTER=$(cat ~/.kugetsu/.agent_count)
|
||||||
|
if [ "$AFTER" = "0" ]; then
|
||||||
|
pass "agent count stays 0 after list (no leak)"
|
||||||
|
else
|
||||||
|
fail "agent count after list was $AFTER, expected 0"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
test_cleanup
|
||||||
|
rm -f /tmp/mock_opencode.sh 2>/dev/null || true
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Concurrency Test Summary ==="
|
||||||
|
echo "Passed: $PASS"
|
||||||
|
echo "Failed: $FAIL"
|
||||||
|
echo ""
|
||||||
|
|
||||||
if [ $FAIL -eq 0 ]; then
|
if [ $FAIL -eq 0 ]; then
|
||||||
echo "All tests passed!"
|
echo "All concurrency tests passed!"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo "Some tests failed."
|
echo "Some concurrency tests failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x /tmp/test-concurrency.sh
|
||||||
|
bash /tmp/test-concurrency.sh
|
||||||
|
CONCURRENCY_RESULT=$?
|
||||||
|
rm -f /tmp/test-concurrency.sh /tmp/mock_opencode.sh 2>/dev/null
|
||||||
|
|
||||||
|
# Combined result
|
||||||
|
if [ $ORIGINAL_FAIL -eq 0 ] && [ $CONCURRENCY_RESULT -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "=== ALL TESTS PASSED ==="
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "=== SOME TESTS FAILED ==="
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
Binary file not shown.
@@ -0,0 +1,29 @@
|
|||||||
|
# Parallel Capacity Test Report
|
||||||
|
|
||||||
|
**Generated:** 2026-03-31 03:51:30
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
| Agents | Duration | Success | Failed | Timeout | Avg Response | Peak Mem (MB) | Mem/Agent | Cost Score |
|
||||||
|
|--------|----------|---------|--------|---------|--------------|---------------|-----------|------------|
|
||||||
|
| 1 | 1.0s | 0 | 1 | 0 | 0.0s | 2177MB | -0.0MB | 0.00 |
|
||||||
|
| 2 | 1.0s | 0 | 2 | 0 | 0.0s | 2176MB | 0.3MB | 0.00 |
|
||||||
|
| 3 | 1.0s | 0 | 3 | 0 | 0.0s | 2175MB | 0.1MB | 0.00 |
|
||||||
|
| 5 | 1.0s | 0 | 5 | 0 | 0.0s | 2175MB | 0.0MB | 0.00 |
|
||||||
|
| 8 | 1.0s | 0 | 8 | 0 | 0.0s | 2176MB | 0.2MB | 0.00 |
|
||||||
|
|
||||||
|
## Cost Analysis
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Baseline Memory | 2177.1 MB |
|
||||||
|
| Avg Memory per Agent | 0.1 MB |
|
||||||
|
| Memory Limit | 1024 MB |
|
||||||
|
| Estimated Max Capacity | 9729 agents |
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
2. **Monitor closely:** 5+ agents
|
||||||
|
3. **Implement circuit breaker** when failure rate exceeds threshold
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Parallel Capacity Test Report
|
||||||
|
|
||||||
|
**Generated:** 2026-03-31 03:53:45
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
| Agents | Duration | Success | Failed | Timeout | Avg Response | Peak Mem (MB) | Mem/Agent | Cost Score |
|
||||||
|
|--------|----------|---------|--------|---------|--------------|---------------|-----------|------------|
|
||||||
|
| 1 | 7.0s | 1 | 0 | 0 | 6.3s | 2547MB | 363.6MB | 2.55 |
|
||||||
|
| 2 | 13.0s | 2 | 0 | 0 | 9.2s | 2889MB | 350.0MB | 9.11 |
|
||||||
|
| 3 | 8.0s | 3 | 0 | 0 | 6.3s | 3233MB | 340.4MB | 8.19 |
|
||||||
|
| 5 | 12.0s | 5 | 0 | 0 | 6.7s | 3912MB | 340.3MB | 20.49 |
|
||||||
|
| 8 | 62.5s | 0 | 0 | 8 | 60.0s | 4033MB | 223.4MB | 111.69 |
|
||||||
|
|
||||||
|
## Cost Analysis
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Baseline Memory | 2183.3 MB |
|
||||||
|
| Avg Memory per Agent | 323.5 MB |
|
||||||
|
| Memory Limit | 1024 MB |
|
||||||
|
| Estimated Max Capacity | 3 agents |
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
### Optimal Configuration
|
||||||
|
- **5 agents** achieved perfect success rate
|
||||||
|
- Average response time: 6.7s
|
||||||
|
- Peak CPU: 0.0%
|
||||||
|
- Peak Memory: 3911.8MB (0.0%)
|
||||||
|
- Memory per agent: 340.3MB
|
||||||
|
- Cost score: 20.49
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
1. **Recommended max agents:** 5 for stable operation
|
||||||
|
2. **Monitor closely:** 5+ agents
|
||||||
|
3. **Implement circuit breaker** when failure rate exceeds threshold
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Parallel Capacity Test Report
|
||||||
|
|
||||||
|
**Generated:** 2026-03-31 04:07:51
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
| Agents | Duration | Success | Failed | Timeout | Avg Response | Peak Mem (MB) | Mem/Agent | Cost Score |
|
||||||
|
|--------|----------|---------|--------|---------|--------------|---------------|-----------|------------|
|
||||||
|
| 1 | 1.0s | 0 | 1 | 0 | 0.0s | 2461MB | 1.9MB | 0.00 |
|
||||||
|
| 2 | 1.0s | 0 | 2 | 0 | 0.0s | 2464MB | 0.5MB | 0.00 |
|
||||||
|
| 3 | 1.0s | 0 | 3 | 0 | 0.0s | 2444MB | 0.1MB | 0.00 |
|
||||||
|
|
||||||
|
## Cost Analysis
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Baseline Memory | 2458.8 MB |
|
||||||
|
| Avg Memory per Agent | 0.8 MB |
|
||||||
|
| Memory Limit | 1024 MB |
|
||||||
|
| Estimated Max Capacity | 1241 agents |
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
2. **Monitor closely:** 5+ agents
|
||||||
|
3. **Implement circuit breaker** when failure rate exceeds threshold
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"agent_count": 1,
|
||||||
|
"total_duration": 1.0135109424591064,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 1,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.011479854583740234,
|
||||||
|
"stddev_response_time": 0,
|
||||||
|
"min_response_time": 0.011479854583740234,
|
||||||
|
"max_response_time": 0.011479854583740234,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2177.1123046875,
|
||||||
|
"avg_memory_mb": 2177.10498046875,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2177.1162109375,
|
||||||
|
"memory_per_agent_mb": -0.00390625,
|
||||||
|
"total_cost_score": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 2,
|
||||||
|
"total_duration": 1.0150294303894043,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 2,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.004192829132080078,
|
||||||
|
"stddev_response_time": 0.0006507473410082039,
|
||||||
|
"min_response_time": 0.0037326812744140625,
|
||||||
|
"max_response_time": 0.004652976989746094,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2175.671875,
|
||||||
|
"avg_memory_mb": 2175.529296875,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2175.13671875,
|
||||||
|
"memory_per_agent_mb": 0.267578125,
|
||||||
|
"total_cost_score": 0.0005431993436068297
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 3,
|
||||||
|
"total_duration": 1.0151348114013672,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 3,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.00410922368367513,
|
||||||
|
"stddev_response_time": 0.0005485598755713246,
|
||||||
|
"min_response_time": 0.0034792423248291016,
|
||||||
|
"max_response_time": 0.004481315612792969,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2175.234375,
|
||||||
|
"avg_memory_mb": 2175.171875,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2174.984375,
|
||||||
|
"memory_per_agent_mb": 0.08333333333333333,
|
||||||
|
"total_cost_score": 0.0002537837028503418
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 5,
|
||||||
|
"total_duration": 1.0233359336853027,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 5,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.003859806060791016,
|
||||||
|
"stddev_response_time": 0.0005061271938518695,
|
||||||
|
"min_response_time": 0.003265857696533203,
|
||||||
|
"max_response_time": 0.004559516906738281,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2174.8115234375,
|
||||||
|
"avg_memory_mb": 2174.765625,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2174.7197265625,
|
||||||
|
"memory_per_agent_mb": 0.018359375,
|
||||||
|
"total_cost_score": 9.393904078751803e-05
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 8,
|
||||||
|
"total_duration": 1.0180647373199463,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 8,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.0040419697761535645,
|
||||||
|
"stddev_response_time": 0.0005073540280823215,
|
||||||
|
"min_response_time": 0.0034415721893310547,
|
||||||
|
"max_response_time": 0.004962921142578125,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2175.9697265625,
|
||||||
|
"avg_memory_mb": 2175.328125,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2174.6826171875,
|
||||||
|
"memory_per_agent_mb": 0.160888671875,
|
||||||
|
"total_cost_score": 0.0013103606677614152
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"agent_count": 1,
|
||||||
|
"total_duration": 7.013643741607666,
|
||||||
|
"success_count": 1,
|
||||||
|
"failed_count": 0,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 6.2816431522369385,
|
||||||
|
"stddev_response_time": 0,
|
||||||
|
"min_response_time": 6.2816431522369385,
|
||||||
|
"max_response_time": 6.2816431522369385,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2546.8349609375,
|
||||||
|
"avg_memory_mb": 2439.7982177734375,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2183.2587890625,
|
||||||
|
"memory_per_agent_mb": 363.576171875,
|
||||||
|
"total_cost_score": 2.549993742468767
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 2,
|
||||||
|
"total_duration": 13.01965594291687,
|
||||||
|
"success_count": 2,
|
||||||
|
"failed_count": 0,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 9.241770267486572,
|
||||||
|
"stddev_response_time": 4.460840653831581,
|
||||||
|
"min_response_time": 6.087479591369629,
|
||||||
|
"max_response_time": 12.396060943603516,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2889.0400390625,
|
||||||
|
"avg_memory_mb": 2659.376727764423,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2189.068359375,
|
||||||
|
"memory_per_agent_mb": 349.98583984375,
|
||||||
|
"total_cost_score": 9.113390439316863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 3,
|
||||||
|
"total_duration": 8.017883539199829,
|
||||||
|
"success_count": 3,
|
||||||
|
"failed_count": 0,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 6.328219811121623,
|
||||||
|
"stddev_response_time": 1.4813371254887444,
|
||||||
|
"min_response_time": 4.74861478805542,
|
||||||
|
"max_response_time": 7.686349391937256,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 3233.111328125,
|
||||||
|
"avg_memory_mb": 2848.880425347222,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2211.83984375,
|
||||||
|
"memory_per_agent_mb": 340.423828125,
|
||||||
|
"total_cost_score": 8.188435823624488
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 5,
|
||||||
|
"total_duration": 12.039501190185547,
|
||||||
|
"success_count": 5,
|
||||||
|
"failed_count": 0,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 6.650626277923584,
|
||||||
|
"stddev_response_time": 2.765260504640065,
|
||||||
|
"min_response_time": 4.714812755584717,
|
||||||
|
"max_response_time": 11.523208379745483,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 3911.77734375,
|
||||||
|
"avg_memory_mb": 2996.949669471154,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2210.08203125,
|
||||||
|
"memory_per_agent_mb": 340.3390625,
|
||||||
|
"total_cost_score": 20.487562740176916
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 8,
|
||||||
|
"total_duration": 62.496517181396484,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 0,
|
||||||
|
"timeout_count": 8,
|
||||||
|
"avg_response_time": 60,
|
||||||
|
"stddev_response_time": 0.0,
|
||||||
|
"min_response_time": 60,
|
||||||
|
"max_response_time": 60,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 4033.01171875,
|
||||||
|
"avg_memory_mb": 3940.566368689904,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2245.8857421875,
|
||||||
|
"memory_per_agent_mb": 223.3907470703125,
|
||||||
|
"total_cost_score": 111.68914929955825
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"agent_count": 1,
|
||||||
|
"total_duration": 1.0171289443969727,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 1,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.005397796630859375,
|
||||||
|
"stddev_response_time": 0,
|
||||||
|
"min_response_time": 0.005397796630859375,
|
||||||
|
"max_response_time": 0.005397796630859375,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2460.7001953125,
|
||||||
|
"avg_memory_mb": 2459.75439453125,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2458.80859375,
|
||||||
|
"memory_per_agent_mb": 1.8916015625,
|
||||||
|
"total_cost_score": 0.001924002700485289
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 2,
|
||||||
|
"total_duration": 1.0177080631256104,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 2,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.004194378852844238,
|
||||||
|
"stddev_response_time": 0.0005352649760883542,
|
||||||
|
"min_response_time": 0.003815889358520508,
|
||||||
|
"max_response_time": 0.004572868347167969,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2464.1708984375,
|
||||||
|
"avg_memory_mb": 2463.69287109375,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2463.21484375,
|
||||||
|
"memory_per_agent_mb": 0.47802734375,
|
||||||
|
"total_cost_score": 0.0009729845642577857
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"agent_count": 3,
|
||||||
|
"total_duration": 1.016812801361084,
|
||||||
|
"success_count": 0,
|
||||||
|
"failed_count": 3,
|
||||||
|
"timeout_count": 0,
|
||||||
|
"avg_response_time": 0.00549777348836263,
|
||||||
|
"stddev_response_time": 0.0004058027330303703,
|
||||||
|
"min_response_time": 0.0052263736724853516,
|
||||||
|
"max_response_time": 0.0059642791748046875,
|
||||||
|
"peak_cpu_percent": 0.0,
|
||||||
|
"avg_cpu_percent": 0.0,
|
||||||
|
"peak_memory_mb": 2443.9794921875,
|
||||||
|
"avg_memory_mb": 2443.8232421875,
|
||||||
|
"peak_memory_percent": 0.0,
|
||||||
|
"avg_memory_percent": 0.0,
|
||||||
|
"peak_opencode_procs": 0,
|
||||||
|
"baseline_memory_mb": 2443.6669921875,
|
||||||
|
"memory_per_agent_mb": 0.10416666666666667,
|
||||||
|
"total_cost_score": 0.00031775400042533875
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
agents,duration,success,failed,timeout,avg_response,stddev,min_response,max_response,peak_cpu,avg_cpu,peak_mem_mb,avg_mem_mb,peak_mem_pct,avg_mem_pct,peak_procs,baseline_mem,mem_per_agent,cost_score
|
||||||
|
1,1.01,0,1,0,0.01,0.00,0.01,0.01,0.0,0.0,2177.1,2177.1,0.0,0.0,0,2177.1,-0.0,0.00
|
||||||
|
2,1.02,0,2,0,0.00,0.00,0.00,0.00,0.0,0.0,2175.7,2175.5,0.0,0.0,0,2175.1,0.3,0.00
|
||||||
|
3,1.02,0,3,0,0.00,0.00,0.00,0.00,0.0,0.0,2175.2,2175.2,0.0,0.0,0,2175.0,0.1,0.00
|
||||||
|
5,1.02,0,5,0,0.00,0.00,0.00,0.00,0.0,0.0,2174.8,2174.8,0.0,0.0,0,2174.7,0.0,0.00
|
||||||
|
8,1.02,0,8,0,0.00,0.00,0.00,0.00,0.0,0.0,2176.0,2175.3,0.0,0.0,0,2174.7,0.2,0.00
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
agents,duration,success,failed,timeout,avg_response,stddev,min_response,max_response,peak_cpu,avg_cpu,peak_mem_mb,avg_mem_mb,peak_mem_pct,avg_mem_pct,peak_procs,baseline_mem,mem_per_agent,cost_score
|
||||||
|
1,7.01,1,0,0,6.28,0.00,6.28,6.28,0.0,0.0,2546.8,2439.8,0.0,0.0,0,2183.3,363.6,2.55
|
||||||
|
2,13.02,2,0,0,9.24,4.46,6.09,12.40,0.0,0.0,2889.0,2659.4,0.0,0.0,0,2189.1,350.0,9.11
|
||||||
|
3,8.02,3,0,0,6.33,1.48,4.75,7.69,0.0,0.0,3233.1,2848.9,0.0,0.0,0,2211.8,340.4,8.19
|
||||||
|
5,12.04,5,0,0,6.65,2.77,4.71,11.52,0.0,0.0,3911.8,2996.9,0.0,0.0,0,2210.1,340.3,20.49
|
||||||
|
8,62.50,0,0,8,60.00,0.00,60.00,60.00,0.0,0.0,4033.0,3940.6,0.0,0.0,0,2245.9,223.4,111.69
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
agents,duration,success,failed,timeout,avg_response,stddev,min_response,max_response,peak_cpu,avg_cpu,peak_mem_mb,avg_mem_mb,peak_mem_pct,avg_mem_pct,peak_procs,baseline_mem,mem_per_agent,cost_score
|
||||||
|
1,1.02,0,1,0,0.01,0.00,0.01,0.01,0.0,0.0,2460.7,2459.8,0.0,0.0,0,2458.8,1.9,0.00
|
||||||
|
2,1.02,0,2,0,0.00,0.00,0.00,0.00,0.0,0.0,2464.2,2463.7,0.0,0.0,0,2463.2,0.5,0.00
|
||||||
|
3,1.02,0,3,0,0.01,0.00,0.01,0.01,0.0,0.0,2444.0,2443.8,0.0,0.0,0,2443.7,0.1,0.00
|
||||||
|
Reference in New Issue
Block a user