Skip to content

Instantly share code, notes, and snippets.

@aphexddb
Created April 19, 2026 17:24
Show Gist options
  • Select an option

  • Save aphexddb/d925988dcf121b608fd79b221c6ffd84 to your computer and use it in GitHub Desktop.

Select an option

Save aphexddb/d925988dcf121b608fd79b221c6ffd84 to your computer and use it in GitHub Desktop.
Ralph loops with local GLM-4.7-Flash
  1. Assumes llama-server is build in ~/llama.cpp
  2. Assumes you have a 5090
  3. Assumes model is UD-Q5_K_XL via https://huggingface.co/unsloth/GLM-4.7-Flash-GGUF
  4. Assumes you have a well defined Read PRD.md, PLAN.md, STATE.md, and CLAUDE.md

Start llama.cpp server

serve-glm-64k.sh

run claude locally

claude-code-glm-local.sh

start the loop

run-claude-forever.sh
Read PRD.md, PLAN.md, STATE.md, and CLAUDE.md first.
Choose the next smallest unfinished, unblocked slice from PLAN.md and execute only that slice.
Rules:
- Work on exactly one slice
- Read only files needed for that slice
- Keep changes minimal and typed
- Do not broaden scope
- If blocked, do only one smallest useful unblock step
- If still blocked, mark the slice blocked in PLAN.md and explain in STATE.md
- If all remaining slices are done or blocked, say so clearly and stop
- Update PLAN.md and STATE.md before stopping
- Print a short summary
Stop immediately after one slice.
#!/usr/bin/env bash
set -euo pipefail
HOST="${HOST:-127.0.0.1}"
PORT="${PORT:-8001}"
MODEL="${MODEL:-glm-4.7-flash}"
export ANTHROPIC_BASE_URL="http://${HOST}:${PORT}"
export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-sk-no-key-required}"
export ANTHROPIC_MODEL="${ANTHROPIC_MODEL:-${MODEL}}"
export OPENAI_BASE_URL="${OPENAI_BASE_URL:-http://${HOST}:${PORT}/v1}"
export OPENAI_API_KEY="${OPENAI_API_KEY:-sk-no-key-required}"
export OPENAI_MODEL="${OPENAI_MODEL:-${MODEL}}"
export CLAUDE_CODE_ATTRIBUTION_HEADER="${CLAUDE_CODE_ATTRIBUTION_HEADER:-0}"
echo "Claude Code configured for ${ANTHROPIC_BASE_URL}"
echo "Model: ${ANTHROPIC_MODEL}"
echo
exec claude --dangerously-skip-permissions
#!/usr/bin/env bash
set -euo pipefail
WORKDIR="${1:-$PWD}"
PROMPT_FILE="${PROMPT_FILE:-$WORKDIR/AUTO_LOOP_PROMPT.txt}"
SLEEP_SECS="${SLEEP_SECS:-2}"
LOG_DIR="${LOG_DIR:-$WORKDIR/logs}"
HEARTBEAT_SECS="${HEARTBEAT_SECS:-15}"
SUMMARY_FILE="${SUMMARY_FILE:-$LOG_DIR/run-summary.tsv}"
cd "$WORKDIR"
if [[ ! -f "$PROMPT_FILE" ]]; then
echo "Missing prompt file: $PROMPT_FILE" >&2
exit 1
fi
mkdir -p "$LOG_DIR"
if [[ ! -f "$SUMMARY_FILE" ]]; then
printf "run\tstart_time\telapsed_seconds\texit_code\tprompt_tokens\tcompletion_tokens\ttotal_tokens\tlog_file\n" > "$SUMMARY_FILE"
fi
run_num=0
while true; do
((run_num+=1))
ts="$(date '+%Y%m%d-%H%M%S')"
start_human="$(date '+%Y-%m-%d %H:%M:%S %Z')"
start_epoch="$(date +%s)"
log_file="$LOG_DIR/claude-run-${run_num}-${ts}.log"
prompt_contents="$(cat "$PROMPT_FILE")"
{
echo
echo "============================================================"
echo "Starting fresh non-interactive Claude run"
echo "Run: $run_num"
echo "Timestamp: $start_human"
echo "Workdir: $WORKDIR"
echo "Prompt: $PROMPT_FILE"
echo "Log file: $log_file"
echo "Summary: $SUMMARY_FILE"
echo "============================================================"
echo
echo "Prompt contents:"
echo "------------------------------------------------------------"
printf '%s\n' "$prompt_contents"
echo "------------------------------------------------------------"
echo
echo "Launching Claude with stream-json..."
echo
} | tee -a "$log_file"
set +e
(
while true; do
echo "[heartbeat] Claude still running at $(date)" >> "$log_file"
sleep "$HEARTBEAT_SECS"
done
) &
heartbeat_pid=$!
stdbuf -oL -eL \
env \
ANTHROPIC_BASE_URL="${ANTHROPIC_BASE_URL:-http://127.0.0.1:8001}" \
ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-sk-no-key-required}" \
ANTHROPIC_MODEL="${ANTHROPIC_MODEL:-glm-4.7-flash}" \
OPENAI_BASE_URL="${OPENAI_BASE_URL:-http://127.0.0.1:8001/v1}" \
OPENAI_API_KEY="${OPENAI_API_KEY:-sk-no-key-required}" \
OPENAI_MODEL="${OPENAI_MODEL:-glm-4.7-flash}" \
CLAUDE_CODE_ATTRIBUTION_HEADER="${CLAUDE_CODE_ATTRIBUTION_HEADER:-0}" \
claude -p "$prompt_contents" \
--verbose \
--output-format stream-json \
< /dev/null \
2>&1 \
| tee -a "$log_file" \
| jq -Rr '
def emit_text_blocks:
.message.content[]?
| select(.type == "text")
| .text, "\n";
. as $line
| try ($line | fromjson) catch empty
| if (.type == "assistant") then
emit_text_blocks
elif (.type == "stream_event"
and .event.type == "content_block_start"
and .event.content_block.type == "tool_use") then
"\n[tool] " + (.event.content_block.name // "unknown") + "\n"
elif (.type == "result") then
"\n"
else
empty
end
'
exit_code=${PIPESTATUS[0]}
kill "$heartbeat_pid" 2>/dev/null || true
wait "$heartbeat_pid" 2>/dev/null || true
end_epoch="$(date +%s)"
elapsed="$((end_epoch - start_epoch))"
usage_tsv="$(
jq -sr '
[
.[]
| ..
| objects
| select(has("usage"))
| .usage
]
| last // {}
| [
(.input_tokens // .prompt_tokens // .cache_creation_input_tokens // 0),
(.output_tokens // .completion_tokens // 0),
(.total_tokens // ((.input_tokens // .prompt_tokens // .cache_creation_input_tokens // 0) + (.output_tokens // .completion_tokens // 0)))
]
| @tsv
' "$log_file" 2>/dev/null
)"
if [[ -n "${usage_tsv:-}" ]]; then
prompt_tokens="$(printf '%s' "$usage_tsv" | cut -f1)"
completion_tokens="$(printf '%s' "$usage_tsv" | cut -f2)"
total_tokens="$(printf '%s' "$usage_tsv" | cut -f3)"
else
prompt_tokens="0"
completion_tokens="0"
total_tokens="0"
fi
set -e
{
echo
echo "------------------------------------------------------------"
echo "Claude run finished"
echo "Run: $run_num"
echo "Exit code: $exit_code"
echo "Elapsed seconds: $elapsed"
echo "Prompt tokens: $prompt_tokens"
echo "Completion tokens: $completion_tokens"
echo "Total tokens: $total_tokens"
echo "Finished: $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo "------------------------------------------------------------"
echo
} | tee -a "$log_file"
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" \
"$run_num" \
"$start_human" \
"$elapsed" \
"$exit_code" \
"$prompt_tokens" \
"$completion_tokens" \
"$total_tokens" \
"$log_file" >> "$SUMMARY_FILE"
echo "Sleeping ${SLEEP_SECS}s before next fresh run..." | tee -a "$log_file"
sleep "$SLEEP_SECS"
done
#!/usr/bin/env bash
set -euo pipefail
MODEL="${MODEL:-~/.ollama/models/unsloth/GLM-4.7-Flash-GGU/GLM-4.7-Flash-UD-Q5_K_XL.gguf}"
ALIAS="${ALIAS:-glm-4.7-flash}"
HOST="${HOST:-127.0.0.1}"
PORT="${PORT:-8001}"
CTX_SIZE="${CTX_SIZE:-65536}"
BATCH_SIZE="${BATCH_SIZE:-512}"
UBATCH_SIZE="${UBATCH_SIZE:-256}"
TEMP="${TEMP:-0.7}"
TOP_P="${TOP_P:-0.95}"
MIN_P="${MIN_P:-0.01}"
REPEAT_PENALTY="${REPEAT_PENALTY:-1.0}"
CACHE_TYPE_K="${CACHE_TYPE_K:-f16}"
CACHE_TYPE_V="${CACHE_TYPE_V:-f16}"
export OPENAI_API_KEY="${OPENAI_API_KEY:-sk-no-key-required}"
export OPENAI_BASE_URL="${OPENAI_BASE_URL:-http://${HOST}:${PORT}/v1}"
export OPENAI_MODEL="${OPENAI_MODEL:-${ALIAS}}"
export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-sk-no-key-required}"
export ANTHROPIC_BASE_URL="${ANTHROPIC_BASE_URL:-http://${HOST}:${PORT}}"
export ANTHROPIC_MODEL="${ANTHROPIC_MODEL:-${ALIAS}}"
mkdir -p "${HOME}/llama-slots/${ALIAS}-64k"
echo "Starting ${ALIAS} on ${HOST}:${PORT}"
echo "Context: ${CTX_SIZE} (Hermes/Claude)"
echo "Batch/Ubatch: ${BATCH_SIZE}/${UBATCH_SIZE}"
echo "Cache K/V: ${CACHE_TYPE_K}/${CACHE_TYPE_V}"
echo
exec "${HOME}/llama.cpp/build/bin/llama-server" \
-m "${MODEL}" \
--alias "${ALIAS}" \
--host "${HOST}" \
--port "${PORT}" \
--jinja \
--reasoning off \
-ngl -1 \
--flash-attn off \
--ctx-size "${CTX_SIZE}" \
--batch-size "${BATCH_SIZE}" \
--ubatch-size "${UBATCH_SIZE}" \
--cache-type-k "${CACHE_TYPE_K}" \
--cache-type-v "${CACHE_TYPE_V}" \
--parallel 1 \
--cont-batching \
--no-context-shift \
--no-mmap \
--temp "${TEMP}" \
--top-p "${TOP_P}" \
--min-p "${MIN_P}" \
--repeat-penalty "${REPEAT_PENALTY}" \
--slot-save-path "${HOME}/llama-slots/${ALIAS}-64k"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment