loki-mode 5.4.5 → 5.4.7
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 +135 -13
- package/package.json +1 -1
- package/providers/gemini.sh +45 -9
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 zero human intervention. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v5.4.
|
|
6
|
+
# Loki Mode v5.4.7
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -241,4 +241,4 @@ Auto-detected or force with `LOKI_COMPLEXITY`:
|
|
|
241
241
|
|
|
242
242
|
---
|
|
243
243
|
|
|
244
|
-
**v5.4.
|
|
244
|
+
**v5.4.7 | Gemini rate limit fallback to flash model | ~245 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.4.
|
|
1
|
+
5.4.7
|
package/autonomy/run.sh
CHANGED
|
@@ -1378,10 +1378,9 @@ spawn_worktree_session() {
|
|
|
1378
1378
|
;;
|
|
1379
1379
|
gemini)
|
|
1380
1380
|
# Note: -p flag is DEPRECATED per gemini --help. Using positional prompt.
|
|
1381
|
-
#
|
|
1382
|
-
|
|
1383
|
-
"
|
|
1384
|
-
< /dev/null >> "$log_file" 2>&1
|
|
1381
|
+
# Uses invoke_gemini helper for rate limit fallback to flash model
|
|
1382
|
+
invoke_gemini "Loki Mode: $task_prompt. Read .loki/CONTINUITY.md for context." \
|
|
1383
|
+
>> "$log_file" 2>&1
|
|
1385
1384
|
;;
|
|
1386
1385
|
*)
|
|
1387
1386
|
log_error "Unknown provider: ${PROVIDER_NAME}"
|
|
@@ -1471,8 +1470,8 @@ Output ONLY the resolved file content with no conflict markers. No explanations.
|
|
|
1471
1470
|
resolution=$(codex exec --dangerously-bypass-approvals-and-sandbox "$conflict_prompt" 2>/dev/null)
|
|
1472
1471
|
;;
|
|
1473
1472
|
gemini)
|
|
1474
|
-
#
|
|
1475
|
-
resolution=$(
|
|
1473
|
+
# Uses invoke_gemini_capture for rate limit fallback to flash model
|
|
1474
|
+
resolution=$(invoke_gemini_capture "$conflict_prompt" 2>/dev/null)
|
|
1476
1475
|
;;
|
|
1477
1476
|
*)
|
|
1478
1477
|
log_error "Unknown provider: ${PROVIDER_NAME}"
|
|
@@ -1864,6 +1863,112 @@ EOF
|
|
|
1864
1863
|
log_info "Loki directory initialized: .loki/"
|
|
1865
1864
|
}
|
|
1866
1865
|
|
|
1866
|
+
#===============================================================================
|
|
1867
|
+
# Gemini Invocation with Rate Limit Fallback
|
|
1868
|
+
#===============================================================================
|
|
1869
|
+
|
|
1870
|
+
# Invoke Gemini with automatic fallback to flash model on rate limit
|
|
1871
|
+
# Usage: invoke_gemini "prompt" [additional args...]
|
|
1872
|
+
# Returns: exit code from gemini CLI
|
|
1873
|
+
invoke_gemini() {
|
|
1874
|
+
local prompt="$1"
|
|
1875
|
+
shift
|
|
1876
|
+
|
|
1877
|
+
local model="${PROVIDER_MODEL:-gemini-3-pro-preview}"
|
|
1878
|
+
local fallback="${PROVIDER_MODEL_FALLBACK:-gemini-3-flash-preview}"
|
|
1879
|
+
|
|
1880
|
+
# Create temp file for output to preserve streaming while checking for rate limit
|
|
1881
|
+
local tmp_output
|
|
1882
|
+
tmp_output=$(mktemp)
|
|
1883
|
+
|
|
1884
|
+
# Try primary model first
|
|
1885
|
+
gemini --yolo --model "$model" "$prompt" "$@" < /dev/null 2>&1 | tee "$tmp_output"
|
|
1886
|
+
local exit_code=${PIPESTATUS[0]}
|
|
1887
|
+
|
|
1888
|
+
# Check for rate limit in output
|
|
1889
|
+
if [[ $exit_code -ne 0 ]] && grep -qiE "(rate.?limit|429|quota|resource.?exhausted)" "$tmp_output"; then
|
|
1890
|
+
log_warn "Rate limit hit on $model, falling back to $fallback"
|
|
1891
|
+
rm -f "$tmp_output"
|
|
1892
|
+
gemini --yolo --model "$fallback" "$prompt" "$@" < /dev/null
|
|
1893
|
+
exit_code=$?
|
|
1894
|
+
else
|
|
1895
|
+
rm -f "$tmp_output"
|
|
1896
|
+
fi
|
|
1897
|
+
|
|
1898
|
+
return $exit_code
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
# Invoke Gemini and capture output (for variable assignment)
|
|
1902
|
+
# Usage: result=$(invoke_gemini_capture "prompt")
|
|
1903
|
+
# Falls back to flash model on rate limit
|
|
1904
|
+
invoke_gemini_capture() {
|
|
1905
|
+
local prompt="$1"
|
|
1906
|
+
shift
|
|
1907
|
+
|
|
1908
|
+
local model="${PROVIDER_MODEL:-gemini-3-pro-preview}"
|
|
1909
|
+
local fallback="${PROVIDER_MODEL_FALLBACK:-gemini-3-flash-preview}"
|
|
1910
|
+
local output
|
|
1911
|
+
|
|
1912
|
+
# Try primary model first
|
|
1913
|
+
output=$(gemini --yolo --model "$model" "$prompt" "$@" < /dev/null 2>&1)
|
|
1914
|
+
local exit_code=$?
|
|
1915
|
+
|
|
1916
|
+
# Check for rate limit in output
|
|
1917
|
+
if [[ $exit_code -ne 0 ]] && echo "$output" | grep -qiE "(rate.?limit|429|quota|resource.?exhausted)"; then
|
|
1918
|
+
log_warn "Rate limit hit on $model, falling back to $fallback" >&2
|
|
1919
|
+
output=$(gemini --yolo --model "$fallback" "$prompt" "$@" < /dev/null 2>&1)
|
|
1920
|
+
fi
|
|
1921
|
+
|
|
1922
|
+
echo "$output"
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
#===============================================================================
|
|
1926
|
+
# Copy Skill Files to Project Directory
|
|
1927
|
+
#===============================================================================
|
|
1928
|
+
|
|
1929
|
+
copy_skill_files() {
|
|
1930
|
+
# Copy skill files from the CLI package to the project's .loki/ directory.
|
|
1931
|
+
# This makes the CLI self-contained - no need to install Claude Code skill separately.
|
|
1932
|
+
# All providers (Claude, Gemini, Codex) use the same .loki/skills/ location.
|
|
1933
|
+
|
|
1934
|
+
local skills_src="$PROJECT_DIR/skills"
|
|
1935
|
+
local skills_dst=".loki/skills"
|
|
1936
|
+
|
|
1937
|
+
if [ ! -d "$skills_src" ]; then
|
|
1938
|
+
log_warn "Skills directory not found at $skills_src"
|
|
1939
|
+
return 1
|
|
1940
|
+
fi
|
|
1941
|
+
|
|
1942
|
+
# Create destination and copy skill files
|
|
1943
|
+
mkdir -p "$skills_dst"
|
|
1944
|
+
|
|
1945
|
+
# Copy all skill markdown files
|
|
1946
|
+
local copied=0
|
|
1947
|
+
for skill_file in "$skills_src"/*.md; do
|
|
1948
|
+
if [ -f "$skill_file" ]; then
|
|
1949
|
+
cp "$skill_file" "$skills_dst/"
|
|
1950
|
+
((copied++))
|
|
1951
|
+
fi
|
|
1952
|
+
done
|
|
1953
|
+
|
|
1954
|
+
# Also copy SKILL.md to .loki/ and rewrite paths for workspace access
|
|
1955
|
+
if [ -f "$PROJECT_DIR/SKILL.md" ]; then
|
|
1956
|
+
# Rewrite skill paths from skills/ to .loki/skills/
|
|
1957
|
+
sed -e 's|skills/00-index\.md|.loki/skills/00-index.md|g' \
|
|
1958
|
+
-e 's|skills/model-selection\.md|.loki/skills/model-selection.md|g' \
|
|
1959
|
+
-e 's|skills/quality-gates\.md|.loki/skills/quality-gates.md|g' \
|
|
1960
|
+
-e 's|skills/testing\.md|.loki/skills/testing.md|g' \
|
|
1961
|
+
-e 's|skills/troubleshooting\.md|.loki/skills/troubleshooting.md|g' \
|
|
1962
|
+
-e 's|skills/production\.md|.loki/skills/production.md|g' \
|
|
1963
|
+
-e 's|skills/parallel-workflows\.md|.loki/skills/parallel-workflows.md|g' \
|
|
1964
|
+
-e 's|skills/providers\.md|.loki/skills/providers.md|g' \
|
|
1965
|
+
-e 's|Read skills/|Read .loki/skills/|g' \
|
|
1966
|
+
"$PROJECT_DIR/SKILL.md" > ".loki/SKILL.md"
|
|
1967
|
+
fi
|
|
1968
|
+
|
|
1969
|
+
log_info "Copied $copied skill files to .loki/skills/"
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1867
1972
|
#===============================================================================
|
|
1868
1973
|
# Task Status Monitor
|
|
1869
1974
|
#===============================================================================
|
|
@@ -3415,7 +3520,8 @@ build_prompt() {
|
|
|
3415
3520
|
# Core autonomous instructions - NO questions, NO waiting, NEVER say done
|
|
3416
3521
|
local autonomous_suffix="CRITICAL AUTONOMY RULES: 1) NEVER ask questions - just decide. 2) NEVER wait for confirmation - just act. 3) NEVER say 'done' or 'complete' - there's always more to improve. 4) NEVER stop voluntarily - if out of tasks, create new ones (add tests, optimize, refactor, add features). 5) Work continues PERPETUALLY. Even if PRD is implemented, find bugs, add tests, improve UX, optimize performance."
|
|
3417
3522
|
|
|
3418
|
-
|
|
3523
|
+
# Skill files are always copied to .loki/skills/ for all providers
|
|
3524
|
+
local sdlc_instruction="SDLC_PHASES_ENABLED: [$phases]. Execute ALL enabled phases. Log results to .loki/logs/. See .loki/SKILL.md for phase details. Skill modules at .loki/skills/."
|
|
3419
3525
|
|
|
3420
3526
|
# Codebase Analysis Mode - when no PRD provided
|
|
3421
3527
|
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."
|
|
@@ -3830,13 +3936,25 @@ if __name__ == "__main__":
|
|
|
3830
3936
|
|
|
3831
3937
|
gemini)
|
|
3832
3938
|
# Gemini: Degraded mode - no stream-json, no agent tracking
|
|
3833
|
-
#
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
echo "[loki] Gemini model: $
|
|
3837
|
-
|
|
3838
|
-
|
|
3939
|
+
# Uses invoke_gemini helper for rate limit fallback to flash model
|
|
3940
|
+
local model="${PROVIDER_MODEL:-gemini-3-pro-preview}"
|
|
3941
|
+
local fallback="${PROVIDER_MODEL_FALLBACK:-gemini-3-flash-preview}"
|
|
3942
|
+
echo "[loki] Gemini model: $model (fallback: $fallback), tier: $tier_param" >> "$log_file"
|
|
3943
|
+
echo "[loki] Gemini model: $model (fallback: $fallback), tier: $tier_param" >> "$agent_log"
|
|
3944
|
+
|
|
3945
|
+
# Try primary model, fallback on rate limit
|
|
3946
|
+
local tmp_output
|
|
3947
|
+
tmp_output=$(mktemp)
|
|
3948
|
+
gemini --yolo --model "$model" "$prompt" < /dev/null 2>&1 | tee "$tmp_output" | tee -a "$log_file" "$agent_log"
|
|
3839
3949
|
local exit_code=${PIPESTATUS[0]}
|
|
3950
|
+
|
|
3951
|
+
if [[ $exit_code -ne 0 ]] && grep -qiE "(rate.?limit|429|quota|resource.?exhausted)" "$tmp_output"; then
|
|
3952
|
+
log_warn "Rate limit hit on $model, falling back to $fallback"
|
|
3953
|
+
echo "[loki] Fallback to $fallback due to rate limit" >> "$log_file"
|
|
3954
|
+
gemini --yolo --model "$fallback" "$prompt" < /dev/null 2>&1 | tee -a "$log_file" "$agent_log"
|
|
3955
|
+
exit_code=${PIPESTATUS[0]}
|
|
3956
|
+
fi
|
|
3957
|
+
rm -f "$tmp_output"
|
|
3840
3958
|
;;
|
|
3841
3959
|
|
|
3842
3960
|
*)
|
|
@@ -4276,6 +4394,10 @@ main() {
|
|
|
4276
4394
|
# Initialize .loki directory
|
|
4277
4395
|
init_loki_dir
|
|
4278
4396
|
|
|
4397
|
+
# Copy skill files to .loki/skills/ - makes CLI self-contained
|
|
4398
|
+
# No need to install Claude Code skill separately
|
|
4399
|
+
copy_skill_files
|
|
4400
|
+
|
|
4279
4401
|
# Import GitHub issues if enabled (v4.1.0)
|
|
4280
4402
|
if [ "$GITHUB_IMPORT" = "true" ]; then
|
|
4281
4403
|
import_github_issues
|
package/package.json
CHANGED
package/providers/gemini.sh
CHANGED
|
@@ -49,11 +49,13 @@ PROVIDER_MAX_PARALLEL=1
|
|
|
49
49
|
|
|
50
50
|
# Model Configuration
|
|
51
51
|
# Gemini CLI supports --model flag to specify model
|
|
52
|
-
#
|
|
52
|
+
# Primary: gemini-3-pro-preview (latest as of Jan 2026)
|
|
53
|
+
# Fallback: gemini-3-flash-preview (for rate limit scenarios)
|
|
53
54
|
PROVIDER_MODEL="gemini-3-pro-preview"
|
|
55
|
+
PROVIDER_MODEL_FALLBACK="gemini-3-flash-preview"
|
|
54
56
|
PROVIDER_MODEL_PLANNING="gemini-3-pro-preview"
|
|
55
57
|
PROVIDER_MODEL_DEVELOPMENT="gemini-3-pro-preview"
|
|
56
|
-
PROVIDER_MODEL_FAST="gemini-3-
|
|
58
|
+
PROVIDER_MODEL_FAST="gemini-3-flash-preview"
|
|
57
59
|
|
|
58
60
|
# Thinking levels (Gemini-specific: maps to reasoning depth)
|
|
59
61
|
PROVIDER_THINKING_PLANNING="high"
|
|
@@ -96,14 +98,28 @@ provider_version() {
|
|
|
96
98
|
gemini --version 2>/dev/null | head -1
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
# Invocation function
|
|
101
|
+
# Invocation function with rate limit fallback
|
|
100
102
|
# Uses --model flag to specify model, --yolo for autonomous mode
|
|
101
|
-
#
|
|
103
|
+
# Falls back to flash model if pro hits rate limit
|
|
102
104
|
# Note: < /dev/null prevents Gemini from pausing on stdin
|
|
103
105
|
provider_invoke() {
|
|
104
106
|
local prompt="$1"
|
|
105
107
|
shift
|
|
106
|
-
|
|
108
|
+
local output
|
|
109
|
+
local exit_code
|
|
110
|
+
|
|
111
|
+
# Try primary model first
|
|
112
|
+
output=$(gemini --yolo --model "$PROVIDER_MODEL" "$prompt" "$@" < /dev/null 2>&1)
|
|
113
|
+
exit_code=$?
|
|
114
|
+
|
|
115
|
+
# Check for rate limit (429) or quota exceeded
|
|
116
|
+
if [[ $exit_code -ne 0 ]] && echo "$output" | grep -qiE "(rate.?limit|429|quota|resource.?exhausted)"; then
|
|
117
|
+
echo "[loki] Rate limit hit on $PROVIDER_MODEL, falling back to $PROVIDER_MODEL_FALLBACK" >&2
|
|
118
|
+
gemini --yolo --model "$PROVIDER_MODEL_FALLBACK" "$prompt" "$@" < /dev/null
|
|
119
|
+
else
|
|
120
|
+
echo "$output"
|
|
121
|
+
return $exit_code
|
|
122
|
+
fi
|
|
107
123
|
}
|
|
108
124
|
|
|
109
125
|
# Model tier to thinking level parameter
|
|
@@ -117,14 +133,34 @@ provider_get_tier_param() {
|
|
|
117
133
|
esac
|
|
118
134
|
}
|
|
119
135
|
|
|
120
|
-
# Tier-aware invocation
|
|
136
|
+
# Tier-aware invocation with rate limit fallback
|
|
121
137
|
# Uses --model flag to specify model
|
|
122
|
-
#
|
|
138
|
+
# Falls back to flash model if pro hits rate limit
|
|
123
139
|
# Note: < /dev/null prevents Gemini from pausing on stdin
|
|
124
140
|
provider_invoke_with_tier() {
|
|
125
141
|
local tier="$1"
|
|
126
142
|
local prompt="$2"
|
|
127
143
|
shift 2
|
|
128
|
-
|
|
129
|
-
|
|
144
|
+
|
|
145
|
+
# Select model based on tier
|
|
146
|
+
local model="$PROVIDER_MODEL"
|
|
147
|
+
[[ "$tier" == "fast" ]] && model="$PROVIDER_MODEL_FAST"
|
|
148
|
+
|
|
149
|
+
echo "[loki] Using tier: $tier, model: $model" >&2
|
|
150
|
+
|
|
151
|
+
local output
|
|
152
|
+
local exit_code
|
|
153
|
+
|
|
154
|
+
# Try selected model first
|
|
155
|
+
output=$(gemini --yolo --model "$model" "$prompt" "$@" < /dev/null 2>&1)
|
|
156
|
+
exit_code=$?
|
|
157
|
+
|
|
158
|
+
# Check for rate limit (429) or quota exceeded - fallback to flash
|
|
159
|
+
if [[ $exit_code -ne 0 ]] && echo "$output" | grep -qiE "(rate.?limit|429|quota|resource.?exhausted)"; then
|
|
160
|
+
echo "[loki] Rate limit hit on $model, falling back to $PROVIDER_MODEL_FALLBACK" >&2
|
|
161
|
+
gemini --yolo --model "$PROVIDER_MODEL_FALLBACK" "$prompt" "$@" < /dev/null
|
|
162
|
+
else
|
|
163
|
+
echo "$output"
|
|
164
|
+
return $exit_code
|
|
165
|
+
fi
|
|
130
166
|
}
|