Skip to content

Commit 04ba403

Browse files
committed
Update diff parameters for faster processing and reduced timeout
1 parent 6b6a7cf commit 04ba403

File tree

1 file changed

+95
-46
lines changed

1 file changed

+95
-46
lines changed

β€Žgit-commit-push-script.shβ€Ž

Lines changed: 95 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22
source ~/.bash_profile
33

44
# Configuration
5-
MAX_DIFF_CHARS=2000 # Truncate diff to prevent long processing
6-
TIMEOUT_SECONDS=120 # Max time to wait for LLM response (14B model can take 60-90s on first token)
7-
MAX_COMMIT_LENGTH=50 # Max characters for commit message
5+
MAX_DIFF_CHARS=600 # stripped +/- lines only β€” keeps 1.5B prefill fast
6+
TIMEOUT_SECONDS=60 # 60s covers multi-file commits on the 1.5B model
7+
MAX_COMMIT_LENGTH=72 # Standard git commit length
88

9-
# Squish model selection β€” set SQUISH_MODEL to target a specific compressed model.
10-
# Accepts a name hint (e.g. "14b", "7b") or a full path to a model directory.
11-
# Leave empty to let squish auto-detect (uses the first available model in ~/models).
12-
# Examples:
13-
# SQUISH_MODEL="14b" # matches Qwen2.5-14B-*
14-
# SQUISH_MODEL="$HOME/models/Qwen2.5-14B-Instruct-bf16" # explicit path
15-
SQUISH_MODEL="${SQUISH_MODEL:-}"
9+
# Squish model selection.
10+
# 7B runs at 15-25 tok/s on M3 16GB (comfortably fits in memory).
11+
# 14B is too slow on 16GB β€” use it only if you have 32GB+ RAM.
12+
# Override: SQUISH_MODEL=14b cm
13+
SQUISH_MODEL="${SQUISH_MODEL:-7b}"
1614

17-
# Squish server port β€” override if you run multiple squish servers concurrently.
18-
SQUISH_PORT="${SQUISH_PORT:-8000}"
15+
# Squish server port β€” must match the port squish is started with.
16+
# CLI default is 11435; override with SQUISH_PORT env var.
17+
SQUISH_PORT="${SQUISH_PORT:-11435}"
1918

2019
# Colors
2120
RED='\033[0;31m'
@@ -30,25 +29,35 @@ BOLD='\033[1m'
3029
DIM='\033[2m'
3130
NC='\033[0m' # No Color
3231

