loki-mode 6.80.1 → 6.81.1
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 -5
- package/VERSION +1 -1
- package/autonomy/CONSTITUTION.md +2 -2
- package/autonomy/loki +196 -55
- package/autonomy/run.sh +32 -28
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/references/core-workflow.md +0 -13
- package/skills/model-selection.md +18 -0
- package/skills/troubleshooting.md +4 -41
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 v6.
|
|
6
|
+
# Loki Mode v6.81.1
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -131,7 +131,6 @@ GROWTH ──[continuous improvement loop]──> GROWTH
|
|
|
131
131
|
|
|
132
132
|
- Load only 1-2 skill modules at a time (from skills/00-index.md)
|
|
133
133
|
- Use Task tool with subagents for exploration (isolates context)
|
|
134
|
-
- IF context feels heavy: Create `.loki/signals/CONTEXT_CLEAR_REQUESTED`
|
|
135
134
|
- **Context Window Tracking (v5.40.0):** Dashboard gauge, timeline, and per-agent breakdown at `GET /api/context`
|
|
136
135
|
- **Notification Triggers (v5.40.0):** Configurable alerts when context exceeds thresholds, tasks fail, or budget limits hit. Manage via `GET/PUT /api/notifications/triggers`
|
|
137
136
|
|
|
@@ -154,7 +153,6 @@ GROWTH ──[continuous improvement loop]──> GROWTH
|
|
|
154
153
|
| `.loki/memory/semantic/patterns.json` | Before implementation tasks | On consolidation |
|
|
155
154
|
| `.loki/memory/semantic/anti-patterns.json` | Before debugging tasks | On error learning |
|
|
156
155
|
| `.loki/queue/dead-letter.json` | Session start | On task failure (5+ attempts) |
|
|
157
|
-
| `.loki/signals/CONTEXT_CLEAR_REQUESTED` | Never | When context heavy |
|
|
158
156
|
| `.loki/signals/HUMAN_REVIEW_NEEDED` | Never | When human decision required |
|
|
159
157
|
| `.loki/state/checkpoints/` | After task completion | Automatic + manual via `loki checkpoint` |
|
|
160
158
|
|
|
@@ -266,10 +264,9 @@ The following features are documented in skill modules but not yet fully automat
|
|
|
266
264
|
|
|
267
265
|
| Feature | Status | Notes |
|
|
268
266
|
|---------|--------|-------|
|
|
269
|
-
| PRE-ACT goal drift detection | Planned | Agent-level attention check before each action; no automated enforcement yet |
|
|
270
267
|
| CONTINUITY.md working memory | Implemented (v5.35.0) | Auto-managed by run.sh, updated each iteration |
|
|
271
268
|
| GitHub integration | Implemented (v5.42.2) | Import, sync-back, PR creation, export. CLI: `loki github`, API: `/api/github/*` |
|
|
272
269
|
| Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
|
|
273
270
|
| Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
|
|
274
271
|
|
|
275
|
-
**v6.
|
|
272
|
+
**v6.81.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
6.
|
|
1
|
+
6.81.1
|
package/autonomy/CONSTITUTION.md
CHANGED
|
@@ -433,8 +433,8 @@ git reset --hard ${checkpoint_hash}
|
|
|
433
433
|
|
|
434
434
|
- Load only 1-2 skill modules at a time
|
|
435
435
|
- Use Task tool with subagents for exploration (isolates context)
|
|
436
|
-
-
|
|
437
|
-
-
|
|
436
|
+
- Periodically consolidate learnings to CONTINUITY.md
|
|
437
|
+
- Rely on provider-native context management when context feels heavy (no explicit clear signal)
|
|
438
438
|
|
|
439
439
|
---
|
|
440
440
|
|
package/autonomy/loki
CHANGED
|
@@ -522,6 +522,7 @@ cmd_start() {
|
|
|
522
522
|
local mirofish_docker_image=""
|
|
523
523
|
local mirofish_bg=false
|
|
524
524
|
local mirofish_disabled=false
|
|
525
|
+
local no_plan=false # v6.81.1: --no-plan opts out of auto-plan display
|
|
525
526
|
|
|
526
527
|
while [[ $# -gt 0 ]]; do
|
|
527
528
|
case "$1" in
|
|
@@ -554,6 +555,7 @@ cmd_start() {
|
|
|
554
555
|
echo " --mirofish-timeout S Max pipeline wait in seconds (default: 3600)"
|
|
555
556
|
echo " --mirofish-bg Run MiroFish pipeline in background"
|
|
556
557
|
echo " --no-mirofish Disable MiroFish even if env var is set"
|
|
558
|
+
echo " --no-plan Skip auto-shown PRD analysis at startup"
|
|
557
559
|
echo " --yes, -y Skip confirmation prompts (auto-confirm)"
|
|
558
560
|
echo ""
|
|
559
561
|
echo "Environment Variables:"
|
|
@@ -776,6 +778,10 @@ cmd_start() {
|
|
|
776
778
|
mirofish_disabled=true
|
|
777
779
|
shift
|
|
778
780
|
;;
|
|
781
|
+
--no-plan)
|
|
782
|
+
no_plan=true
|
|
783
|
+
shift
|
|
784
|
+
;;
|
|
779
785
|
--budget)
|
|
780
786
|
if [[ -n "${2:-}" ]]; then
|
|
781
787
|
if ! echo "$2" | grep -qE '^[0-9]+(\.[0-9]+)?$'; then
|
|
@@ -1032,6 +1038,13 @@ cmd_start() {
|
|
|
1032
1038
|
fi
|
|
1033
1039
|
fi
|
|
1034
1040
|
|
|
1041
|
+
# v6.81.1: auto-show PRD analysis so users see complexity / cost / time
|
|
1042
|
+
# up front without needing a separate `loki plan` invocation. Skipped via
|
|
1043
|
+
# --no-plan or in non-TTY contexts (CI/pipe). No-op when PRD is absent.
|
|
1044
|
+
if [ -n "$prd_file" ]; then
|
|
1045
|
+
maybe_show_auto_plan "$prd_file" "$no_plan" || true
|
|
1046
|
+
fi
|
|
1047
|
+
|
|
1035
1048
|
# Load saved provider if not specified on command line
|
|
1036
1049
|
if [ -z "$provider" ]; then
|
|
1037
1050
|
if [ -f "$LOKI_DIR/state/provider" ]; then
|
|
@@ -4083,6 +4096,7 @@ cmd_run() {
|
|
|
4083
4096
|
echo " --complex Force complex complexity tier"
|
|
4084
4097
|
echo " --no-dashboard Disable web dashboard"
|
|
4085
4098
|
echo " --sandbox Run in Docker sandbox"
|
|
4099
|
+
echo " --no-plan Skip auto-shown PRD analysis at startup"
|
|
4086
4100
|
echo " --budget USD Set cost budget limit"
|
|
4087
4101
|
echo ""
|
|
4088
4102
|
echo "Progressive Isolation:"
|
|
@@ -4155,7 +4169,7 @@ cmd_run() {
|
|
|
4155
4169
|
start_args+=("--provider" "$provider_override")
|
|
4156
4170
|
shift
|
|
4157
4171
|
;;
|
|
4158
|
-
--parallel|--bg|--background|--simple|--complex|--no-dashboard|--sandbox)
|
|
4172
|
+
--parallel|--bg|--background|--simple|--complex|--no-dashboard|--sandbox|--no-plan)
|
|
4159
4173
|
start_args+=("$1")
|
|
4160
4174
|
shift
|
|
4161
4175
|
;;
|
|
@@ -4394,6 +4408,29 @@ INNER_SCRIPT_EOF
|
|
|
4394
4408
|
echo "$prd_content" > "$output_file"
|
|
4395
4409
|
echo -e "${GREEN}PRD generated:${NC} $output_file"
|
|
4396
4410
|
|
|
4411
|
+
# v6.81.1: auto-show PRD analysis once the issue-derived PRD is on disk,
|
|
4412
|
+
# so users see cost / complexity / time before execution begins. When the
|
|
4413
|
+
# user will continue into `cmd_start` below, cmd_start also has its own
|
|
4414
|
+
# auto-plan call -- but that second call respects --no-plan / TTY checks
|
|
4415
|
+
# and would typically re-emit the same analysis. We therefore pass
|
|
4416
|
+
# --no-plan along in start_args to prevent duplicate output. Passing
|
|
4417
|
+
# --no-plan here is safe because `cmd_run` itself already displayed the
|
|
4418
|
+
# plan.
|
|
4419
|
+
local _run_no_plan=false
|
|
4420
|
+
for _arg in "${start_args[@]+"${start_args[@]}"}"; do
|
|
4421
|
+
if [[ "$_arg" == "--no-plan" ]]; then
|
|
4422
|
+
_run_no_plan=true
|
|
4423
|
+
break
|
|
4424
|
+
fi
|
|
4425
|
+
done
|
|
4426
|
+
if [ -f "$output_file" ]; then
|
|
4427
|
+
maybe_show_auto_plan "$output_file" "$_run_no_plan" || true
|
|
4428
|
+
fi
|
|
4429
|
+
# Ensure cmd_start does not re-show the plan now that we just did.
|
|
4430
|
+
if [[ "$_run_no_plan" != "true" ]]; then
|
|
4431
|
+
start_args+=("--no-plan")
|
|
4432
|
+
fi
|
|
4433
|
+
|
|
4397
4434
|
# Start Loki Mode unless --no-start
|
|
4398
4435
|
if [[ "$no_start" == "true" ]]; then
|
|
4399
4436
|
echo ""
|
|
@@ -10524,58 +10561,25 @@ with open('$failover_file', 'w') as f: json.dump(d, f, indent=2)
|
|
|
10524
10561
|
done
|
|
10525
10562
|
}
|
|
10526
10563
|
|
|
10527
|
-
#
|
|
10528
|
-
|
|
10529
|
-
|
|
10530
|
-
|
|
10531
|
-
|
|
10532
|
-
|
|
10533
|
-
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
echo "Options:"
|
|
10544
|
-
echo " --json Machine-readable JSON output"
|
|
10545
|
-
echo " --verbose Show detailed per-iteration breakdown"
|
|
10546
|
-
echo " --help, -h Show this help"
|
|
10547
|
-
echo ""
|
|
10548
|
-
echo "Examples:"
|
|
10549
|
-
echo " loki plan ./prd.md"
|
|
10550
|
-
echo " loki plan ./prd.md --json"
|
|
10551
|
-
echo " loki plan ./prd.md --verbose"
|
|
10552
|
-
return 0
|
|
10553
|
-
;;
|
|
10554
|
-
--json) show_json=true; shift ;;
|
|
10555
|
-
--verbose) show_verbose=true; shift ;;
|
|
10556
|
-
*)
|
|
10557
|
-
if [ -z "$prd_file" ]; then
|
|
10558
|
-
prd_file="$1"
|
|
10559
|
-
fi
|
|
10560
|
-
shift
|
|
10561
|
-
;;
|
|
10562
|
-
esac
|
|
10563
|
-
done
|
|
10564
|
-
|
|
10565
|
-
if [ -z "$prd_file" ]; then
|
|
10566
|
-
echo -e "${RED}Usage: loki plan <PRD file>${NC}"
|
|
10567
|
-
echo "Run 'loki plan --help' for usage."
|
|
10564
|
+
# Reusable PRD plan analysis (v6.81.1)
|
|
10565
|
+
# Shared by `loki plan`, `loki start` (auto-plan), and `loki run` (auto-plan).
|
|
10566
|
+
# Arguments:
|
|
10567
|
+
# $1 - absolute PRD path
|
|
10568
|
+
# $2 - show_json (true|false)
|
|
10569
|
+
# $3 - show_verbose (true|false)
|
|
10570
|
+
# Respects:
|
|
10571
|
+
# LOKI_SESSION_MODEL - Pins ALL iterations to one tier (default: sonnet)
|
|
10572
|
+
# LOKI_LEGACY_TIER_SWITCHING - When 'true', restores per-iteration rotation
|
|
10573
|
+
show_prd_plan() {
|
|
10574
|
+
local prd_path="$1"
|
|
10575
|
+
local show_json="${2:-false}"
|
|
10576
|
+
local show_verbose="${3:-false}"
|
|
10577
|
+
|
|
10578
|
+
if [ -z "$prd_path" ] || [ ! -f "$prd_path" ]; then
|
|
10579
|
+
echo -e "${RED}show_prd_plan: PRD file not found: $prd_path${NC}" >&2
|
|
10568
10580
|
return 1
|
|
10569
10581
|
fi
|
|
10570
10582
|
|
|
10571
|
-
if [ ! -f "$prd_file" ]; then
|
|
10572
|
-
echo -e "${RED}PRD file not found: $prd_file${NC}"
|
|
10573
|
-
return 1
|
|
10574
|
-
fi
|
|
10575
|
-
|
|
10576
|
-
local prd_path
|
|
10577
|
-
prd_path="$(cd "$(dirname "$prd_file")" && pwd)/$(basename "$prd_file")"
|
|
10578
|
-
|
|
10579
10583
|
python3 -c "
|
|
10580
10584
|
import json, sys, os, re, math
|
|
10581
10585
|
|
|
@@ -10583,6 +10587,22 @@ prd_path = sys.argv[1]
|
|
|
10583
10587
|
show_json = sys.argv[2] == 'true'
|
|
10584
10588
|
show_verbose = sys.argv[3] == 'true'
|
|
10585
10589
|
|
|
10590
|
+
# v6.81.1: Respect LOKI_SESSION_MODEL (pinned by v6.81.0) so the estimate
|
|
10591
|
+
# matches what the main loop actually invokes. LOKI_LEGACY_TIER_SWITCHING=true
|
|
10592
|
+
# restores the legacy per-iteration Opus/Sonnet/Haiku rotation for users who
|
|
10593
|
+
# explicitly opt out.
|
|
10594
|
+
session_model_env = (os.environ.get('LOKI_SESSION_MODEL', 'sonnet') or 'sonnet').strip().lower()
|
|
10595
|
+
legacy_tier_switching = (os.environ.get('LOKI_LEGACY_TIER_SWITCHING', 'false') or 'false').strip().lower() == 'true'
|
|
10596
|
+
|
|
10597
|
+
# Map session model name to tier key used in tokens_per_tier below.
|
|
10598
|
+
# Unknown models fall through to 'development' (Sonnet) as a safe default.
|
|
10599
|
+
_session_tier_map = {
|
|
10600
|
+
'opus': 'planning',
|
|
10601
|
+
'sonnet': 'development',
|
|
10602
|
+
'haiku': 'fast',
|
|
10603
|
+
}
|
|
10604
|
+
session_tier = _session_tier_map.get(session_model_env, 'development')
|
|
10605
|
+
|
|
10586
10606
|
# Colors (disabled for JSON mode)
|
|
10587
10607
|
if show_json:
|
|
10588
10608
|
RED = GREEN = YELLOW = BLUE = CYAN = BOLD = DIM = NC = ''
|
|
@@ -10770,18 +10790,28 @@ tier_iterations = {'Opus': 0, 'Sonnet': 0, 'Haiku': 0}
|
|
|
10770
10790
|
for i in range(estimated_iterations):
|
|
10771
10791
|
rarv_step = i % 4
|
|
10772
10792
|
if rarv_step == 0:
|
|
10773
|
-
tier = 'planning'
|
|
10774
10793
|
phase_label = 'Reason (Planning)'
|
|
10775
10794
|
elif rarv_step == 1:
|
|
10776
|
-
tier = 'development'
|
|
10777
10795
|
phase_label = 'Act (Implementation)'
|
|
10778
10796
|
elif rarv_step == 2:
|
|
10779
|
-
tier = 'development'
|
|
10780
10797
|
phase_label = 'Reflect (Review)'
|
|
10781
10798
|
else:
|
|
10782
|
-
tier = 'fast'
|
|
10783
10799
|
phase_label = 'Verify (Testing)'
|
|
10784
10800
|
|
|
10801
|
+
if legacy_tier_switching:
|
|
10802
|
+
# Legacy pre-v6.81.0 behavior: rotate tier per RARV step.
|
|
10803
|
+
if rarv_step == 0:
|
|
10804
|
+
tier = 'planning'
|
|
10805
|
+
elif rarv_step in (1, 2):
|
|
10806
|
+
tier = 'development'
|
|
10807
|
+
else:
|
|
10808
|
+
tier = 'fast'
|
|
10809
|
+
else:
|
|
10810
|
+
# v6.81.0+: main loop is pinned to LOKI_SESSION_MODEL. Estimate
|
|
10811
|
+
# MUST use the same tier for all iterations to avoid quoting a
|
|
10812
|
+
# cost higher than the user will actually pay.
|
|
10813
|
+
tier = session_tier
|
|
10814
|
+
|
|
10785
10815
|
info = tokens_per_tier[tier]
|
|
10786
10816
|
model = info['model']
|
|
10787
10817
|
inp = info['input']
|
|
@@ -10957,7 +10987,20 @@ print(f' RARV cycles: {cycle_count} (4 iterations per cycle)')
|
|
|
10957
10987
|
opus_n = tier_iterations.get('Opus', 0)
|
|
10958
10988
|
sonnet_n = tier_iterations.get('Sonnet', 0)
|
|
10959
10989
|
haiku_n = tier_iterations.get('Haiku', 0)
|
|
10960
|
-
|
|
10990
|
+
if legacy_tier_switching:
|
|
10991
|
+
print(f' Model distribution: Opus x{opus_n} | Sonnet x{sonnet_n} | Haiku x{haiku_n}')
|
|
10992
|
+
print(f' {DIM}(legacy rotation: LOKI_LEGACY_TIER_SWITCHING=true){NC}')
|
|
10993
|
+
else:
|
|
10994
|
+
# Session-pinned: exactly one tier has all iterations.
|
|
10995
|
+
pinned_parts = []
|
|
10996
|
+
if opus_n > 0:
|
|
10997
|
+
pinned_parts.append(f'Opus x{opus_n}')
|
|
10998
|
+
if sonnet_n > 0:
|
|
10999
|
+
pinned_parts.append(f'Sonnet x{sonnet_n}')
|
|
11000
|
+
if haiku_n > 0:
|
|
11001
|
+
pinned_parts.append(f'Haiku x{haiku_n}')
|
|
11002
|
+
print(' Model distribution: ' + (' | '.join(pinned_parts) if pinned_parts else '(none)'))
|
|
11003
|
+
print(f' {DIM}(pinned via LOKI_SESSION_MODEL={session_model_env}; set LOKI_LEGACY_TIER_SWITCHING=true to rotate){NC}')
|
|
10961
11004
|
|
|
10962
11005
|
# Tokens
|
|
10963
11006
|
total_tok = total_input_tokens + total_output_tokens
|
|
@@ -10971,6 +11014,11 @@ ds = chr(36) # dollar sign
|
|
|
10971
11014
|
print(f'\n{CYAN}Cost Estimate{NC}')
|
|
10972
11015
|
print(f' {BOLD}Total: {ds}{total_cost:.2f}{NC}')
|
|
10973
11016
|
for model in ['Opus', 'Sonnet', 'Haiku']:
|
|
11017
|
+
# v6.81.1: suppress zero-cost tiers (e.g. session-pinned runs). Keeps
|
|
11018
|
+
# the breakdown focused on models actually used. Legacy mode still
|
|
11019
|
+
# shows all three because each tier has non-zero iterations.
|
|
11020
|
+
if tier_iterations.get(model, 0) == 0 and tier_totals.get(model, 0) == 0:
|
|
11021
|
+
continue
|
|
10974
11022
|
pct = (tier_totals[model] / total_cost * 100) if total_cost > 0 else 0
|
|
10975
11023
|
bar_len = int(pct / 5)
|
|
10976
11024
|
bar = '#' * bar_len + '.' * (20 - bar_len)
|
|
@@ -11025,6 +11073,99 @@ print()
|
|
|
11025
11073
|
" "$prd_path" "$show_json" "$show_verbose"
|
|
11026
11074
|
}
|
|
11027
11075
|
|
|
11076
|
+
# Dry-run PRD analysis and cost estimation (v6.18.0; refactored v6.81.1)
|
|
11077
|
+
# Thin wrapper around show_prd_plan() so the same analysis is reusable from
|
|
11078
|
+
# `loki start`, `loki run`, and other commands without duplicated code.
|
|
11079
|
+
cmd_plan() {
|
|
11080
|
+
local prd_file=""
|
|
11081
|
+
local show_json=false
|
|
11082
|
+
local show_verbose=false
|
|
11083
|
+
|
|
11084
|
+
while [[ $# -gt 0 ]]; do
|
|
11085
|
+
case "$1" in
|
|
11086
|
+
--help|-h)
|
|
11087
|
+
echo -e "${BOLD}loki plan${NC} - Dry-run PRD analysis and cost estimation"
|
|
11088
|
+
echo ""
|
|
11089
|
+
echo "Usage: loki plan <PRD> [options]"
|
|
11090
|
+
echo ""
|
|
11091
|
+
echo "Analyzes a PRD file without executing anything. Outputs complexity,"
|
|
11092
|
+
echo "estimated iterations, token usage, cost, and execution plan."
|
|
11093
|
+
echo ""
|
|
11094
|
+
echo "Options:"
|
|
11095
|
+
echo " --json Machine-readable JSON output"
|
|
11096
|
+
echo " --verbose Show detailed per-iteration breakdown"
|
|
11097
|
+
echo " --help, -h Show this help"
|
|
11098
|
+
echo ""
|
|
11099
|
+
echo "Environment Variables:"
|
|
11100
|
+
echo " LOKI_SESSION_MODEL Pin cost estimate to a single tier"
|
|
11101
|
+
echo " (opus|sonnet|haiku, default: sonnet)"
|
|
11102
|
+
echo " LOKI_LEGACY_TIER_SWITCHING Set to 'true' to restore the legacy"
|
|
11103
|
+
echo " Opus/Sonnet/Haiku per-iteration rotation"
|
|
11104
|
+
echo ""
|
|
11105
|
+
echo "Examples:"
|
|
11106
|
+
echo " loki plan ./prd.md"
|
|
11107
|
+
echo " loki plan ./prd.md --json"
|
|
11108
|
+
echo " loki plan ./prd.md --verbose"
|
|
11109
|
+
return 0
|
|
11110
|
+
;;
|
|
11111
|
+
--json) show_json=true; shift ;;
|
|
11112
|
+
--verbose) show_verbose=true; shift ;;
|
|
11113
|
+
*)
|
|
11114
|
+
if [ -z "$prd_file" ]; then
|
|
11115
|
+
prd_file="$1"
|
|
11116
|
+
fi
|
|
11117
|
+
shift
|
|
11118
|
+
;;
|
|
11119
|
+
esac
|
|
11120
|
+
done
|
|
11121
|
+
|
|
11122
|
+
if [ -z "$prd_file" ]; then
|
|
11123
|
+
echo -e "${RED}Usage: loki plan <PRD file>${NC}"
|
|
11124
|
+
echo "Run 'loki plan --help' for usage."
|
|
11125
|
+
return 1
|
|
11126
|
+
fi
|
|
11127
|
+
|
|
11128
|
+
if [ ! -f "$prd_file" ]; then
|
|
11129
|
+
echo -e "${RED}PRD file not found: $prd_file${NC}"
|
|
11130
|
+
return 1
|
|
11131
|
+
fi
|
|
11132
|
+
|
|
11133
|
+
local prd_path
|
|
11134
|
+
prd_path="$(cd "$(dirname "$prd_file")" && pwd)/$(basename "$prd_file")"
|
|
11135
|
+
|
|
11136
|
+
show_prd_plan "$prd_path" "$show_json" "$show_verbose"
|
|
11137
|
+
}
|
|
11138
|
+
|
|
11139
|
+
# Helper: decide whether to auto-show the plan from a major command.
|
|
11140
|
+
# v6.81.1: default ON, opt-out via --no-plan. Also auto-skipped when stdout is
|
|
11141
|
+
# not a TTY and --no-plan was not explicitly set (CI/automation contexts),
|
|
11142
|
+
# logging a one-line "plan skipped: non-interactive" to stderr for visibility.
|
|
11143
|
+
maybe_show_auto_plan() {
|
|
11144
|
+
local prd_path="$1"
|
|
11145
|
+
local no_plan_flag="${2:-false}" # user passed --no-plan explicitly
|
|
11146
|
+
|
|
11147
|
+
# Explicit opt-out wins.
|
|
11148
|
+
if [[ "$no_plan_flag" == "true" ]]; then
|
|
11149
|
+
return 0
|
|
11150
|
+
fi
|
|
11151
|
+
|
|
11152
|
+
# PRD missing: silently skip (other commands will emit their own errors).
|
|
11153
|
+
if [ -z "$prd_path" ] || [ ! -f "$prd_path" ]; then
|
|
11154
|
+
return 0
|
|
11155
|
+
fi
|
|
11156
|
+
|
|
11157
|
+
# Non-TTY heuristic: keep CI / pipe output clean. Log to stderr so it is
|
|
11158
|
+
# still surfaced in logs without corrupting stdout parsers.
|
|
11159
|
+
if [ ! -t 1 ]; then
|
|
11160
|
+
echo "plan skipped: non-interactive (pass --no-plan to silence, or run 'loki plan <PRD>' explicitly)" >&2
|
|
11161
|
+
return 0
|
|
11162
|
+
fi
|
|
11163
|
+
|
|
11164
|
+
local abs_prd
|
|
11165
|
+
abs_prd="$(cd "$(dirname "$prd_path")" && pwd)/$(basename "$prd_path")"
|
|
11166
|
+
show_prd_plan "$abs_prd" "false" "false"
|
|
11167
|
+
}
|
|
11168
|
+
|
|
11028
11169
|
# Main command dispatcher
|
|
11029
11170
|
main() {
|
|
11030
11171
|
if [ $# -eq 0 ]; then
|
package/autonomy/run.sh
CHANGED
|
@@ -294,7 +294,6 @@ parse_simple_yaml() {
|
|
|
294
294
|
set_from_yaml "$file" "model.planning" "LOKI_MODEL_PLANNING"
|
|
295
295
|
set_from_yaml "$file" "model.development" "LOKI_MODEL_DEVELOPMENT"
|
|
296
296
|
set_from_yaml "$file" "model.fast" "LOKI_MODEL_FAST"
|
|
297
|
-
set_from_yaml "$file" "model.compaction_interval" "LOKI_COMPACTION_INTERVAL"
|
|
298
297
|
|
|
299
298
|
# Parallel
|
|
300
299
|
set_from_yaml "$file" "parallel.enabled" "LOKI_PARALLEL_MODE"
|
|
@@ -432,7 +431,6 @@ parse_yaml_with_yq() {
|
|
|
432
431
|
"model.prompt_repetition:LOKI_PROMPT_REPETITION"
|
|
433
432
|
"model.confidence_routing:LOKI_CONFIDENCE_ROUTING"
|
|
434
433
|
"model.autonomy_mode:LOKI_AUTONOMY_MODE"
|
|
435
|
-
"model.compaction_interval:LOKI_COMPACTION_INTERVAL"
|
|
436
434
|
"parallel.enabled:LOKI_PARALLEL_MODE"
|
|
437
435
|
"parallel.max_worktrees:LOKI_MAX_WORKTREES"
|
|
438
436
|
"parallel.max_sessions:LOKI_MAX_PARALLEL_SESSIONS"
|
|
@@ -637,8 +635,14 @@ PROMPT_REPETITION=${LOKI_PROMPT_REPETITION:-true}
|
|
|
637
635
|
CONFIDENCE_ROUTING=${LOKI_CONFIDENCE_ROUTING:-true}
|
|
638
636
|
AUTONOMY_MODE=${LOKI_AUTONOMY_MODE:-perpetual} # perpetual|checkpoint|supervised
|
|
639
637
|
|
|
640
|
-
#
|
|
641
|
-
|
|
638
|
+
# Session-pinned model (S0.1): pin a single tier for the whole main loop.
|
|
639
|
+
# Default is "sonnet" -> resolved via the "development" tier in the abstract
|
|
640
|
+
# tier map. Set LOKI_LEGACY_TIER_SWITCHING=true to restore the old
|
|
641
|
+
# per-iteration RARV-driven tier rotation in the main loop. The
|
|
642
|
+
# get_rarv_tier function is preserved for subagent dispatch regardless.
|
|
643
|
+
LOKI_SESSION_MODEL="${LOKI_SESSION_MODEL:-sonnet}"
|
|
644
|
+
LOKI_LEGACY_TIER_SWITCHING="${LOKI_LEGACY_TIER_SWITCHING:-false}"
|
|
645
|
+
export LOKI_SESSION_MODEL LOKI_LEGACY_TIER_SWITCHING
|
|
642
646
|
|
|
643
647
|
# Parallel Workflows (Git Worktrees)
|
|
644
648
|
PARALLEL_MODE=${LOKI_PARALLEL_MODE:-false}
|
|
@@ -7618,16 +7622,6 @@ check_max_iterations() {
|
|
|
7618
7622
|
return 1
|
|
7619
7623
|
}
|
|
7620
7624
|
|
|
7621
|
-
# Check if context clear was requested by agent
|
|
7622
|
-
check_context_clear_signal() {
|
|
7623
|
-
if [ -f ".loki/signals/CONTEXT_CLEAR_REQUESTED" ]; then
|
|
7624
|
-
log_info "Context clear signal detected from agent"
|
|
7625
|
-
rm -f ".loki/signals/CONTEXT_CLEAR_REQUESTED"
|
|
7626
|
-
return 0
|
|
7627
|
-
fi
|
|
7628
|
-
return 1
|
|
7629
|
-
}
|
|
7630
|
-
|
|
7631
7625
|
# Load latest ledger content for context injection
|
|
7632
7626
|
load_ledger_context() {
|
|
7633
7627
|
local ledger_content=""
|
|
@@ -8389,13 +8383,7 @@ build_prompt() {
|
|
|
8389
8383
|
local analysis_instruction="CODEBASE_ANALYSIS_MODE: No PRD. FIRST: Analyze codebase - scan structure, read package.json/requirements.txt, examine README. THEN: Generate PRD at .loki/generated-prd.md. FINALLY: Execute SDLC phases."
|
|
8390
8384
|
|
|
8391
8385
|
# Context Memory Instructions (integrated with new memory system)
|
|
8392
|
-
local memory_instruction="MEMORY SYSTEM: Relevant context from past sessions is provided below (if any). Your actions will be automatically recorded for future reference. For complex handoffs: create .loki/memory/handoffs/{timestamp}.md. For important decisions: they will be captured in the timeline. Check .loki/CONTINUITY.md for session-level working memory.
|
|
8393
|
-
|
|
8394
|
-
# Proactive Compaction Reminder (every N iterations)
|
|
8395
|
-
local compaction_reminder=""
|
|
8396
|
-
if [ $((iteration % COMPACTION_INTERVAL)) -eq 0 ] && [ $iteration -gt 0 ]; then
|
|
8397
|
-
compaction_reminder="PROACTIVE_CONTEXT_CHECK: You are at iteration $iteration. Review context size - if conversation history is long, consolidate to CONTINUITY.md and consider creating .loki/signals/CONTEXT_CLEAR_REQUESTED to reset context while preserving state."
|
|
8398
|
-
fi
|
|
8386
|
+
local memory_instruction="MEMORY SYSTEM: Relevant context from past sessions is provided below (if any). Your actions will be automatically recorded for future reference. For complex handoffs: create .loki/memory/handoffs/{timestamp}.md. For important decisions: they will be captured in the timeline. Check .loki/CONTINUITY.md for session-level working memory."
|
|
8399
8387
|
|
|
8400
8388
|
# Load existing context if resuming
|
|
8401
8389
|
local context_injection=""
|
|
@@ -8691,15 +8679,15 @@ except Exception:
|
|
|
8691
8679
|
else
|
|
8692
8680
|
if [ $retry -eq 0 ]; then
|
|
8693
8681
|
if [ -n "$prd" ]; then
|
|
8694
|
-
echo "Loki Mode with PRD at $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $
|
|
8682
|
+
echo "Loki Mode with PRD at $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
|
|
8695
8683
|
else
|
|
8696
|
-
echo "Loki Mode. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $analysis_instruction $rarv_instruction $memory_instruction $
|
|
8684
|
+
echo "Loki Mode. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $analysis_instruction $rarv_instruction $memory_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
|
|
8697
8685
|
fi
|
|
8698
8686
|
else
|
|
8699
8687
|
if [ -n "$prd" ]; then
|
|
8700
|
-
echo "Loki Mode - Resume iteration #$iteration (retry #$retry). PRD: $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $
|
|
8688
|
+
echo "Loki Mode - Resume iteration #$iteration (retry #$retry). PRD: $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
|
|
8701
8689
|
else
|
|
8702
|
-
echo "Loki Mode - Resume iteration #$iteration (retry #$retry). $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section Use .loki/generated-prd.md if exists. $rarv_instruction $memory_instruction $
|
|
8690
|
+
echo "Loki Mode - Resume iteration #$iteration (retry #$retry). $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section Use .loki/generated-prd.md if exists. $rarv_instruction $memory_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
|
|
8703
8691
|
fi
|
|
8704
8692
|
fi
|
|
8705
8693
|
fi
|
|
@@ -9728,9 +9716,25 @@ except Exception as exc:
|
|
|
9728
9716
|
echo "=== Provider: ${PROVIDER_NAME:-claude} ===" | tee -a "$log_file" "$agent_log"
|
|
9729
9717
|
echo "=== Prompt (truncated): ${prompt:0:200}... ===" | tee -a "$log_file" "$agent_log"
|
|
9730
9718
|
|
|
9731
|
-
#
|
|
9732
|
-
|
|
9733
|
-
#
|
|
9719
|
+
# Tier selection (S0.1):
|
|
9720
|
+
# Default: pin a single tier for the whole session via LOKI_SESSION_MODEL.
|
|
9721
|
+
# Legacy: LOKI_LEGACY_TIER_SWITCHING=true restores RARV-driven rotation.
|
|
9722
|
+
if [ "${LOKI_LEGACY_TIER_SWITCHING:-false}" = "true" ]; then
|
|
9723
|
+
CURRENT_TIER=$(get_rarv_tier "$ITERATION_COUNT")
|
|
9724
|
+
else
|
|
9725
|
+
# Map session-pinned model name to an abstract tier so provider
|
|
9726
|
+
# helpers (which expect tier names) resolve correctly. Unknown
|
|
9727
|
+
# model strings are passed through as-is; provider loaders fall
|
|
9728
|
+
# back to a sane default.
|
|
9729
|
+
case "${LOKI_SESSION_MODEL:-sonnet}" in
|
|
9730
|
+
opus) CURRENT_TIER="planning" ;;
|
|
9731
|
+
sonnet) CURRENT_TIER="development" ;;
|
|
9732
|
+
haiku) CURRENT_TIER="fast" ;;
|
|
9733
|
+
planning|development|fast) CURRENT_TIER="${LOKI_SESSION_MODEL}" ;;
|
|
9734
|
+
*) CURRENT_TIER="${LOKI_SESSION_MODEL}" ;;
|
|
9735
|
+
esac
|
|
9736
|
+
fi
|
|
9737
|
+
# Export LOKI_CURRENT_TIER so provider helper functions
|
|
9734
9738
|
# (e.g., gemini.sh:provider_get_current_model) can resolve the correct model.
|
|
9735
9739
|
# Without this, LOKI_CURRENT_TIER is always empty and defaults to "planning".
|
|
9736
9740
|
LOKI_CURRENT_TIER="$CURRENT_TIER"
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -33,13 +33,6 @@ Every iteration follows this cycle:
|
|
|
33
33
|
| - Identify highest priority unblocked task |
|
|
34
34
|
| - Determine exact steps to complete it |
|
|
35
35
|
+-------------------------------------------------------------------+
|
|
36
|
-
| PRE-ACT ATTENTION: Goal alignment check (prevents context drift) |
|
|
37
|
-
| - Re-read .loki/queue/current-task.json |
|
|
38
|
-
| - Verify: "Does my planned action serve task.goal?" |
|
|
39
|
-
| - Check: "Am I solving the original problem, not a tangent?" |
|
|
40
|
-
| - IF drift detected: Log to .loki/signals/DRIFT_DETECTED, |
|
|
41
|
-
| return to REASON |
|
|
42
|
-
+-------------------------------------------------------------------+
|
|
43
36
|
| ACT: Execute the task |
|
|
44
37
|
| - Dispatch subagent via Task tool OR execute directly |
|
|
45
38
|
| - Write code, run tests, fix issues |
|
|
@@ -77,12 +70,6 @@ Every iteration follows this cycle:
|
|
|
77
70
|
- Retries with learned context
|
|
78
71
|
- Achieves 2-3x quality improvement (Boris Cherny's observed result)
|
|
79
72
|
|
|
80
|
-
**Key Enhancement (PRE-ACT ATTENTION):** The planning-with-files pattern adds a goal alignment check:
|
|
81
|
-
- Context drift is silent - agents don't notice they've drifted off-task
|
|
82
|
-
- Forcing goal re-read before each action catches drift early
|
|
83
|
-
- Prevents "correct solution to wrong problem" failure mode
|
|
84
|
-
- Cost: One file read per action. Benefit: Catches misalignment before wasted work.
|
|
85
|
-
|
|
86
73
|
---
|
|
87
74
|
|
|
88
75
|
## CONTINUITY.md - Working Memory Protocol
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Model Selection & Task Tool
|
|
2
2
|
|
|
3
|
+
## Session-Pinned Model (default)
|
|
4
|
+
|
|
5
|
+
Since v6.81.0, the main RARV loop uses **one pinned model per session** instead of rotating models per RARV phase. This eliminates per-iteration tier churn and keeps the main loop behavior predictable.
|
|
6
|
+
|
|
7
|
+
- Controlled by `LOKI_SESSION_MODEL` (default: `sonnet`).
|
|
8
|
+
- Accepted values: `opus`, `sonnet`, `haiku`, or a raw tier name (`planning`, `development`, `fast`). Model names are mapped to abstract tiers (opus -> planning, sonnet -> development, haiku -> fast) so provider helpers resolve correctly.
|
|
9
|
+
- `get_rarv_tier()` is retained and still used for subagent Task-tool dispatches (planning vs implementation vs fast work), not for the main loop.
|
|
10
|
+
|
|
11
|
+
**Rollback (legacy RARV tier rotation in the main loop):**
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
LOKI_LEGACY_TIER_SWITCHING=true ./autonomy/run.sh ./prd.md
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Set `LOKI_LEGACY_TIER_SWITCHING=true` to restore the previous per-iteration `get_rarv_tier "$ITERATION_COUNT"` behavior in the main loop.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
3
21
|
## Multi-Provider Support (v5.0.0)
|
|
4
22
|
|
|
5
23
|
Loki Mode supports five AI providers. Claude has full features; all others run in **degraded mode** (sequential execution only, no Task tool, no parallel agents).
|
|
@@ -577,7 +577,7 @@ Signals are inter-process communication files in `.loki/signals/` that trigger a
|
|
|
577
577
|
| Any drift detected | Return to REASON phase immediately |
|
|
578
578
|
| 1 drift in task | Log warning, continue with corrected action |
|
|
579
579
|
| 2 drifts in same task | Escalate to orchestrator for task review |
|
|
580
|
-
| 3+ drifts accumulated |
|
|
580
|
+
| 3+ drifts accumulated | Escalate to orchestrator, consolidate state to CONTINUITY.md |
|
|
581
581
|
| High/Critical severity | Pause task, dispatch opus reviewer |
|
|
582
582
|
|
|
583
583
|
**Automated Responses:**
|
|
@@ -590,9 +590,9 @@ immediate:
|
|
|
590
590
|
|
|
591
591
|
accumulated_threshold: 3
|
|
592
592
|
accumulated_action:
|
|
593
|
-
-
|
|
594
|
-
-
|
|
595
|
-
-
|
|
593
|
+
- Consolidate working memory to CONTINUITY.md
|
|
594
|
+
- Escalate to orchestrator for task review
|
|
595
|
+
- Rely on provider-native context management (no explicit clear signal)
|
|
596
596
|
```
|
|
597
597
|
|
|
598
598
|
**How to Write:**
|
|
@@ -605,42 +605,6 @@ EOF
|
|
|
605
605
|
|
|
606
606
|
---
|
|
607
607
|
|
|
608
|
-
### CONTEXT_CLEAR_REQUESTED Signal
|
|
609
|
-
|
|
610
|
-
**Purpose:** Agent requests context window reset while preserving state.
|
|
611
|
-
|
|
612
|
-
**Schema:** File presence only (empty file is sufficient).
|
|
613
|
-
|
|
614
|
-
**When to Create:**
|
|
615
|
-
- Context feels heavy/slow
|
|
616
|
-
- After 25+ iterations
|
|
617
|
-
- Conversation history exceeds 50KB
|
|
618
|
-
- Agent detects own confusion or loops
|
|
619
|
-
- 3+ accumulated DRIFT_DETECTED events
|
|
620
|
-
|
|
621
|
-
**Processing (by run.sh wrapper):**
|
|
622
|
-
1. Detect signal file
|
|
623
|
-
2. Load ledger context from `.loki/memory/ledgers/`
|
|
624
|
-
3. Load recent handoffs from `.loki/memory/handoffs/`
|
|
625
|
-
4. Delete signal file
|
|
626
|
-
5. Start new Claude session with injected context
|
|
627
|
-
6. Continue from last CONTINUITY.md state
|
|
628
|
-
|
|
629
|
-
**How to Create:**
|
|
630
|
-
```bash
|
|
631
|
-
touch .loki/signals/CONTEXT_CLEAR_REQUESTED
|
|
632
|
-
```
|
|
633
|
-
|
|
634
|
-
**Thresholds:**
|
|
635
|
-
| Trigger | Threshold |
|
|
636
|
-
|---------|-----------|
|
|
637
|
-
| Iteration count | Every 25 iterations (compaction reminder) |
|
|
638
|
-
| Drift accumulation | 3+ DRIFT_DETECTED events |
|
|
639
|
-
| Agent self-assessment | "Context feels heavy" |
|
|
640
|
-
| Error loop detection | Same error 3+ times |
|
|
641
|
-
|
|
642
|
-
---
|
|
643
|
-
|
|
644
608
|
### HUMAN_REVIEW_NEEDED Signal
|
|
645
609
|
|
|
646
610
|
**Purpose:** Escalate to human when autonomous action is inappropriate.
|
|
@@ -762,7 +726,6 @@ These signals coordinate parallel worktrees (see `skills/parallel-workflows.md`)
|
|
|
762
726
|
```
|
|
763
727
|
.loki/signals/
|
|
764
728
|
DRIFT_DETECTED # Append-only log (JSON lines)
|
|
765
|
-
CONTEXT_CLEAR_REQUESTED # Presence flag (empty file OK)
|
|
766
729
|
HUMAN_REVIEW_NEEDED # JSON with review context
|
|
767
730
|
HUMAN_APPROVED # JSON with decision
|
|
768
731
|
FEATURE_READY_auth # Worktree signal
|