@the-bearded-bear/claude-craft 3.0.3-next.d0d2746 → 3.1.0-next.a356bbd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dev/i18n/de/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/de/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/en/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/en/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/es/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/es/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/fr/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/fr/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/pt/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/pt/Common/commands/ralph-run.md +171 -0
- package/Tools/Ralph/README.md +303 -0
- package/Tools/Ralph/lib/checkpoint.sh +238 -0
- package/Tools/Ralph/lib/circuit-breaker.sh +172 -0
- package/Tools/Ralph/lib/dod-validator.sh +306 -0
- package/Tools/Ralph/lib/loop.sh +232 -0
- package/Tools/Ralph/lib/session.sh +234 -0
- package/Tools/Ralph/ralph.sh +491 -0
- package/Tools/Ralph/templates/ralph.yml.template +178 -0
- package/Tools/i18n/ralph/de.sh +147 -0
- package/Tools/i18n/ralph/en.sh +147 -0
- package/Tools/i18n/ralph/es.sh +147 -0
- package/Tools/i18n/ralph/fr.sh +147 -0
- package/Tools/i18n/ralph/pt.sh +147 -0
- package/cli/index.js +90 -0
- package/package.json +1 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Ralph Wiggum - Git Checkpointing Module
|
|
4
|
+
# Creates git checkpoints for recovery and history tracking
|
|
5
|
+
# =============================================================================
|
|
6
|
+
|
|
7
|
+
# Checkpointing configuration
|
|
8
|
+
CP_ENABLED="${CP_ENABLED:-true}"
|
|
9
|
+
CP_ASYNC="${CP_ASYNC:-true}"
|
|
10
|
+
CP_BRANCH_PREFIX="${CP_BRANCH_PREFIX:-ralph/}"
|
|
11
|
+
CP_COMMIT_TEMPLATE="${CP_COMMIT_TEMPLATE:-checkpoint: Ralph iteration {iteration}}"
|
|
12
|
+
|
|
13
|
+
# =============================================================================
|
|
14
|
+
# Initialization
|
|
15
|
+
# =============================================================================
|
|
16
|
+
|
|
17
|
+
init_checkpointing() {
|
|
18
|
+
# Check if git is available
|
|
19
|
+
if ! command -v git &> /dev/null; then
|
|
20
|
+
CP_ENABLED=false
|
|
21
|
+
print_verbose "Git not found, checkpointing disabled"
|
|
22
|
+
return 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Check if we're in a git repository
|
|
26
|
+
if ! git rev-parse --git-dir &> /dev/null; then
|
|
27
|
+
CP_ENABLED=false
|
|
28
|
+
print_verbose "Not in a git repository, checkpointing disabled"
|
|
29
|
+
return 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Load config if available
|
|
33
|
+
if [[ -n "$CONFIG_FILE" && -f "$CONFIG_FILE" ]] && command -v yq &> /dev/null; then
|
|
34
|
+
local enabled=$(yq e '.checkpointing.enabled // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
35
|
+
[[ "$enabled" == "false" ]] && CP_ENABLED=false
|
|
36
|
+
|
|
37
|
+
local async=$(yq e '.checkpointing.async // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
38
|
+
[[ "$async" == "false" ]] && CP_ASYNC=false
|
|
39
|
+
|
|
40
|
+
local prefix=$(yq e '.checkpointing.branch_prefix // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
41
|
+
[[ -n "$prefix" ]] && CP_BRANCH_PREFIX="$prefix"
|
|
42
|
+
|
|
43
|
+
local template=$(yq e '.checkpointing.commit_message_template // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
44
|
+
[[ -n "$template" ]] && CP_COMMIT_TEMPLATE="$template"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
print_verbose "Checkpointing initialized:"
|
|
48
|
+
print_verbose " - Enabled: $CP_ENABLED"
|
|
49
|
+
print_verbose " - Async: $CP_ASYNC"
|
|
50
|
+
print_verbose " - Branch prefix: $CP_BRANCH_PREFIX"
|
|
51
|
+
|
|
52
|
+
return 0
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# =============================================================================
|
|
56
|
+
# Create Checkpoint
|
|
57
|
+
# =============================================================================
|
|
58
|
+
|
|
59
|
+
create_checkpoint() {
|
|
60
|
+
local session_id="$1"
|
|
61
|
+
local iteration="$2"
|
|
62
|
+
|
|
63
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
64
|
+
return 0
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Check for changes to commit
|
|
68
|
+
if [[ -z "$(git status --porcelain 2>/dev/null)" ]]; then
|
|
69
|
+
print_verbose "No changes to checkpoint"
|
|
70
|
+
return 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Generate commit message
|
|
74
|
+
local commit_msg="${CP_COMMIT_TEMPLATE/\{iteration\}/$iteration}"
|
|
75
|
+
commit_msg="${commit_msg/\{session_id\}/$session_id}"
|
|
76
|
+
|
|
77
|
+
if [[ "$CP_ASYNC" == "true" ]]; then
|
|
78
|
+
# Run checkpoint in background
|
|
79
|
+
_create_checkpoint_async "$session_id" "$iteration" "$commit_msg" &
|
|
80
|
+
print_verbose "${MSG_CHECKPOINT_CREATING} (async)"
|
|
81
|
+
else
|
|
82
|
+
# Run checkpoint synchronously
|
|
83
|
+
_create_checkpoint_sync "$session_id" "$iteration" "$commit_msg"
|
|
84
|
+
fi
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# =============================================================================
|
|
88
|
+
# Synchronous Checkpoint
|
|
89
|
+
# =============================================================================
|
|
90
|
+
|
|
91
|
+
_create_checkpoint_sync() {
|
|
92
|
+
local session_id="$1"
|
|
93
|
+
local iteration="$2"
|
|
94
|
+
local commit_msg="$3"
|
|
95
|
+
|
|
96
|
+
print_verbose "${MSG_CHECKPOINT_CREATING}"
|
|
97
|
+
|
|
98
|
+
# Stage all changes
|
|
99
|
+
git add -A 2>/dev/null
|
|
100
|
+
|
|
101
|
+
# Create commit
|
|
102
|
+
local commit_hash
|
|
103
|
+
commit_hash=$(git commit -m "$commit_msg" 2>/dev/null && git rev-parse --short HEAD)
|
|
104
|
+
|
|
105
|
+
if [[ -n "$commit_hash" ]]; then
|
|
106
|
+
print_verbose "${MSG_CHECKPOINT_CREATED}: $commit_hash"
|
|
107
|
+
log_session "$session_id" "INFO" "Checkpoint created: $commit_hash"
|
|
108
|
+
else
|
|
109
|
+
print_verbose "${MSG_CHECKPOINT_FAILED}"
|
|
110
|
+
log_session "$session_id" "WARN" "Checkpoint failed"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# =============================================================================
|
|
115
|
+
# Asynchronous Checkpoint
|
|
116
|
+
# =============================================================================
|
|
117
|
+
|
|
118
|
+
_create_checkpoint_async() {
|
|
119
|
+
local session_id="$1"
|
|
120
|
+
local iteration="$2"
|
|
121
|
+
local commit_msg="$3"
|
|
122
|
+
|
|
123
|
+
# Create a lock file to prevent concurrent checkpoints
|
|
124
|
+
local lock_file="/tmp/ralph-checkpoint-$session_id.lock"
|
|
125
|
+
|
|
126
|
+
# Try to acquire lock
|
|
127
|
+
if ! mkdir "$lock_file" 2>/dev/null; then
|
|
128
|
+
# Another checkpoint is in progress
|
|
129
|
+
return 0
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# Cleanup function
|
|
133
|
+
cleanup() {
|
|
134
|
+
rmdir "$lock_file" 2>/dev/null
|
|
135
|
+
}
|
|
136
|
+
trap cleanup EXIT
|
|
137
|
+
|
|
138
|
+
# Stage all changes
|
|
139
|
+
git add -A 2>/dev/null
|
|
140
|
+
|
|
141
|
+
# Create commit
|
|
142
|
+
git commit -m "$commit_msg" 2>/dev/null
|
|
143
|
+
|
|
144
|
+
# Log result
|
|
145
|
+
if [[ $? -eq 0 ]]; then
|
|
146
|
+
local commit_hash=$(git rev-parse --short HEAD 2>/dev/null)
|
|
147
|
+
log_session "$session_id" "INFO" "Async checkpoint created: $commit_hash"
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
cleanup
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
# =============================================================================
|
|
154
|
+
# Restore from Checkpoint
|
|
155
|
+
# =============================================================================
|
|
156
|
+
|
|
157
|
+
restore_checkpoint() {
|
|
158
|
+
local session_id="$1"
|
|
159
|
+
local commit_hash="$2"
|
|
160
|
+
|
|
161
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
162
|
+
print_error "Checkpointing is disabled"
|
|
163
|
+
return 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
print_info "${MSG_CHECKPOINT_RESTORING}"
|
|
167
|
+
|
|
168
|
+
# Verify commit exists
|
|
169
|
+
if ! git cat-file -e "$commit_hash" 2>/dev/null; then
|
|
170
|
+
print_error "Commit not found: $commit_hash"
|
|
171
|
+
return 1
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Create a backup branch of current state
|
|
175
|
+
local backup_branch="ralph-backup-$(date +%s)"
|
|
176
|
+
git branch "$backup_branch" 2>/dev/null
|
|
177
|
+
|
|
178
|
+
# Reset to the checkpoint
|
|
179
|
+
if git reset --hard "$commit_hash" 2>/dev/null; then
|
|
180
|
+
print_success "${MSG_CHECKPOINT_RESTORED}"
|
|
181
|
+
log_session "$session_id" "INFO" "Restored to checkpoint: $commit_hash (backup: $backup_branch)"
|
|
182
|
+
return 0
|
|
183
|
+
else
|
|
184
|
+
print_error "${MSG_CHECKPOINT_FAILED}"
|
|
185
|
+
return 1
|
|
186
|
+
fi
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# =============================================================================
|
|
190
|
+
# List Checkpoints
|
|
191
|
+
# =============================================================================
|
|
192
|
+
|
|
193
|
+
list_checkpoints() {
|
|
194
|
+
local session_id="$1"
|
|
195
|
+
|
|
196
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
197
|
+
echo "[]"
|
|
198
|
+
return
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# Find commits matching the checkpoint pattern
|
|
202
|
+
local commits
|
|
203
|
+
commits=$(git log --oneline --grep="checkpoint: Ralph" 2>/dev/null | head -20)
|
|
204
|
+
|
|
205
|
+
if [[ -n "$commits" ]]; then
|
|
206
|
+
echo "$commits" | while read -r line; do
|
|
207
|
+
local hash=$(echo "$line" | cut -d' ' -f1)
|
|
208
|
+
local msg=$(echo "$line" | cut -d' ' -f2-)
|
|
209
|
+
echo "{\"hash\":\"$hash\",\"message\":\"$msg\"}"
|
|
210
|
+
done | jq -s '.'
|
|
211
|
+
else
|
|
212
|
+
echo "[]"
|
|
213
|
+
fi
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
# =============================================================================
|
|
217
|
+
# Create Branch for Session
|
|
218
|
+
# =============================================================================
|
|
219
|
+
|
|
220
|
+
create_session_branch() {
|
|
221
|
+
local session_id="$1"
|
|
222
|
+
local branch_name="${CP_BRANCH_PREFIX}${session_id}"
|
|
223
|
+
|
|
224
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
225
|
+
return 1
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# Check if branch already exists
|
|
229
|
+
if git show-ref --verify --quiet "refs/heads/$branch_name" 2>/dev/null; then
|
|
230
|
+
# Switch to existing branch
|
|
231
|
+
git checkout "$branch_name" 2>/dev/null
|
|
232
|
+
else
|
|
233
|
+
# Create new branch
|
|
234
|
+
git checkout -b "$branch_name" 2>/dev/null
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
print_verbose "${MSG_CHECKPOINT_BRANCH}: $branch_name"
|
|
238
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Ralph Wiggum - Circuit Breaker Module
|
|
4
|
+
# Safety mechanism to prevent infinite loops and detect stalls
|
|
5
|
+
# =============================================================================
|
|
6
|
+
|
|
7
|
+
# Circuit breaker thresholds (defaults)
|
|
8
|
+
CB_NO_CHANGES_THRESHOLD="${CB_NO_CHANGES_THRESHOLD:-3}"
|
|
9
|
+
CB_REPEATED_ERROR_THRESHOLD="${CB_REPEATED_ERROR_THRESHOLD:-5}"
|
|
10
|
+
CB_OUTPUT_DECLINE_THRESHOLD="${CB_OUTPUT_DECLINE_THRESHOLD:-70}"
|
|
11
|
+
|
|
12
|
+
# Circuit breaker state
|
|
13
|
+
CB_ITERATIONS_WITHOUT_CHANGES=0
|
|
14
|
+
CB_CONSECUTIVE_ERRORS=0
|
|
15
|
+
CB_PEAK_OUTPUT_LENGTH=0
|
|
16
|
+
CB_LAST_OUTPUT_LENGTH=0
|
|
17
|
+
CB_TRIGGERED=false
|
|
18
|
+
CB_TRIGGER_REASON=""
|
|
19
|
+
|
|
20
|
+
# =============================================================================
|
|
21
|
+
# Initialization
|
|
22
|
+
# =============================================================================
|
|
23
|
+
|
|
24
|
+
init_circuit_breaker() {
|
|
25
|
+
CB_ITERATIONS_WITHOUT_CHANGES=0
|
|
26
|
+
CB_CONSECUTIVE_ERRORS=0
|
|
27
|
+
CB_PEAK_OUTPUT_LENGTH=0
|
|
28
|
+
CB_LAST_OUTPUT_LENGTH=0
|
|
29
|
+
CB_TRIGGERED=false
|
|
30
|
+
CB_TRIGGER_REASON=""
|
|
31
|
+
|
|
32
|
+
# Load thresholds from config if available
|
|
33
|
+
if [[ -n "$CONFIG_FILE" && -f "$CONFIG_FILE" ]] && command -v yq &> /dev/null; then
|
|
34
|
+
local no_changes=$(yq e '.circuit_breaker.no_file_changes_threshold // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
35
|
+
[[ -n "$no_changes" ]] && CB_NO_CHANGES_THRESHOLD=$no_changes
|
|
36
|
+
|
|
37
|
+
local errors=$(yq e '.circuit_breaker.repeated_error_threshold // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
38
|
+
[[ -n "$errors" ]] && CB_REPEATED_ERROR_THRESHOLD=$errors
|
|
39
|
+
|
|
40
|
+
local decline=$(yq e '.circuit_breaker.output_decline_threshold // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
41
|
+
[[ -n "$decline" ]] && CB_OUTPUT_DECLINE_THRESHOLD=$decline
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
print_verbose "Circuit breaker initialized:"
|
|
45
|
+
print_verbose " - No changes threshold: $CB_NO_CHANGES_THRESHOLD"
|
|
46
|
+
print_verbose " - Error threshold: $CB_REPEATED_ERROR_THRESHOLD"
|
|
47
|
+
print_verbose " - Output decline threshold: ${CB_OUTPUT_DECLINE_THRESHOLD}%"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# =============================================================================
|
|
51
|
+
# Circuit Breaker Check
|
|
52
|
+
# =============================================================================
|
|
53
|
+
|
|
54
|
+
check_circuit_breaker() {
|
|
55
|
+
# Return 0 (true) if triggered, 1 (false) if OK to continue
|
|
56
|
+
|
|
57
|
+
# Check no progress (no file changes)
|
|
58
|
+
if [[ $CB_ITERATIONS_WITHOUT_CHANGES -ge $CB_NO_CHANGES_THRESHOLD ]]; then
|
|
59
|
+
CB_TRIGGERED=true
|
|
60
|
+
CB_TRIGGER_REASON="no_progress"
|
|
61
|
+
print_warning "${MSG_CB_TRIGGERED}: ${MSG_CB_NO_CHANGES} $CB_ITERATIONS_WITHOUT_CHANGES ${MSG_CB_ITERATIONS}"
|
|
62
|
+
return 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Check repeated errors
|
|
66
|
+
if [[ $CB_CONSECUTIVE_ERRORS -ge $CB_REPEATED_ERROR_THRESHOLD ]]; then
|
|
67
|
+
CB_TRIGGERED=true
|
|
68
|
+
CB_TRIGGER_REASON="repeated_errors"
|
|
69
|
+
print_warning "${MSG_CB_TRIGGERED}: ${MSG_CB_REPEATED_ERRORS}"
|
|
70
|
+
return 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Check output decline
|
|
74
|
+
if [[ $CB_PEAK_OUTPUT_LENGTH -gt 0 && $CB_LAST_OUTPUT_LENGTH -gt 0 ]]; then
|
|
75
|
+
local decline_percent=$(( (CB_PEAK_OUTPUT_LENGTH - CB_LAST_OUTPUT_LENGTH) * 100 / CB_PEAK_OUTPUT_LENGTH ))
|
|
76
|
+
if [[ $decline_percent -ge $CB_OUTPUT_DECLINE_THRESHOLD ]]; then
|
|
77
|
+
CB_TRIGGERED=true
|
|
78
|
+
CB_TRIGGER_REASON="output_decline"
|
|
79
|
+
print_warning "${MSG_CB_TRIGGERED}: ${MSG_CB_OUTPUT_DECLINE} ${decline_percent}${MSG_CB_PERCENT}"
|
|
80
|
+
return 0
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
return 1
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# =============================================================================
|
|
88
|
+
# Update Circuit Breaker State
|
|
89
|
+
# =============================================================================
|
|
90
|
+
|
|
91
|
+
update_circuit_breaker() {
|
|
92
|
+
local event_type="$1"
|
|
93
|
+
local output="$2"
|
|
94
|
+
|
|
95
|
+
case "$event_type" in
|
|
96
|
+
progress)
|
|
97
|
+
# Reset counters on progress
|
|
98
|
+
CB_ITERATIONS_WITHOUT_CHANGES=0
|
|
99
|
+
CB_CONSECUTIVE_ERRORS=0
|
|
100
|
+
|
|
101
|
+
# Update output tracking
|
|
102
|
+
local output_length=${#output}
|
|
103
|
+
CB_LAST_OUTPUT_LENGTH=$output_length
|
|
104
|
+
if [[ $output_length -gt $CB_PEAK_OUTPUT_LENGTH ]]; then
|
|
105
|
+
CB_PEAK_OUTPUT_LENGTH=$output_length
|
|
106
|
+
fi
|
|
107
|
+
;;
|
|
108
|
+
|
|
109
|
+
no_progress)
|
|
110
|
+
CB_ITERATIONS_WITHOUT_CHANGES=$((CB_ITERATIONS_WITHOUT_CHANGES + 1))
|
|
111
|
+
print_verbose "No progress: $CB_ITERATIONS_WITHOUT_CHANGES / $CB_NO_CHANGES_THRESHOLD"
|
|
112
|
+
;;
|
|
113
|
+
|
|
114
|
+
error)
|
|
115
|
+
CB_CONSECUTIVE_ERRORS=$((CB_CONSECUTIVE_ERRORS + 1))
|
|
116
|
+
print_verbose "Error count: $CB_CONSECUTIVE_ERRORS / $CB_REPEATED_ERROR_THRESHOLD"
|
|
117
|
+
;;
|
|
118
|
+
|
|
119
|
+
reset)
|
|
120
|
+
CB_ITERATIONS_WITHOUT_CHANGES=0
|
|
121
|
+
CB_CONSECUTIVE_ERRORS=0
|
|
122
|
+
CB_TRIGGERED=false
|
|
123
|
+
CB_TRIGGER_REASON=""
|
|
124
|
+
print_verbose "${MSG_CB_RESET}"
|
|
125
|
+
;;
|
|
126
|
+
esac
|
|
127
|
+
|
|
128
|
+
# Update session state if available
|
|
129
|
+
if [[ -n "$SESSION_ID" ]]; then
|
|
130
|
+
update_session_state "$SESSION_ID" "circuit_breaker" "{
|
|
131
|
+
\"iterations_without_changes\": $CB_ITERATIONS_WITHOUT_CHANGES,
|
|
132
|
+
\"consecutive_errors\": $CB_CONSECUTIVE_ERRORS,
|
|
133
|
+
\"peak_output_length\": $CB_PEAK_OUTPUT_LENGTH,
|
|
134
|
+
\"last_output_length\": $CB_LAST_OUTPUT_LENGTH,
|
|
135
|
+
\"triggered\": $CB_TRIGGERED,
|
|
136
|
+
\"trigger_reason\": \"$CB_TRIGGER_REASON\"
|
|
137
|
+
}"
|
|
138
|
+
fi
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
# =============================================================================
|
|
142
|
+
# Circuit Breaker Status
|
|
143
|
+
# =============================================================================
|
|
144
|
+
|
|
145
|
+
get_circuit_breaker_status() {
|
|
146
|
+
cat <<EOF
|
|
147
|
+
{
|
|
148
|
+
"iterations_without_changes": $CB_ITERATIONS_WITHOUT_CHANGES,
|
|
149
|
+
"consecutive_errors": $CB_CONSECUTIVE_ERRORS,
|
|
150
|
+
"peak_output_length": $CB_PEAK_OUTPUT_LENGTH,
|
|
151
|
+
"last_output_length": $CB_LAST_OUTPUT_LENGTH,
|
|
152
|
+
"triggered": $CB_TRIGGERED,
|
|
153
|
+
"trigger_reason": "$CB_TRIGGER_REASON",
|
|
154
|
+
"thresholds": {
|
|
155
|
+
"no_changes": $CB_NO_CHANGES_THRESHOLD,
|
|
156
|
+
"errors": $CB_REPEATED_ERROR_THRESHOLD,
|
|
157
|
+
"output_decline": $CB_OUTPUT_DECLINE_THRESHOLD
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
EOF
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# =============================================================================
|
|
164
|
+
# Force Trip
|
|
165
|
+
# =============================================================================
|
|
166
|
+
|
|
167
|
+
trip_circuit_breaker() {
|
|
168
|
+
local reason="$1"
|
|
169
|
+
CB_TRIGGERED=true
|
|
170
|
+
CB_TRIGGER_REASON="${reason:-manual}"
|
|
171
|
+
print_warning "${MSG_CB_TRIGGERED}: $CB_TRIGGER_REASON"
|
|
172
|
+
}
|