33-
# Animated spinner with colors
34-
spinner() {
32+
# Snake spinner β€” cycling snake glyphs while waiting.
33+
# Usage: snake_spinner PID [label]
34+
# PID = 0 β†’ run until killed (for server-start polling)
35+
# PID > 0 β†’ run until that process exits (for curl/LLM wait)
36+
snake_spinner() {
3537
local pid=$1
36-
local delay=0.08
38+
local label="${2:-Generating commit message}"
3739
local frames=('⣾' '⣽' '⣻' 'Ⓙ' '⑿' '⣟' '⣯' '⣷')
38-
local colors=("$CYAN" "$BLUE" "$PURPLE" "$CYAN" "$BLUE" "$PURPLE" "$CYAN" "$BLUE")
39-
local i=0
40-
local elapsed=0
41-
42-
while ps -p $pid > /dev/null 2>&1; do
43-
printf "\r${colors[$i]}${frames[$i]}${NC} ${WHITE}Generating commit message${NC}${GRAY}...${NC} ${DIM}(${elapsed}s)${NC} "
44-
sleep $delay
45-
i=$(( (i + 1) % ${#frames[@]} ))
46-
elapsed=$(echo "scale=1; $elapsed + $delay" | bc)
47-
if ! ps -p $pid > /dev/null 2>&1; then
40+
local col_arr=("$CYAN" "$BLUE" "$PURPLE" "$CYAN" "$BLUE" "$PURPLE" "$CYAN" "$BLUE")
41+
local nf=${#frames[@]}
42+
local ncol=${#col_arr[@]}
43+
local i=0 step=0
44+
local delay=0.08
45+
local elapsed="0.0"
46+
47+
while true; do
48+
if [ "$pid" -ne 0 ] && ! ps -p "$pid" > /dev/null 2>&1; then
4849
break
4950
fi
51+
52+
local c="${col_arr[$i]}"
53+
printf "\r${c}${frames[$i]}${NC} ${WHITE}${label}${NC}${GRAY}...${NC} ${DIM}(${elapsed}s)${NC} "
54+
55+
sleep "$delay"
56+
i=$(( (i + 1) % nf ))
57+
step=$(( step + 1 ))
58+
elapsed=$(echo "scale=1; $step * $delay" | bc)
5059
done
51-
printf "\r${GREEN}βœ“${NC} ${WHITE}Done!${NC} \n"
60+
printf "\r${GREEN}βœ“${NC} ${WHITE}Done!${NC} \n"
5261
}
5362

5463
# Status messages
@@ -152,11 +161,17 @@ if [ -n "$SQUISH_PORT" ]; then
152161
fi
153162

154163
# ── Debug: squish availability ───────────────────────────────────────────
155-
# squish may be a zsh alias (not visible to bash scripts) β€” fall back to
156-
# calling cli.py directly with python3 if the command isn't on PATH.
164+
# squish is typically a zsh alias (not visible to bash scripts) β€” fall back to
165+
# calling squish/cli.py directly with python3 if the command isn't on PATH.
166+
# Also export SQUISH_MODELS_DIR so the CLI finds models in the squish repo.
167+
export SQUISH_MODELS_DIR="${SQUISH_MODELS_DIR:-$HOME/squish/models}"_SQUISH_CLI="/Users/wscholl/squish/squish/cli.py"
157168
SQUISH_BIN=$(command -v squish 2>/dev/null)
158-
if [ -z "$SQUISH_BIN" ] && [ -f "/Users/wscholl/squish/cli.py" ]; then
159-
SQUISH_BIN="python3 /Users/wscholl/squish/cli.py"
169+
# command -v may return an alias definition string in some shells β€” treat that as not-found
170+
if echo "$SQUISH_BIN" | grep -q '^alias '; then
171+
SQUISH_BIN=""
172+
fi
173+
if [ -z "$SQUISH_BIN" ] && [ -f "$_SQUISH_CLI" ]; then
174+
SQUISH_BIN="python3 $_SQUISH_CLI"
160175
print_info "squish binary: ${CYAN}$SQUISH_BIN${GRAY} (alias not in bash PATH, using direct path)${NC}"
161176
elif [ -n "$SQUISH_BIN" ]; then
162177
print_info "squish binary: ${CYAN}$SQUISH_BIN${NC}"
@@ -183,11 +198,17 @@ if [ -n "$SQUISH_BIN" ]; then
183198
# Start the server in the background and wait for it
184199
$SQUISH_BIN serve ${SQUISH_MODEL:+--model $SQUISH_MODEL} --port "$_port" > /tmp/squish_serve.log 2>&1 &
185200
_serve_pid=$!
201+
# Run snake spinner in background while polling for server readiness
202+
snake_spinner 0 "Starting squish server" &
203+
_snake_pid=$!
186204
_waited=0
187205
while [ $_waited -lt 90 ] && ! nc -z 127.0.0.1 "$_port" 2>/dev/null; do
188206
sleep 1
189207
_waited=$((_waited + 1))
190208
done
209+
kill "$_snake_pid" 2>/dev/null
210+
wait "$_snake_pid" 2>/dev/null
211+
printf "\r \r"
191212
if ! nc -z 127.0.0.1 "$_port" 2>/dev/null; then
192213
print_warning "Server failed to start. Using fallback message."
193214
commit_message="$fallback_message"
@@ -198,57 +219,85 @@ if [ -n "$SQUISH_BIN" ]; then
198219
echo ""
199220

200221
if [ -z "$commit_message" ]; then
201-
# Build a focused prompt β€” only the stat summary + truncated diff,
202-
# no surrounding debug text that could confuse the model.
222+
# Build a focused prompt β€” stat summary + truncated diff
203223
stat_summary=$(git diff --cached --stat | tail -1)
204224
changed_names=$(git diff --cached --name-only | head -10 | tr '\n' ' ')
205225

206-
# Write diff to a temp file so Python can read it without any
207-
# shell-interpolation escaping issues (newlines, backslashes, etc.)
226+
# Write diff to a temp file so Python reads it safely
208227
echo "$diff" > /tmp/squish_diff.txt
209228

210229
# Use python3 to build the JSON payload β€” all values go through
211230
# json.dumps() so control characters are properly escaped.
212-
PAYLOAD=$(SQUISH_CHANGED="$changed_names" SQUISH_STAT="$stat_summary" \
231+
PAYLOAD=$(SQUISH_CHANGED="$changed_names" SQUISH_STAT="$stat_summary" MAX_DIFF_CHARS="$MAX_DIFF_CHARS" \
213232
python3 - <<'PYEOF'
214-
import json, os
233+
import json, os, re
234+
235+
def strip_diff(raw: str, max_chars: int) -> str:
236+
"""Keep only added/removed lines; skip headers and unchanged context."""
237+
lines = []
238+
for line in raw.splitlines():
239+
# +++ / --- are file headers β€” skip
240+
if line.startswith("---") or line.startswith("+++"):
241+
continue
242+
# @@ hunk headers β€” include as section markers but shorten
243+
if line.startswith("@@"):
244+
lines.append(line.split("@@")[-1].strip() or "~~")
245+
continue
246+
# diff --git / index headers β€” skip
247+
if line.startswith("diff ") or line.startswith("index ") or line.startswith("new file") or line.startswith("deleted file"):
248+
continue
249+
# Keep + / - changed lines, drop unchanged context lines
250+
if line.startswith("+") or line.startswith("-"):
251+
lines.append(line)
252+
return "\n".join(lines)[:max_chars]
253+
254+
diff_raw = open("/tmp/squish_diff.txt").read()
255+
diff = strip_diff(diff_raw, int(os.environ.get("MAX_DIFF_CHARS", "1200")))
256+
215257
system = (
216-
"You generate concise git commit messages. "
217-
"Reply with ONLY the commit message, nothing else. "
218-
"Max 50 characters. Imperative mood. No period. No quotes. No markdown."
258+
"You are a git commit message writer. "
259+
"Read the diff and write ONE concise commit message describing what actually changed. "
260+
"Reply with ONLY the commit message β€” no labels, no filenames, no markdown, no period. "
261+
"Must be a complete thought under 72 characters. Imperative mood (e.g. 'Add', 'Fix', 'Update', 'Remove')."
219262
)
220-
diff = open("/tmp/squish_diff.txt").read()
221263
user = (
222-
f"Files changed: {os.environ['SQUISH_CHANGED']}\n"
223-
f"Summary: {os.environ['SQUISH_STAT']}\n\n"
224-
f"Diff:\n{diff}\n\nCommit message:"
264+
f"Files: {os.environ['SQUISH_CHANGED']}\n"
265+
f"Stat: {os.environ['SQUISH_STAT']}\n\n"
266+
f"Changed lines:\n{diff}\n"
267+
"--- END DIFF ---\n\n"
268+
"Commit message (imperative, < 72 chars):"
225269
)
226270
print(json.dumps({
227271
"model": "squish",
228272
"messages": [
229273
{"role": "system", "content": system},
230274
{"role": "user", "content": user},
231275
],
232-
"max_tokens": 60,
276+
"max_tokens": 50,
233277
"temperature": 0.2,
234278
"stream": False,
279+
"stop": ["\n", "\r"],
235280
}))
236281
PYEOF
237282
)
238283
rm -f /tmp/squish_diff.txt
239284

240285
# Run squish with timeout and spinner
241286
print_step "Asking AI for commit message (Squish local LLM)..."
242-
_port="${SQUISH_PORT:-8000}"
287+
_port="${SQUISH_PORT:-11435}"
288+
_llm_start=$(date +%s%3N)
243289
curl -s --max-time $TIMEOUT_SECONDS \
244290
-X POST "http://127.0.0.1:${_port}/v1/chat/completions" \
245291
-H "Content-Type: application/json" \
292+
-H "Authorization: Bearer ${SQUISH_API_KEY:-squish}" \
246293
-d "$PAYLOAD" 2>/tmp/squish_stderr.txt \
247294
> /tmp/squish_response.txt &
248295
LLM_PID=$!
249-
spinner $LLM_PID
296+
snake_spinner $LLM_PID "Generating commit message"
250297
wait $LLM_PID
251298
exit_code=$?
299+
_llm_elapsed=$(echo "scale=2; ($(date +%s%3N) - $_llm_start) / 1000" | bc)
300+
print_info "model response time: ${CYAN}${_llm_elapsed}s${NC}"
252301

253302
# ── Debug: result diagnostics ─────────────────────────────────────────
254303
raw_response=$(cat /tmp/squish_response.txt 2>/dev/null)

0 commit comments

Comments
Β (0)