agentk8 1.0.0
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/LICENSE +21 -0
- package/README.md +222 -0
- package/agentk +481 -0
- package/bin/agentk-wrapper.js +35 -0
- package/bin/postinstall.js +97 -0
- package/lib/core.sh +281 -0
- package/lib/ipc.sh +501 -0
- package/lib/spawn.sh +398 -0
- package/lib/ui.sh +415 -0
- package/lib/visual.sh +349 -0
- package/modes/dev/engineer.md +118 -0
- package/modes/dev/orchestrator.md +110 -0
- package/modes/dev/security.md +221 -0
- package/modes/dev/tester.md +161 -0
- package/modes/ml/data-engineer.md +244 -0
- package/modes/ml/evaluator.md +265 -0
- package/modes/ml/ml-engineer.md +239 -0
- package/modes/ml/orchestrator.md +145 -0
- package/modes/ml/researcher.md +198 -0
- package/modes/shared/scout.md +270 -0
- package/package.json +49 -0
package/lib/ipc.sh
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# AGENT-K IPC Library
|
|
3
|
+
# File-based inter-process communication between agents
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Source core for utilities
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
source "$SCRIPT_DIR/core.sh"
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# TASK STATUS CONSTANTS
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
STATUS_PENDING="pending"
|
|
16
|
+
STATUS_IN_PROGRESS="in_progress"
|
|
17
|
+
STATUS_COMPLETED="completed"
|
|
18
|
+
STATUS_FAILED="failed"
|
|
19
|
+
STATUS_CANCELLED="cancelled"
|
|
20
|
+
|
|
21
|
+
# Task types
|
|
22
|
+
TYPE_IMPLEMENT="implement"
|
|
23
|
+
TYPE_TEST="test"
|
|
24
|
+
TYPE_REVIEW="review"
|
|
25
|
+
TYPE_RESEARCH="research"
|
|
26
|
+
TYPE_EVALUATE="evaluate"
|
|
27
|
+
|
|
28
|
+
# =============================================================================
|
|
29
|
+
# TASK CREATION
|
|
30
|
+
# =============================================================================
|
|
31
|
+
|
|
32
|
+
create_task() {
|
|
33
|
+
local task_id="${1:-$(generate_task_id)}"
|
|
34
|
+
local task_type="$2"
|
|
35
|
+
local assigned_to="$3"
|
|
36
|
+
local prompt="$4"
|
|
37
|
+
local priority="${5:-1}"
|
|
38
|
+
local dependencies="${6:-[]}"
|
|
39
|
+
local context_files="${7:-[]}"
|
|
40
|
+
|
|
41
|
+
ensure_workspace
|
|
42
|
+
|
|
43
|
+
local task_file
|
|
44
|
+
task_file=$(get_task_file "$task_id")
|
|
45
|
+
local created_at
|
|
46
|
+
created_at=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
47
|
+
|
|
48
|
+
cat > "$task_file" <<EOF
|
|
49
|
+
{
|
|
50
|
+
"id": "$task_id",
|
|
51
|
+
"type": "$task_type",
|
|
52
|
+
"status": "$STATUS_PENDING",
|
|
53
|
+
"assigned_to": "$assigned_to",
|
|
54
|
+
"priority": $priority,
|
|
55
|
+
"created_at": "$created_at",
|
|
56
|
+
"started_at": null,
|
|
57
|
+
"completed_at": null,
|
|
58
|
+
"prompt": $(echo "$prompt" | jq -Rs .),
|
|
59
|
+
"context": {
|
|
60
|
+
"files": $context_files,
|
|
61
|
+
"dependencies": $dependencies
|
|
62
|
+
},
|
|
63
|
+
"result": null,
|
|
64
|
+
"error": null
|
|
65
|
+
}
|
|
66
|
+
EOF
|
|
67
|
+
|
|
68
|
+
log_debug "Created task: $task_id (assigned to: $assigned_to)"
|
|
69
|
+
echo "$task_id"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# =============================================================================
|
|
73
|
+
# TASK READING
|
|
74
|
+
# =============================================================================
|
|
75
|
+
|
|
76
|
+
read_task() {
|
|
77
|
+
local task_id="$1"
|
|
78
|
+
local task_file
|
|
79
|
+
task_file=$(get_task_file "$task_id")
|
|
80
|
+
|
|
81
|
+
if [[ -f "$task_file" ]]; then
|
|
82
|
+
cat "$task_file"
|
|
83
|
+
else
|
|
84
|
+
log_error "Task not found: $task_id"
|
|
85
|
+
return 1
|
|
86
|
+
fi
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get_task_status() {
|
|
90
|
+
local task_id="$1"
|
|
91
|
+
local task_file
|
|
92
|
+
task_file=$(get_task_file "$task_id")
|
|
93
|
+
|
|
94
|
+
if [[ -f "$task_file" ]]; then
|
|
95
|
+
jq -r '.status' "$task_file"
|
|
96
|
+
else
|
|
97
|
+
echo "unknown"
|
|
98
|
+
fi
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
get_task_field() {
|
|
102
|
+
local task_id="$1"
|
|
103
|
+
local field="$2"
|
|
104
|
+
local task_file
|
|
105
|
+
task_file=$(get_task_file "$task_id")
|
|
106
|
+
|
|
107
|
+
if [[ -f "$task_file" ]]; then
|
|
108
|
+
jq -r ".$field" "$task_file"
|
|
109
|
+
else
|
|
110
|
+
echo ""
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# =============================================================================
|
|
115
|
+
# TASK UPDATING
|
|
116
|
+
# =============================================================================
|
|
117
|
+
|
|
118
|
+
update_task_status() {
|
|
119
|
+
local task_id="$1"
|
|
120
|
+
local new_status="$2"
|
|
121
|
+
local task_file
|
|
122
|
+
task_file=$(get_task_file "$task_id")
|
|
123
|
+
|
|
124
|
+
if [[ ! -f "$task_file" ]]; then
|
|
125
|
+
log_error "Task not found: $task_id"
|
|
126
|
+
return 1
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
local tmp
|
|
130
|
+
tmp=$(mktemp)
|
|
131
|
+
local timestamp
|
|
132
|
+
timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
133
|
+
|
|
134
|
+
case "$new_status" in
|
|
135
|
+
"$STATUS_IN_PROGRESS")
|
|
136
|
+
jq ".status = \"$new_status\" | .started_at = \"$timestamp\"" "$task_file" > "$tmp"
|
|
137
|
+
;;
|
|
138
|
+
"$STATUS_COMPLETED"|"$STATUS_FAILED"|"$STATUS_CANCELLED")
|
|
139
|
+
jq ".status = \"$new_status\" | .completed_at = \"$timestamp\"" "$task_file" > "$tmp"
|
|
140
|
+
;;
|
|
141
|
+
*)
|
|
142
|
+
jq ".status = \"$new_status\"" "$task_file" > "$tmp"
|
|
143
|
+
;;
|
|
144
|
+
esac
|
|
145
|
+
|
|
146
|
+
mv "$tmp" "$task_file"
|
|
147
|
+
log_debug "Updated task $task_id status to: $new_status"
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
update_task_field() {
|
|
151
|
+
local task_id="$1"
|
|
152
|
+
local field="$2"
|
|
153
|
+
local value="$3"
|
|
154
|
+
local task_file
|
|
155
|
+
task_file=$(get_task_file "$task_id")
|
|
156
|
+
|
|
157
|
+
if [[ ! -f "$task_file" ]]; then
|
|
158
|
+
log_error "Task not found: $task_id"
|
|
159
|
+
return 1
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
local tmp
|
|
163
|
+
tmp=$(mktemp)
|
|
164
|
+
jq ".$field = $value" "$task_file" > "$tmp"
|
|
165
|
+
mv "$tmp" "$task_file"
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
# =============================================================================
|
|
169
|
+
# RESULT HANDLING
|
|
170
|
+
# =============================================================================
|
|
171
|
+
|
|
172
|
+
create_result() {
|
|
173
|
+
local task_id="$1"
|
|
174
|
+
local agent="$2"
|
|
175
|
+
local status="$3"
|
|
176
|
+
local output="$4"
|
|
177
|
+
local files_modified="${5:-[]}"
|
|
178
|
+
local next_steps="${6:-[]}"
|
|
179
|
+
|
|
180
|
+
ensure_workspace
|
|
181
|
+
|
|
182
|
+
local result_file
|
|
183
|
+
result_file=$(get_result_file "$task_id")
|
|
184
|
+
local completed_at
|
|
185
|
+
completed_at=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
|
|
186
|
+
|
|
187
|
+
cat > "$result_file" <<EOF
|
|
188
|
+
{
|
|
189
|
+
"task_id": "$task_id",
|
|
190
|
+
"agent": "$agent",
|
|
191
|
+
"status": "$status",
|
|
192
|
+
"output": $(echo "$output" | jq -Rs .),
|
|
193
|
+
"files_modified": $files_modified,
|
|
194
|
+
"next_steps": $next_steps,
|
|
195
|
+
"completed_at": "$completed_at"
|
|
196
|
+
}
|
|
197
|
+
EOF
|
|
198
|
+
|
|
199
|
+
# Also update the task with the result reference
|
|
200
|
+
update_task_field "$task_id" "result" "\"$result_file\""
|
|
201
|
+
update_task_status "$task_id" "$status"
|
|
202
|
+
|
|
203
|
+
log_debug "Created result for task: $task_id"
|
|
204
|
+
echo "$result_file"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
read_result() {
|
|
208
|
+
local task_id="$1"
|
|
209
|
+
local result_file
|
|
210
|
+
result_file=$(get_result_file "$task_id")
|
|
211
|
+
|
|
212
|
+
if [[ -f "$result_file" ]]; then
|
|
213
|
+
cat "$result_file"
|
|
214
|
+
else
|
|
215
|
+
log_error "Result not found for task: $task_id"
|
|
216
|
+
return 1
|
|
217
|
+
fi
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
# =============================================================================
|
|
221
|
+
# TASK QUERIES
|
|
222
|
+
# =============================================================================
|
|
223
|
+
|
|
224
|
+
list_tasks() {
|
|
225
|
+
local status_filter="${1:-}"
|
|
226
|
+
local task_dir="$AGENTK_WORKSPACE/tasks"
|
|
227
|
+
|
|
228
|
+
if [[ ! -d "$task_dir" ]]; then
|
|
229
|
+
echo "[]"
|
|
230
|
+
return
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
local tasks="[]"
|
|
234
|
+
|
|
235
|
+
for task_file in "$task_dir"/*.json; do
|
|
236
|
+
[[ -f "$task_file" ]] || continue
|
|
237
|
+
|
|
238
|
+
if [[ -z "$status_filter" ]]; then
|
|
239
|
+
tasks=$(echo "$tasks" | jq --slurpfile t "$task_file" '. + $t')
|
|
240
|
+
else
|
|
241
|
+
local task_status
|
|
242
|
+
task_status=$(jq -r '.status' "$task_file")
|
|
243
|
+
if [[ "$task_status" == "$status_filter" ]]; then
|
|
244
|
+
tasks=$(echo "$tasks" | jq --slurpfile t "$task_file" '. + $t')
|
|
245
|
+
fi
|
|
246
|
+
fi
|
|
247
|
+
done
|
|
248
|
+
|
|
249
|
+
echo "$tasks"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
list_tasks_by_agent() {
|
|
253
|
+
local agent="$1"
|
|
254
|
+
local task_dir="$AGENTK_WORKSPACE/tasks"
|
|
255
|
+
|
|
256
|
+
if [[ ! -d "$task_dir" ]]; then
|
|
257
|
+
echo "[]"
|
|
258
|
+
return
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
local tasks="[]"
|
|
262
|
+
|
|
263
|
+
for task_file in "$task_dir"/*.json; do
|
|
264
|
+
[[ -f "$task_file" ]] || continue
|
|
265
|
+
|
|
266
|
+
local assigned_to
|
|
267
|
+
assigned_to=$(jq -r '.assigned_to' "$task_file")
|
|
268
|
+
if [[ "$assigned_to" == "$agent" ]]; then
|
|
269
|
+
tasks=$(echo "$tasks" | jq --slurpfile t "$task_file" '. + $t')
|
|
270
|
+
fi
|
|
271
|
+
done
|
|
272
|
+
|
|
273
|
+
echo "$tasks"
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get_pending_tasks() {
|
|
277
|
+
list_tasks "$STATUS_PENDING"
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
get_active_tasks() {
|
|
281
|
+
list_tasks "$STATUS_IN_PROGRESS"
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
get_completed_tasks() {
|
|
285
|
+
list_tasks "$STATUS_COMPLETED"
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
# =============================================================================
|
|
289
|
+
# DEPENDENCY CHECKING
|
|
290
|
+
# =============================================================================
|
|
291
|
+
|
|
292
|
+
check_dependencies_met() {
|
|
293
|
+
local task_id="$1"
|
|
294
|
+
local task_file
|
|
295
|
+
task_file=$(get_task_file "$task_id")
|
|
296
|
+
|
|
297
|
+
if [[ ! -f "$task_file" ]]; then
|
|
298
|
+
return 1
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
local deps
|
|
302
|
+
deps=$(jq -r '.context.dependencies[]' "$task_file" 2>/dev/null || echo "")
|
|
303
|
+
|
|
304
|
+
if [[ -z "$deps" ]]; then
|
|
305
|
+
return 0 # No dependencies
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
while IFS= read -r dep_id; do
|
|
309
|
+
[[ -z "$dep_id" ]] && continue
|
|
310
|
+
|
|
311
|
+
local dep_status
|
|
312
|
+
dep_status=$(get_task_status "$dep_id")
|
|
313
|
+
if [[ "$dep_status" != "$STATUS_COMPLETED" ]]; then
|
|
314
|
+
log_debug "Task $task_id waiting on dependency: $dep_id (status: $dep_status)"
|
|
315
|
+
return 1
|
|
316
|
+
fi
|
|
317
|
+
done <<< "$deps"
|
|
318
|
+
|
|
319
|
+
return 0
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
get_ready_tasks() {
|
|
323
|
+
local pending
|
|
324
|
+
pending=$(get_pending_tasks)
|
|
325
|
+
|
|
326
|
+
echo "$pending" | jq -c '.[]' | while read -r task; do
|
|
327
|
+
local task_id
|
|
328
|
+
task_id=$(echo "$task" | jq -r '.id')
|
|
329
|
+
if check_dependencies_met "$task_id"; then
|
|
330
|
+
echo "$task"
|
|
331
|
+
fi
|
|
332
|
+
done | jq -s '.'
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
# =============================================================================
|
|
336
|
+
# TASK WATCHING
|
|
337
|
+
# =============================================================================
|
|
338
|
+
|
|
339
|
+
watch_task() {
|
|
340
|
+
local task_id="$1"
|
|
341
|
+
local timeout="${2:-300}" # Default 5 minutes
|
|
342
|
+
local poll_interval="${3:-1}"
|
|
343
|
+
|
|
344
|
+
local elapsed=0
|
|
345
|
+
while [[ $elapsed -lt $timeout ]]; do
|
|
346
|
+
local status
|
|
347
|
+
status=$(get_task_status "$task_id")
|
|
348
|
+
|
|
349
|
+
case "$status" in
|
|
350
|
+
"$STATUS_COMPLETED"|"$STATUS_FAILED"|"$STATUS_CANCELLED")
|
|
351
|
+
echo "$status"
|
|
352
|
+
return 0
|
|
353
|
+
;;
|
|
354
|
+
esac
|
|
355
|
+
|
|
356
|
+
sleep "$poll_interval"
|
|
357
|
+
elapsed=$((elapsed + poll_interval))
|
|
358
|
+
done
|
|
359
|
+
|
|
360
|
+
log_warn "Timeout waiting for task: $task_id"
|
|
361
|
+
echo "timeout"
|
|
362
|
+
return 1
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
watch_all_tasks() {
|
|
366
|
+
local callback="$1"
|
|
367
|
+
local poll_interval="${2:-1}"
|
|
368
|
+
|
|
369
|
+
while true; do
|
|
370
|
+
local active
|
|
371
|
+
active=$(get_active_tasks)
|
|
372
|
+
local count
|
|
373
|
+
count=$(echo "$active" | jq 'length')
|
|
374
|
+
|
|
375
|
+
if [[ "$count" -eq 0 ]]; then
|
|
376
|
+
# Check for pending tasks
|
|
377
|
+
local pending
|
|
378
|
+
pending=$(get_pending_tasks)
|
|
379
|
+
local pending_count
|
|
380
|
+
pending_count=$(echo "$pending" | jq 'length')
|
|
381
|
+
|
|
382
|
+
if [[ "$pending_count" -eq 0 ]]; then
|
|
383
|
+
log_debug "No active or pending tasks, stopping watch"
|
|
384
|
+
break
|
|
385
|
+
fi
|
|
386
|
+
fi
|
|
387
|
+
|
|
388
|
+
# Call the callback with current state
|
|
389
|
+
if [[ -n "$callback" ]] && type "$callback" &>/dev/null; then
|
|
390
|
+
"$callback" "$active"
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
sleep "$poll_interval"
|
|
394
|
+
done
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
# =============================================================================
|
|
398
|
+
# CLEANUP
|
|
399
|
+
# =============================================================================
|
|
400
|
+
|
|
401
|
+
cancel_task() {
|
|
402
|
+
local task_id="$1"
|
|
403
|
+
update_task_status "$task_id" "$STATUS_CANCELLED"
|
|
404
|
+
log_info "Cancelled task: $task_id"
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
cancel_all_tasks() {
|
|
408
|
+
local task_dir="$AGENTK_WORKSPACE/tasks"
|
|
409
|
+
|
|
410
|
+
if [[ ! -d "$task_dir" ]]; then
|
|
411
|
+
return
|
|
412
|
+
fi
|
|
413
|
+
|
|
414
|
+
for task_file in "$task_dir"/*.json; do
|
|
415
|
+
[[ -f "$task_file" ]] || continue
|
|
416
|
+
|
|
417
|
+
local status
|
|
418
|
+
status=$(jq -r '.status' "$task_file")
|
|
419
|
+
if [[ "$status" == "$STATUS_PENDING" || "$status" == "$STATUS_IN_PROGRESS" ]]; then
|
|
420
|
+
local task_id
|
|
421
|
+
task_id=$(jq -r '.id' "$task_file")
|
|
422
|
+
cancel_task "$task_id"
|
|
423
|
+
fi
|
|
424
|
+
done
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
delete_task() {
|
|
428
|
+
local task_id="$1"
|
|
429
|
+
local task_file
|
|
430
|
+
task_file=$(get_task_file "$task_id")
|
|
431
|
+
local result_file
|
|
432
|
+
result_file=$(get_result_file "$task_id")
|
|
433
|
+
|
|
434
|
+
[[ -f "$task_file" ]] && rm "$task_file"
|
|
435
|
+
[[ -f "$result_file" ]] && rm "$result_file"
|
|
436
|
+
|
|
437
|
+
log_debug "Deleted task: $task_id"
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
# =============================================================================
|
|
441
|
+
# SESSION MANAGEMENT
|
|
442
|
+
# =============================================================================
|
|
443
|
+
|
|
444
|
+
create_session() {
|
|
445
|
+
local session_id
|
|
446
|
+
session_id=$(generate_session_id)
|
|
447
|
+
local session_file="$AGENTK_WORKSPACE/session.json"
|
|
448
|
+
|
|
449
|
+
ensure_workspace
|
|
450
|
+
|
|
451
|
+
cat > "$session_file" <<EOF
|
|
452
|
+
{
|
|
453
|
+
"id": "$session_id",
|
|
454
|
+
"started_at": "$(date -u '+%Y-%m-%dT%H:%M:%SZ')",
|
|
455
|
+
"mode": "${AGENTK_MODE:-dev}",
|
|
456
|
+
"agents": {},
|
|
457
|
+
"task_count": 0
|
|
458
|
+
}
|
|
459
|
+
EOF
|
|
460
|
+
|
|
461
|
+
echo "$session_id"
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
get_current_session() {
|
|
465
|
+
local session_file="$AGENTK_WORKSPACE/session.json"
|
|
466
|
+
|
|
467
|
+
if [[ -f "$session_file" ]]; then
|
|
468
|
+
cat "$session_file"
|
|
469
|
+
else
|
|
470
|
+
echo "{}"
|
|
471
|
+
fi
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
update_session_agent() {
|
|
475
|
+
local agent="$1"
|
|
476
|
+
local status="$2"
|
|
477
|
+
local message="${3:-}"
|
|
478
|
+
local session_file="$AGENTK_WORKSPACE/session.json"
|
|
479
|
+
|
|
480
|
+
if [[ ! -f "$session_file" ]]; then
|
|
481
|
+
return 1
|
|
482
|
+
fi
|
|
483
|
+
|
|
484
|
+
local tmp
|
|
485
|
+
tmp=$(mktemp)
|
|
486
|
+
jq ".agents[\"$agent\"] = {\"status\": \"$status\", \"message\": \"$message\", \"updated_at\": \"$(date -u '+%Y-%m-%dT%H:%M:%SZ')\"}" "$session_file" > "$tmp"
|
|
487
|
+
mv "$tmp" "$session_file"
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
end_session() {
|
|
491
|
+
local session_file="$AGENTK_WORKSPACE/session.json"
|
|
492
|
+
|
|
493
|
+
if [[ -f "$session_file" ]]; then
|
|
494
|
+
local tmp
|
|
495
|
+
tmp=$(mktemp)
|
|
496
|
+
jq ".ended_at = \"$(date -u '+%Y-%m-%dT%H:%M:%SZ')\"" "$session_file" > "$tmp"
|
|
497
|
+
mv "$tmp" "$session_file"
|
|
498
|
+
fi
|
|
499
|
+
|
|
500
|
+
cancel_all_tasks
|
|
501
|
+
}
|