loki-mode 5.57.1 → 5.58.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/run.sh +149 -1
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Multi-agent autonomous startup system. Triggers on "Loki Mode". Takes PRD to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v5.
|
|
6
|
+
# Loki Mode v5.58.0
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -263,4 +263,4 @@ The following features are documented in skill modules but not yet fully automat
|
|
|
263
263
|
| Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
|
|
264
264
|
| Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
|
|
265
265
|
|
|
266
|
-
**v5.
|
|
266
|
+
**v5.58.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.
|
|
1
|
+
5.58.0
|
package/autonomy/run.sh
CHANGED
|
@@ -5556,6 +5556,76 @@ stop_dashboard() {
|
|
|
5556
5556
|
fi
|
|
5557
5557
|
}
|
|
5558
5558
|
|
|
5559
|
+
# Handle dashboard crash: restart silently without triggering pause handler
|
|
5560
|
+
# This prevents a killed dashboard from being misinterpreted as a user interrupt
|
|
5561
|
+
handle_dashboard_crash() {
|
|
5562
|
+
if [[ "${ENABLE_DASHBOARD:-true}" != "true" ]]; then
|
|
5563
|
+
return 0
|
|
5564
|
+
fi
|
|
5565
|
+
|
|
5566
|
+
local dashboard_pid_file=".loki/dashboard/dashboard.pid"
|
|
5567
|
+
if [[ ! -f "$dashboard_pid_file" ]]; then
|
|
5568
|
+
return 0
|
|
5569
|
+
fi
|
|
5570
|
+
|
|
5571
|
+
local dpid
|
|
5572
|
+
dpid=$(cat "$dashboard_pid_file" 2>/dev/null)
|
|
5573
|
+
if [[ -z "$dpid" ]]; then
|
|
5574
|
+
return 0
|
|
5575
|
+
fi
|
|
5576
|
+
|
|
5577
|
+
# Dashboard is still alive, nothing to do
|
|
5578
|
+
if kill -0 "$dpid" 2>/dev/null; then
|
|
5579
|
+
return 0
|
|
5580
|
+
fi
|
|
5581
|
+
|
|
5582
|
+
# Dashboard is dead -- restart it silently (with throttle)
|
|
5583
|
+
DASHBOARD_RESTART_COUNT=${DASHBOARD_RESTART_COUNT:-0}
|
|
5584
|
+
local max_restarts=${DASHBOARD_MAX_RESTARTS:-3}
|
|
5585
|
+
|
|
5586
|
+
if [ "$DASHBOARD_RESTART_COUNT" -ge "$max_restarts" ]; then
|
|
5587
|
+
log_warn "Dashboard restart limit reached ($max_restarts) - disabling dashboard for this session"
|
|
5588
|
+
ENABLE_DASHBOARD=false
|
|
5589
|
+
return 1
|
|
5590
|
+
fi
|
|
5591
|
+
|
|
5592
|
+
DASHBOARD_RESTART_COUNT=$((DASHBOARD_RESTART_COUNT + 1))
|
|
5593
|
+
log_info "Dashboard process $dpid exited, restarting silently (attempt $DASHBOARD_RESTART_COUNT/$max_restarts)..."
|
|
5594
|
+
emit_event_json "dashboard_crash" \
|
|
5595
|
+
"pid=$dpid" \
|
|
5596
|
+
"action=auto_restart" \
|
|
5597
|
+
"attempt=$DASHBOARD_RESTART_COUNT" \
|
|
5598
|
+
"autonomy_mode=$AUTONOMY_MODE"
|
|
5599
|
+
DASHBOARD_PID=""
|
|
5600
|
+
rm -f "$dashboard_pid_file"
|
|
5601
|
+
start_dashboard
|
|
5602
|
+
return 0
|
|
5603
|
+
}
|
|
5604
|
+
|
|
5605
|
+
# Check if a signal was caused by a child process dying (e.g., dashboard)
|
|
5606
|
+
# rather than an actual user interrupt. Returns 0 if it was a child crash
|
|
5607
|
+
# (handled silently), 1 if it was a real interrupt.
|
|
5608
|
+
is_child_process_signal() {
|
|
5609
|
+
# If dashboard PID is set and dashboard is now dead, this signal
|
|
5610
|
+
# was likely caused by the dashboard process exiting
|
|
5611
|
+
if [ -n "$DASHBOARD_PID" ] && ! kill -0 "$DASHBOARD_PID" 2>/dev/null; then
|
|
5612
|
+
handle_dashboard_crash
|
|
5613
|
+
return 0
|
|
5614
|
+
fi
|
|
5615
|
+
|
|
5616
|
+
# Check PID file as fallback
|
|
5617
|
+
if [ -f ".loki/dashboard/dashboard.pid" ]; then
|
|
5618
|
+
local dpid
|
|
5619
|
+
dpid=$(cat ".loki/dashboard/dashboard.pid" 2>/dev/null)
|
|
5620
|
+
if [ -n "$dpid" ] && ! kill -0 "$dpid" 2>/dev/null; then
|
|
5621
|
+
handle_dashboard_crash
|
|
5622
|
+
return 0
|
|
5623
|
+
fi
|
|
5624
|
+
fi
|
|
5625
|
+
|
|
5626
|
+
return 1
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5559
5629
|
#===============================================================================
|
|
5560
5630
|
# Calculate Exponential Backoff
|
|
5561
5631
|
#===============================================================================
|
|
@@ -7171,6 +7241,9 @@ if __name__ == "__main__":
|
|
|
7171
7241
|
# Update session continuity file for next iteration / agent handoff
|
|
7172
7242
|
update_continuity
|
|
7173
7243
|
|
|
7244
|
+
# Checkpoint after each iteration (v5.57.0)
|
|
7245
|
+
create_checkpoint "iteration-${ITERATION_COUNT} complete" "iteration-${ITERATION_COUNT}"
|
|
7246
|
+
|
|
7174
7247
|
# Code review gate (v5.35.0)
|
|
7175
7248
|
if [ "$PHASE_CODE_REVIEW" = "true" ] && [ "$ITERATION_COUNT" -gt 0 ]; then
|
|
7176
7249
|
run_code_review || log_warn "Code review found issues - check .loki/quality/reviews/"
|
|
@@ -7240,6 +7313,9 @@ if __name__ == "__main__":
|
|
|
7240
7313
|
local goal_desc="${prd_path:-codebase-analysis}"
|
|
7241
7314
|
store_episode_trace "$task_id" "failure" "iteration" "$goal_desc" "$duration"
|
|
7242
7315
|
|
|
7316
|
+
# Checkpoint failed iteration state (v5.57.0)
|
|
7317
|
+
create_checkpoint "iteration-${ITERATION_COUNT} failed (exit=$exit_code)" "iteration-${ITERATION_COUNT}-fail"
|
|
7318
|
+
|
|
7243
7319
|
# Handle retry - check for rate limit first
|
|
7244
7320
|
local rate_limit_wait=$(detect_rate_limit "$log_file")
|
|
7245
7321
|
local wait_time
|
|
@@ -7299,6 +7375,15 @@ check_human_intervention() {
|
|
|
7299
7375
|
# handle_pause returns 1 if STOP was requested during the pause, so we must
|
|
7300
7376
|
# propagate that as return 2 (stop) instead of always returning 1 (continue).
|
|
7301
7377
|
if [ -f "$loki_dir/PAUSE" ]; then
|
|
7378
|
+
# In perpetual mode: auto-clear PAUSE files and continue without waiting
|
|
7379
|
+
if [ "$AUTONOMY_MODE" = "perpetual" ] || [ "$PERPETUAL_MODE" = "true" ]; then
|
|
7380
|
+
log_warn "PAUSE file detected but autonomy mode is perpetual - auto-clearing"
|
|
7381
|
+
notify_intervention_needed "PAUSE file auto-cleared in perpetual mode" 2>/dev/null || true
|
|
7382
|
+
rm -f "$loki_dir/PAUSE" "$loki_dir/PAUSED.md"
|
|
7383
|
+
# Restart dashboard if it crashed (likely cause of the PAUSE)
|
|
7384
|
+
handle_dashboard_crash
|
|
7385
|
+
return 0
|
|
7386
|
+
fi
|
|
7302
7387
|
log_warn "PAUSE file detected - pausing execution"
|
|
7303
7388
|
notify_intervention_needed "Execution paused via PAUSE file"
|
|
7304
7389
|
handle_pause
|
|
@@ -7311,6 +7396,26 @@ check_human_intervention() {
|
|
|
7311
7396
|
return 1
|
|
7312
7397
|
fi
|
|
7313
7398
|
|
|
7399
|
+
# Check for PAUSE_AT_CHECKPOINT (checkpoint mode deferred pause)
|
|
7400
|
+
if [ -f "$loki_dir/PAUSE_AT_CHECKPOINT" ]; then
|
|
7401
|
+
if [ "$AUTONOMY_MODE" = "checkpoint" ]; then
|
|
7402
|
+
log_warn "Checkpoint pause requested - pausing now"
|
|
7403
|
+
rm -f "$loki_dir/PAUSE_AT_CHECKPOINT"
|
|
7404
|
+
notify_intervention_needed "Execution paused at checkpoint"
|
|
7405
|
+
touch "$loki_dir/PAUSE"
|
|
7406
|
+
handle_pause
|
|
7407
|
+
local pause_result=$?
|
|
7408
|
+
rm -f "$loki_dir/PAUSE"
|
|
7409
|
+
if [ "$pause_result" -eq 1 ]; then
|
|
7410
|
+
return 2
|
|
7411
|
+
fi
|
|
7412
|
+
return 1
|
|
7413
|
+
else
|
|
7414
|
+
# Clean up stale checkpoint pause file
|
|
7415
|
+
rm -f "$loki_dir/PAUSE_AT_CHECKPOINT"
|
|
7416
|
+
fi
|
|
7417
|
+
fi
|
|
7418
|
+
|
|
7314
7419
|
# Check for HUMAN_INPUT.md (prompt injection)
|
|
7315
7420
|
# Security: Check it's a regular file (not symlink) to prevent symlink attacks
|
|
7316
7421
|
if [ -f "$loki_dir/HUMAN_INPUT.md" ] && [ ! -L "$loki_dir/HUMAN_INPUT.md" ]; then
|
|
@@ -7516,7 +7621,46 @@ except (json.JSONDecodeError, OSError): pass
|
|
|
7516
7621
|
# Re-enable signals for pause mode
|
|
7517
7622
|
trap cleanup INT TERM
|
|
7518
7623
|
|
|
7519
|
-
#
|
|
7624
|
+
# Check if this signal was caused by a child process dying (e.g., dashboard)
|
|
7625
|
+
# rather than an actual user interrupt. In that case, handle silently.
|
|
7626
|
+
if is_child_process_signal; then
|
|
7627
|
+
log_info "Child process exit detected, handled silently"
|
|
7628
|
+
INTERRUPT_COUNT=0
|
|
7629
|
+
return
|
|
7630
|
+
fi
|
|
7631
|
+
|
|
7632
|
+
# In perpetual/autonomous mode: NEVER pause, NEVER wait for input
|
|
7633
|
+
# Log the interrupt but continue the iteration loop immediately
|
|
7634
|
+
if [ "$AUTONOMY_MODE" = "perpetual" ] || [ "$PERPETUAL_MODE" = "true" ]; then
|
|
7635
|
+
INTERRUPT_COUNT=$((INTERRUPT_COUNT + 1))
|
|
7636
|
+
INTERRUPT_LAST_TIME=$current_time
|
|
7637
|
+
echo ""
|
|
7638
|
+
log_warn "Interrupt received in perpetual mode - ignoring (not pausing)"
|
|
7639
|
+
log_info "To stop: touch .loki/STOP or press Ctrl+C twice within 2 seconds"
|
|
7640
|
+
echo ""
|
|
7641
|
+
# Check and restart dashboard if it died
|
|
7642
|
+
handle_dashboard_crash
|
|
7643
|
+
# Do NOT reset INTERRUPT_COUNT -- let it accumulate so double-Ctrl+C escape works
|
|
7644
|
+
return
|
|
7645
|
+
fi
|
|
7646
|
+
|
|
7647
|
+
# In checkpoint mode: only pause at explicit checkpoint boundaries, not on
|
|
7648
|
+
# random signals. A signal during normal execution is treated as noise.
|
|
7649
|
+
if [ "$AUTONOMY_MODE" = "checkpoint" ]; then
|
|
7650
|
+
INTERRUPT_COUNT=$((INTERRUPT_COUNT + 1))
|
|
7651
|
+
INTERRUPT_LAST_TIME=$current_time
|
|
7652
|
+
echo ""
|
|
7653
|
+
log_warn "Interrupt received in checkpoint mode - will pause at next checkpoint"
|
|
7654
|
+
log_info "To stop immediately: press Ctrl+C again within 2 seconds"
|
|
7655
|
+
echo ""
|
|
7656
|
+
# Mark that a pause was requested for the next checkpoint
|
|
7657
|
+
touch "${TARGET_DIR:-.}/.loki/PAUSE_AT_CHECKPOINT"
|
|
7658
|
+
handle_dashboard_crash
|
|
7659
|
+
# Do NOT reset INTERRUPT_COUNT -- let it accumulate so double-Ctrl+C escape works
|
|
7660
|
+
return
|
|
7661
|
+
fi
|
|
7662
|
+
|
|
7663
|
+
# Supervised mode (or unrecognized): original behavior - pause and show options
|
|
7520
7664
|
INTERRUPT_COUNT=$((INTERRUPT_COUNT + 1))
|
|
7521
7665
|
INTERRUPT_LAST_TIME=$current_time
|
|
7522
7666
|
|
|
@@ -7937,6 +8081,10 @@ main() {
|
|
|
7937
8081
|
# Compound learnings into structured solution files (v5.30.0)
|
|
7938
8082
|
compound_session_to_solutions
|
|
7939
8083
|
|
|
8084
|
+
# Log checkpoint count before final checkpoint (v5.57.0)
|
|
8085
|
+
local cp_count=$(find .loki/state/checkpoints -maxdepth 1 -type d -name "cp-*" 2>/dev/null | wc -l | tr -d ' ')
|
|
8086
|
+
log_info "Session checkpoints: ${cp_count}"
|
|
8087
|
+
|
|
7940
8088
|
# Create session-end checkpoint (v5.34.0)
|
|
7941
8089
|
create_checkpoint "session end (iterations=$ITERATION_COUNT)" "session-end"
|
|
7942
8090
|
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
package/mcp/__init__.py
CHANGED