claude-flow-novice 2.14.18 → 2.14.19
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/.claude/commands/CFN_EXPERT_UPDATE.md +142 -0
- package/.claude/commands/cfn-docker/CFN_DOCKER_CLI.md +527 -0
- package/.claude/commands/cfn-docker/CFN_DOCKER_LOOP.md +377 -0
- package/.claude/commands/cfn-docker/CFN_DOCKER_TASK.md +490 -0
- package/.claude/commands/cfn-loop-cli.md +220 -46
- package/.claude/commands/deprecated/README.md +55 -0
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +199 -0
- package/claude-assets/commands/CFN_EXPERT_UPDATE.md +142 -0
- package/claude-assets/commands/cfn-docker/CFN_DOCKER_CLI.md +527 -0
- package/claude-assets/commands/cfn-docker/CFN_DOCKER_LOOP.md +377 -0
- package/claude-assets/commands/cfn-docker/CFN_DOCKER_TASK.md +490 -0
- package/claude-assets/commands/cfn-loop-cli.md +220 -46
- package/claude-assets/commands/deprecated/README.md +55 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +394 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +461 -0
- package/claude-assets/skills/cfn-docker-loop-orchestration/SKILL.md +449 -0
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +787 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/SKILL.md +435 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh +635 -0
- package/claude-assets/skills/cfn-docker-skill-mcp-selection/SKILL.md +289 -0
- package/claude-assets/skills/cfn-docker-skill-mcp-selection/skill-mcp-selector.js +472 -0
- package/claude-assets/skills/cfn-expert-update/update-expert.sh +346 -0
- package/dist/agents/agent-loader.js +165 -146
- package/dist/agents/agent-loader.js.map +1 -1
- package/package.json +1 -1
- /package/.claude/commands/{cfn-loop-epic.md → deprecated/cfn-loop-epic.md} +0 -0
- /package/.claude/commands/{cfn-loop-single.md → deprecated/cfn-loop-single.md} +0 -0
- /package/.claude/commands/{cfn-loop-sprints.md → deprecated/cfn-loop-sprints.md} +0 -0
- /package/.claude/commands/{cfn-loop.md → deprecated/cfn-loop.md} +0 -0
- /package/.claude/commands/{cfn/run-tests.md → run-tests.md} +0 -0
- /package/claude-assets/commands/{cfn-loop-epic.md → deprecated/cfn-loop-epic.md} +0 -0
- /package/claude-assets/commands/{cfn-loop-single.md → deprecated/cfn-loop-single.md} +0 -0
- /package/claude-assets/commands/{cfn-loop-sprints.md → deprecated/cfn-loop-sprints.md} +0 -0
- /package/claude-assets/commands/{cfn-loop.md → deprecated/cfn-loop.md} +0 -0
- /package/claude-assets/commands/{cfn/run-tests.md → run-tests.md} +0 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# CFN Docker Redis Coordination Implementation
|
|
4
|
+
# Usage: ./coordinate.sh [OPERATION] [OPTIONS]
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Default configuration
|
|
9
|
+
DEFAULT_REDIS_HOST="localhost"
|
|
10
|
+
DEFAULT_REDIS_PORT=6379
|
|
11
|
+
DEFAULT_REDIS_DB=0
|
|
12
|
+
DEFAULT_TIMEOUT=30
|
|
13
|
+
DEFAULT_TTL=3600
|
|
14
|
+
|
|
15
|
+
# Colors for output
|
|
16
|
+
RED='\033[0;31m'
|
|
17
|
+
GREEN='\033[0;32m'
|
|
18
|
+
YELLOW='\033[1;33m'
|
|
19
|
+
BLUE='\033[0;34m'
|
|
20
|
+
NC='\033[0m'
|
|
21
|
+
|
|
22
|
+
log() {
|
|
23
|
+
echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $*"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
log_success() {
|
|
27
|
+
echo -e "${GREEN}[SUCCESS]${NC} $*"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
log_error() {
|
|
31
|
+
echo -e "${RED}[ERROR]${NC} $*"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
log_warning() {
|
|
35
|
+
echo -e "${YELLOW}[WARNING]${NC} $*"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Function to display usage
|
|
39
|
+
usage() {
|
|
40
|
+
cat << EOF
|
|
41
|
+
CFN Docker Redis Coordination
|
|
42
|
+
|
|
43
|
+
Usage: $0 [OPERATION] [OPTIONS]
|
|
44
|
+
|
|
45
|
+
Operations:
|
|
46
|
+
init-task Initialize coordination for new task
|
|
47
|
+
store-context Store task context
|
|
48
|
+
get-context Retrieve task context
|
|
49
|
+
register-agent Register new agent
|
|
50
|
+
update-status Update agent status
|
|
51
|
+
signal-complete Signal agent completion
|
|
52
|
+
wait-loop Wait for loop completion
|
|
53
|
+
collect-consensus Collect validator consensus
|
|
54
|
+
recover-task Recover interrupted task
|
|
55
|
+
monitor-agents Monitor agent status
|
|
56
|
+
health-check Check Redis health
|
|
57
|
+
metrics Show performance metrics
|
|
58
|
+
cleanup Clean up expired data
|
|
59
|
+
debug Debug coordination state
|
|
60
|
+
|
|
61
|
+
Options:
|
|
62
|
+
--task-id ID Task identifier
|
|
63
|
+
--agent-id ID Agent identifier
|
|
64
|
+
--agent-type TYPE Agent type
|
|
65
|
+
--container-id ID Docker container ID
|
|
66
|
+
--confidence NUM Confidence score (0.0-1.0)
|
|
67
|
+
--iteration NUM Loop iteration number
|
|
68
|
+
--loop-number NUM Loop number (1-4)
|
|
69
|
+
--context-file PATH JSON context file
|
|
70
|
+
--timeout SECONDS Operation timeout
|
|
71
|
+
--ttl SECONDS Data TTL
|
|
72
|
+
--required-consensus Consensus threshold (0.0-1.0)
|
|
73
|
+
--host HOST Redis host (default: localhost)
|
|
74
|
+
--port PORT Redis port (default: 6379)
|
|
75
|
+
--db DB Redis database (default: 0)
|
|
76
|
+
--password PASS Redis password
|
|
77
|
+
--verbose Enable verbose logging
|
|
78
|
+
--help Show this help message
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
$0 init-task --task-id task-auth --context-file context.json
|
|
82
|
+
$0 register-agent --agent-id agent-001 --agent-type frontend --task-id task-auth
|
|
83
|
+
$0 signal-complete --agent-id agent-001 --task-id task-auth --confidence 0.85
|
|
84
|
+
$0 wait-loop --task-id task-auth --loop-number 3 --agent-count 3
|
|
85
|
+
$0 collect-consensus --task-id task-auth --loop-number 2 --required-consensus 0.90
|
|
86
|
+
|
|
87
|
+
EOF
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Redis connection check
|
|
91
|
+
check_redis_connection() {
|
|
92
|
+
local host="${REDIS_HOST:-$DEFAULT_REDIS_HOST}"
|
|
93
|
+
local port="${REDIS_PORT:-$DEFAULT_REDIS_PORT}"
|
|
94
|
+
local password="${REDIS_PASSWORD:-}"
|
|
95
|
+
|
|
96
|
+
if ! command -v redis-cli &> /dev/null; then
|
|
97
|
+
log_error "redis-cli command not found. Please install Redis tools."
|
|
98
|
+
return 1
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
local redis_cmd="redis-cli -h $host -p $port"
|
|
102
|
+
if [[ -n "$password" ]]; then
|
|
103
|
+
redis_cmd="$redis_cmd -a $password"
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
if ! $redis_cmd ping &> /dev/null; then
|
|
107
|
+
log_error "Cannot connect to Redis at $host:$port"
|
|
108
|
+
return 1
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
REDIS_CMD="$redis_cmd"
|
|
112
|
+
return 0
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Parse command line arguments
|
|
116
|
+
OPERATION=""
|
|
117
|
+
TASK_ID=""
|
|
118
|
+
AGENT_ID=""
|
|
119
|
+
AGENT_TYPE=""
|
|
120
|
+
CONTAINER_ID=""
|
|
121
|
+
CONFIDENCE=""
|
|
122
|
+
ITERATION=""
|
|
123
|
+
LOOP_NUMBER=""
|
|
124
|
+
CONTEXT_FILE=""
|
|
125
|
+
TIMEOUT="${DEFAULT_TIMEOUT}"
|
|
126
|
+
TTL="${DEFAULT_TTL}"
|
|
127
|
+
REQUIRED_CONSENSUS=""
|
|
128
|
+
REDIS_HOST="$DEFAULT_REDIS_HOST"
|
|
129
|
+
REDIS_PORT="$DEFAULT_REDIS_PORT"
|
|
130
|
+
REDIS_DB="$DEFAULT_REDIS_DB"
|
|
131
|
+
REDIS_PASSWORD=""
|
|
132
|
+
VERBOSE=false
|
|
133
|
+
|
|
134
|
+
while [[ $# -gt 0 ]]; do
|
|
135
|
+
case $1 in
|
|
136
|
+
--task-id)
|
|
137
|
+
TASK_ID="$2"
|
|
138
|
+
shift 2
|
|
139
|
+
;;
|
|
140
|
+
--agent-id)
|
|
141
|
+
AGENT_ID="$2"
|
|
142
|
+
shift 2
|
|
143
|
+
;;
|
|
144
|
+
--agent-type)
|
|
145
|
+
AGENT_TYPE="$2"
|
|
146
|
+
shift 2
|
|
147
|
+
;;
|
|
148
|
+
--container-id)
|
|
149
|
+
CONTAINER_ID="$2"
|
|
150
|
+
shift 2
|
|
151
|
+
;;
|
|
152
|
+
--confidence)
|
|
153
|
+
CONFIDENCE="$2"
|
|
154
|
+
shift 2
|
|
155
|
+
;;
|
|
156
|
+
--iteration)
|
|
157
|
+
ITERATION="$2"
|
|
158
|
+
shift 2
|
|
159
|
+
;;
|
|
160
|
+
--loop-number)
|
|
161
|
+
LOOP_NUMBER="$2"
|
|
162
|
+
shift 2
|
|
163
|
+
;;
|
|
164
|
+
--context-file)
|
|
165
|
+
CONTEXT_FILE="$2"
|
|
166
|
+
shift 2
|
|
167
|
+
;;
|
|
168
|
+
--timeout)
|
|
169
|
+
TIMEOUT="$2"
|
|
170
|
+
shift 2
|
|
171
|
+
;;
|
|
172
|
+
--ttl)
|
|
173
|
+
TTL="$2"
|
|
174
|
+
shift 2
|
|
175
|
+
;;
|
|
176
|
+
--required-consensus)
|
|
177
|
+
REQUIRED_CONSENSUS="$2"
|
|
178
|
+
shift 2
|
|
179
|
+
;;
|
|
180
|
+
--host)
|
|
181
|
+
REDIS_HOST="$2"
|
|
182
|
+
shift 2
|
|
183
|
+
;;
|
|
184
|
+
--port)
|
|
185
|
+
REDIS_PORT="$2"
|
|
186
|
+
shift 2
|
|
187
|
+
;;
|
|
188
|
+
--db)
|
|
189
|
+
REDIS_DB="$2"
|
|
190
|
+
shift 2
|
|
191
|
+
;;
|
|
192
|
+
--password)
|
|
193
|
+
REDIS_PASSWORD="$2"
|
|
194
|
+
shift 2
|
|
195
|
+
;;
|
|
196
|
+
--verbose)
|
|
197
|
+
VERBOSE=true
|
|
198
|
+
shift
|
|
199
|
+
;;
|
|
200
|
+
--help)
|
|
201
|
+
usage
|
|
202
|
+
exit 0
|
|
203
|
+
;;
|
|
204
|
+
-*)
|
|
205
|
+
log_error "Unknown option: $1"
|
|
206
|
+
usage
|
|
207
|
+
exit 1
|
|
208
|
+
;;
|
|
209
|
+
*)
|
|
210
|
+
if [[ -z "$OPERATION" ]]; then
|
|
211
|
+
OPERATION="$1"
|
|
212
|
+
else
|
|
213
|
+
log_error "Too many arguments"
|
|
214
|
+
usage
|
|
215
|
+
exit 1
|
|
216
|
+
fi
|
|
217
|
+
shift
|
|
218
|
+
;;
|
|
219
|
+
esac
|
|
220
|
+
done
|
|
221
|
+
|
|
222
|
+
# Validate operation
|
|
223
|
+
if [[ -z "$OPERATION" ]]; then
|
|
224
|
+
log_error "Operation is required"
|
|
225
|
+
usage
|
|
226
|
+
exit 1
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
# Check Redis connection
|
|
230
|
+
if ! check_redis_connection; then
|
|
231
|
+
exit 1
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
# Redis key generation functions
|
|
235
|
+
task_context_key() {
|
|
236
|
+
echo "cfn_docker:task:$1:context"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
agent_key() {
|
|
240
|
+
echo "cfn_docker:agent:$1"
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
agent_status_key() {
|
|
244
|
+
echo "cfn_docker:task:$1:agent:$2:done"
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
confidence_key() {
|
|
248
|
+
echo "cfn_docker:task:$1:confidence:$2"
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
consensus_key() {
|
|
252
|
+
echo "cfn_docker:task:$1:loop:$2:consensus"
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# Operation implementations
|
|
256
|
+
init_task() {
|
|
257
|
+
local task_id="$1"
|
|
258
|
+
local context_file="$2"
|
|
259
|
+
|
|
260
|
+
if [[ -z "$task_id" ]]; then
|
|
261
|
+
log_error "Task ID is required"
|
|
262
|
+
return 1
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
if [[ -n "$context_file" && ! -f "$context_file" ]]; then
|
|
266
|
+
log_error "Context file not found: $context_file"
|
|
267
|
+
return 1
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
log "Initializing coordination for task: $task_id"
|
|
271
|
+
|
|
272
|
+
# Store task metadata
|
|
273
|
+
$REDIS_CMD HSET "cfn_docker:task:$task_id:meta" \
|
|
274
|
+
"created_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
275
|
+
"ttl" "$TTL" \
|
|
276
|
+
"created_by" "cfn-docker-redis-coordination" \
|
|
277
|
+
> /dev/null
|
|
278
|
+
|
|
279
|
+
# Store context if provided
|
|
280
|
+
if [[ -n "$context_file" ]]; then
|
|
281
|
+
log "Storing context from: $context_file"
|
|
282
|
+
local context_key=$(task_context_key "$task_id")
|
|
283
|
+
|
|
284
|
+
# Read JSON file and store each field
|
|
285
|
+
if jq -e 'keys[]' "$context_file" &> /dev/null; then
|
|
286
|
+
while IFS= read -r key; do
|
|
287
|
+
local value=$(jq -r ".$key" "$context_file")
|
|
288
|
+
$REDIS_CMD HSET "$context_key" "$key" "$value" > /dev/null
|
|
289
|
+
done < <(jq -r 'keys[]' "$context_file")
|
|
290
|
+
else
|
|
291
|
+
log_error "Invalid JSON in context file: $context_file"
|
|
292
|
+
return 1
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# Set TTL on context
|
|
296
|
+
$REDIS_CMD EXPIRE "$context_key" "$TTL" > /dev/null
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
# Set TTL on metadata
|
|
300
|
+
$REDIS_CMD EXPIRE "cfn_docker:task:$task_id:meta" "$TTL" > /dev/null
|
|
301
|
+
|
|
302
|
+
log_success "Task coordination initialized: $task_id"
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
store_context() {
|
|
306
|
+
local task_id="$1"
|
|
307
|
+
local context_file="$2"
|
|
308
|
+
|
|
309
|
+
if [[ -z "$task_id" || -z "$context_file" ]]; then
|
|
310
|
+
log_error "Task ID and context file are required"
|
|
311
|
+
return 1
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
if [[ ! -f "$context_file" ]]; then
|
|
315
|
+
log_error "Context file not found: $context_file"
|
|
316
|
+
return 1
|
|
317
|
+
fi
|
|
318
|
+
|
|
319
|
+
log "Storing context for task: $task_id"
|
|
320
|
+
local context_key=$(task_context_key "$task_id")
|
|
321
|
+
|
|
322
|
+
# Store JSON fields
|
|
323
|
+
while IFS= read -r key; do
|
|
324
|
+
local value=$(jq -r ".$key" "$context_file")
|
|
325
|
+
$REDIS_CMD HSET "$context_key" "$key" "$value" > /dev/null
|
|
326
|
+
done < <(jq -r 'keys[]' "$context_file")
|
|
327
|
+
|
|
328
|
+
# Set TTL
|
|
329
|
+
$REDIS_CMD EXPIRE "$context_key" "$TTL" > /dev/null
|
|
330
|
+
|
|
331
|
+
log_success "Context stored for task: $task_id"
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
get_context() {
|
|
335
|
+
local task_id="$1"
|
|
336
|
+
local agent_id="$2"
|
|
337
|
+
|
|
338
|
+
if [[ -z "$task_id" ]]; then
|
|
339
|
+
log_error "Task ID is required"
|
|
340
|
+
return 1
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
local context_key=$(task_context_key "$task_id")
|
|
344
|
+
|
|
345
|
+
if ! $REDIS_CMD EXISTS "$context_key" &> /dev/null; then
|
|
346
|
+
log_error "No context found for task: $task_id"
|
|
347
|
+
return 1
|
|
348
|
+
fi
|
|
349
|
+
|
|
350
|
+
log "Retrieving context for task: $task_id"
|
|
351
|
+
|
|
352
|
+
# Get all fields and create JSON
|
|
353
|
+
local context_json="{"
|
|
354
|
+
local first=true
|
|
355
|
+
|
|
356
|
+
while IFS= read -r field; do
|
|
357
|
+
if [[ "$first" == false ]]; then
|
|
358
|
+
context_json="${context_json},"
|
|
359
|
+
fi
|
|
360
|
+
local value=$($REDIS_CMD HGET "$context_key" "$field")
|
|
361
|
+
context_json="${context_json}\"$field\":\"$value\""
|
|
362
|
+
first=false
|
|
363
|
+
done < <($REDIS_CMD HKEYS "$context_key")
|
|
364
|
+
|
|
365
|
+
context_json="${context_json}}"
|
|
366
|
+
|
|
367
|
+
echo "$context_json"
|
|
368
|
+
log_success "Context retrieved for task: $task_id"
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
register_agent() {
|
|
372
|
+
local task_id="$1"
|
|
373
|
+
local agent_id="$2"
|
|
374
|
+
local agent_type="$3"
|
|
375
|
+
local container_id="$4"
|
|
376
|
+
|
|
377
|
+
if [[ -z "$task_id" || -z "$agent_id" || -z "$agent_type" ]]; then
|
|
378
|
+
log_error "Task ID, Agent ID, and Agent Type are required"
|
|
379
|
+
return 1
|
|
380
|
+
fi
|
|
381
|
+
|
|
382
|
+
log "Registering agent: $agent_id (type: $agent_type)"
|
|
383
|
+
|
|
384
|
+
# Store agent information
|
|
385
|
+
$REDIS_CMD HSET "$(agent_key "$agent_id")" \
|
|
386
|
+
"agent_type" "$agent_type" \
|
|
387
|
+
"container_id" "${container_id:-}" \
|
|
388
|
+
"task_id" "$task_id" \
|
|
389
|
+
"status" "spawning" \
|
|
390
|
+
"iteration" "1" \
|
|
391
|
+
"created_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
392
|
+
> /dev/null
|
|
393
|
+
|
|
394
|
+
# Add to status history
|
|
395
|
+
$REDIS_CMD LPUSH "cfn_docker:agent:$agent_id:status_history" \
|
|
396
|
+
'{"status":"spawning","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' \
|
|
397
|
+
> /dev/null
|
|
398
|
+
|
|
399
|
+
# Set TTL
|
|
400
|
+
$REDIS_CMD EXPIRE "$(agent_key "$agent_id")" "$TTL" > /dev/null
|
|
401
|
+
|
|
402
|
+
log_success "Agent registered: $agent_id"
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
update_status() {
|
|
406
|
+
local agent_id="$1"
|
|
407
|
+
local status="$2"
|
|
408
|
+
local iteration="${3:-1}"
|
|
409
|
+
|
|
410
|
+
if [[ -z "$agent_id" || -z "$status" ]]; then
|
|
411
|
+
log_error "Agent ID and status are required"
|
|
412
|
+
return 1
|
|
413
|
+
fi
|
|
414
|
+
|
|
415
|
+
log "Updating status for agent $agent_id: $status"
|
|
416
|
+
|
|
417
|
+
# Update agent status
|
|
418
|
+
$REDIS_CMD HSET "$(agent_key "$agent_id")" \
|
|
419
|
+
"status" "$status" \
|
|
420
|
+
"iteration" "$iteration" \
|
|
421
|
+
"updated_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
422
|
+
> /dev/null
|
|
423
|
+
|
|
424
|
+
# Add to status history
|
|
425
|
+
$REDIS_CMD LPUSH "cfn_docker:agent:$agent_id:status_history" \
|
|
426
|
+
'{"status":"'$status'","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' \
|
|
427
|
+
> /dev/null
|
|
428
|
+
|
|
429
|
+
log_success "Status updated for agent $agent_id: $status"
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
signal_complete() {
|
|
433
|
+
local task_id="$1"
|
|
434
|
+
local agent_id="$2"
|
|
435
|
+
local confidence="$3"
|
|
436
|
+
local iteration="${4:-1}"
|
|
437
|
+
|
|
438
|
+
if [[ -z "$task_id" || -z "$agent_id" || -z "$confidence" ]]; then
|
|
439
|
+
log_error "Task ID, Agent ID, and confidence are required"
|
|
440
|
+
return 1
|
|
441
|
+
fi
|
|
442
|
+
|
|
443
|
+
# Validate confidence
|
|
444
|
+
if ! [[ "$confidence" =~ ^0\.[0-9]+$|^1\.0$ ]]; then
|
|
445
|
+
log_error "Confidence must be between 0.0 and 1.0"
|
|
446
|
+
return 1
|
|
447
|
+
fi
|
|
448
|
+
|
|
449
|
+
log "Agent $agent_id signaling completion with confidence: $confidence"
|
|
450
|
+
|
|
451
|
+
# Signal completion
|
|
452
|
+
$REDIS_CMD LPUSH "$(agent_status_key "$task_id" "$agent_id")" "complete" > /dev/null
|
|
453
|
+
|
|
454
|
+
# Store confidence
|
|
455
|
+
local agent_type=$($REDIS_CMD HGET "$(agent_key "$agent_id")" "agent_type")
|
|
456
|
+
$REDIS_CMD HSET "$(confidence_key "$task_id" "$agent_id")" \
|
|
457
|
+
"confidence" "$confidence" \
|
|
458
|
+
"iteration" "$iteration" \
|
|
459
|
+
"reported_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
460
|
+
"agent_type" "${agent_type:-unknown}" \
|
|
461
|
+
> /dev/null
|
|
462
|
+
|
|
463
|
+
# Update agent status
|
|
464
|
+
update_status "$agent_id" "completed" "$iteration"
|
|
465
|
+
|
|
466
|
+
log_success "Agent $agent_id completion signaled"
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
wait_loop() {
|
|
470
|
+
local task_id="$1"
|
|
471
|
+
local loop_number="$2"
|
|
472
|
+
local agent_count="$3"
|
|
473
|
+
local timeout="${4:-$TIMEOUT}"
|
|
474
|
+
|
|
475
|
+
if [[ -z "$task_id" || -z "$loop_number" || -z "$agent_count" ]]; then
|
|
476
|
+
log_error "Task ID, loop number, and agent count are required"
|
|
477
|
+
return 1
|
|
478
|
+
fi
|
|
479
|
+
|
|
480
|
+
log "Waiting for Loop $loop_number completion ($agent_count agents, timeout: ${timeout}s)"
|
|
481
|
+
|
|
482
|
+
local start_time=$(date +%s)
|
|
483
|
+
local completed_agents=0
|
|
484
|
+
|
|
485
|
+
while [[ $(($(date +%s) - start_time)) -lt $timeout ]]; do
|
|
486
|
+
completed_agents=0
|
|
487
|
+
|
|
488
|
+
# Count completed agents for this task
|
|
489
|
+
while IFS= read -r agent_id; do
|
|
490
|
+
if $REDIS_CMD EXISTS "$(agent_status_key "$task_id" "$agent_id")" &> /dev/null; then
|
|
491
|
+
((completed_agents++))
|
|
492
|
+
fi
|
|
493
|
+
done < <($REDIS_CMD KEYS "cfn_docker:agent:*" | grep -o "cfn_docker:agent:[^:]*" | cut -d: -f3)
|
|
494
|
+
|
|
495
|
+
if [[ $completed_agents -ge $agent_count ]]; then
|
|
496
|
+
log_success "Loop $loop_number completed ($completed_agents/$agent_count agents)"
|
|
497
|
+
return 0
|
|
498
|
+
fi
|
|
499
|
+
|
|
500
|
+
if [[ "$VERBOSE" == true ]]; then
|
|
501
|
+
log "Progress: $completed_agents/$agent_count agents completed"
|
|
502
|
+
fi
|
|
503
|
+
|
|
504
|
+
sleep 5
|
|
505
|
+
done
|
|
506
|
+
|
|
507
|
+
log_error "Loop $loop_number timeout: only $completed_agents/$agent_count agents completed"
|
|
508
|
+
return 1
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
collect_consensus() {
|
|
512
|
+
local task_id="$1"
|
|
513
|
+
local loop_number="$2"
|
|
514
|
+
local required_consensus="$3"
|
|
515
|
+
local timeout="${4:-$TIMEOUT}"
|
|
516
|
+
|
|
517
|
+
if [[ -z "$task_id" || -z "$loop_number" || -z "$required_consensus" ]]; then
|
|
518
|
+
log_error "Task ID, loop number, and required consensus are required"
|
|
519
|
+
return 1
|
|
520
|
+
fi
|
|
521
|
+
|
|
522
|
+
log "Collecting Loop $loop_number consensus (threshold: $required_consensus)"
|
|
523
|
+
|
|
524
|
+
local start_time=$(date +%s)
|
|
525
|
+
local responses=0
|
|
526
|
+
local total_confidence=0
|
|
527
|
+
|
|
528
|
+
# Wait for validator responses
|
|
529
|
+
while [[ $(($(date +%s) - start_time)) -lt $timeout ]]; do
|
|
530
|
+
responses=0
|
|
531
|
+
total_confidence=0
|
|
532
|
+
|
|
533
|
+
# Count validator responses
|
|
534
|
+
while IFS= read -r confidence_key; do
|
|
535
|
+
local confidence=$($REDIS_CMD HGET "$confidence_key" "confidence")
|
|
536
|
+
if [[ -n "$confidence" ]]; then
|
|
537
|
+
total_confidence=$(echo "$total_confidence + $confidence" | bc -l)
|
|
538
|
+
((responses++))
|
|
539
|
+
fi
|
|
540
|
+
done < <($REDIS_CMD KEYS "$(confidence_key "$task_id" "*")")
|
|
541
|
+
|
|
542
|
+
if [[ $responses -gt 0 ]]; then
|
|
543
|
+
local average_confidence=$(echo "scale=3; $total_confidence / $responses" | bc -l)
|
|
544
|
+
log "Responses: $responses, Average confidence: $average_confidence"
|
|
545
|
+
|
|
546
|
+
if (( $(echo "$average_confidence >= $required_consensus" | bc -l) )); then
|
|
547
|
+
local decision="PROCEED"
|
|
548
|
+
if (( $(echo "$average_confidence >= 0.95" | bc -l) )); then
|
|
549
|
+
decision="COMPLETE"
|
|
550
|
+
fi
|
|
551
|
+
|
|
552
|
+
# Store consensus result
|
|
553
|
+
$REDIS_CMD HSET "$(consensus_key "$task_id" "$loop_number")" \
|
|
554
|
+
"total_validators" "$responses" \
|
|
555
|
+
"responses_received" "$responses" \
|
|
556
|
+
"average_confidence" "$average_confidence" \
|
|
557
|
+
"consensus_reached" "true" \
|
|
558
|
+
"decision" "$decision" \
|
|
559
|
+
"collected_at" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
560
|
+
> /dev/null
|
|
561
|
+
|
|
562
|
+
log_success "Consensus reached: $average_confidence >= $required_consensus"
|
|
563
|
+
return 0
|
|
564
|
+
fi
|
|
565
|
+
fi
|
|
566
|
+
|
|
567
|
+
sleep 5
|
|
568
|
+
done
|
|
569
|
+
|
|
570
|
+
log_error "Consensus collection timeout: $responses responses, average: $(echo "scale=3; $total_confidence / $responses" | bc -l)"
|
|
571
|
+
return 1
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
health_check() {
|
|
575
|
+
log "Performing Redis health check"
|
|
576
|
+
|
|
577
|
+
# Test basic connectivity
|
|
578
|
+
if ! $REDIS_CMD ping &> /dev/null; then
|
|
579
|
+
log_error "Redis ping failed"
|
|
580
|
+
return 1
|
|
581
|
+
fi
|
|
582
|
+
|
|
583
|
+
# Test memory usage
|
|
584
|
+
local memory_info=$($REDIS_CMD INFO memory | grep used_memory_human)
|
|
585
|
+
log "Memory usage: $memory_info"
|
|
586
|
+
|
|
587
|
+
# Test latency
|
|
588
|
+
local latency_start=$(date +%s%N)
|
|
589
|
+
$REDIS_CMD ping &> /dev/null
|
|
590
|
+
local latency_end=$(date +%s%N)
|
|
591
|
+
local latency_ms=$(( (latency_end - latency_start) / 1000000 ))
|
|
592
|
+
log "Latency: ${latency_ms}ms"
|
|
593
|
+
|
|
594
|
+
# Test data access
|
|
595
|
+
local key_count=$($REDIS_CMD DBSIZE)
|
|
596
|
+
log "Total keys: $key_count"
|
|
597
|
+
|
|
598
|
+
log_success "Redis health check completed"
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
# Main operation dispatcher
|
|
602
|
+
case "$OPERATION" in
|
|
603
|
+
init-task)
|
|
604
|
+
init_task "$TASK_ID" "$CONTEXT_FILE"
|
|
605
|
+
;;
|
|
606
|
+
store-context)
|
|
607
|
+
store_context "$TASK_ID" "$CONTEXT_FILE"
|
|
608
|
+
;;
|
|
609
|
+
get-context)
|
|
610
|
+
get_context "$TASK_ID" "$AGENT_ID"
|
|
611
|
+
;;
|
|
612
|
+
register-agent)
|
|
613
|
+
register_agent "$TASK_ID" "$AGENT_ID" "$AGENT_TYPE" "$CONTAINER_ID"
|
|
614
|
+
;;
|
|
615
|
+
update-status)
|
|
616
|
+
update_status "$AGENT_ID" "$TASK_ID" "$ITERATION"
|
|
617
|
+
;;
|
|
618
|
+
signal-complete)
|
|
619
|
+
signal_complete "$TASK_ID" "$AGENT_ID" "$CONFIDENCE" "$ITERATION"
|
|
620
|
+
;;
|
|
621
|
+
wait-loop)
|
|
622
|
+
wait_loop "$TASK_ID" "$LOOP_NUMBER" "${AGENT_COUNT:-3}" "$TIMEOUT"
|
|
623
|
+
;;
|
|
624
|
+
collect-consensus)
|
|
625
|
+
collect_consensus "$TASK_ID" "$LOOP_NUMBER" "$REQUIRED_CONSENSUS" "$TIMEOUT"
|
|
626
|
+
;;
|
|
627
|
+
health-check)
|
|
628
|
+
health_check
|
|
629
|
+
;;
|
|
630
|
+
*)
|
|
631
|
+
log_error "Unknown operation: $OPERATION"
|
|
632
|
+
usage
|
|
633
|
+
exit 1
|
|
634
|
+
;;
|
|
635
|
+
esac
|