Skip to content

Commit 0d14967

Browse files
author
Trinity Agent
committed
fix(cloud): pipefail, exit codes via tee, HTML escape, rate limit (#137)
Fixes bugs from PR #133: - Change shebang from /bin/sh to /bin/bash for pipefail support - Add set -o pipefail for proper error handling in pipes - Fix Claude Code pipe with tee + PIPESTATUS to capture exit code correctly - Fix test pipe with tee + temp file to preserve exit code - Add HTML escaping for Telegram messages to handle < > & chars - Add rate limit protection (3s minimum) to send_telegram and stream_to_telegram Closes #137
1 parent 09e117a commit 0d14967

1 file changed

Lines changed: 48 additions & 5 deletions

File tree

deploy/agent-entrypoint.sh

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
#!/bin/sh
1+
#!/bin/bash
22
# Trinity Cloud Agent Entrypoint
33
# Solves a single GitHub issue using Claude Code
44
# Required env: ISSUE_NUMBER, GITHUB_TOKEN, ANTHROPIC_API_KEY
55
#
66
# P0 hardened: timeout, SIGTERM handler, heartbeat loop, retry wrapper
77

88
set -e
9+
set -o pipefail
910

1011
REPO_URL="${REPO_URL:-https://github.com/gHashTag/trinity.git}"
1112
ISSUE="${ISSUE_NUMBER:?ISSUE_NUMBER is required}"
@@ -14,6 +15,7 @@ HEARTBEAT_INTERVAL="${HEARTBEAT_INTERVAL:-30}"
1415
CURRENT_STATUS="STARTING"
1516
CURRENT_DETAIL="Initializing"
1617
HEARTBEAT_PID=""
18+
LAST_TELEGRAM_SEND=0
1719

1820
log() { echo "[agent-${ISSUE}] $1"; }
1921

@@ -104,11 +106,41 @@ report_status() {
104106

105107
send_telegram() {
106108
if [ -n "${TELEGRAM_BOT_TOKEN}" ] && [ -n "${TELEGRAM_CHAT_ID}" ]; then
109+
# HTML escape for Telegram
110+
local escaped=$(echo -e "$1" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')
111+
# Rate limit protection: minimum 3 seconds between sends
112+
local now=$(date +%s)
113+
local diff=$((now - LAST_TELEGRAM_SEND))
114+
if [ $diff -lt 3 ]; then
115+
log "Skipping telegram send (rate limited, ${diff}s since last send)"
116+
return
117+
fi
107118
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
108119
-H "Content-Type: application/json" \
109-
-d "{\"chat_id\":\"${TELEGRAM_CHAT_ID}\",\"text\":\"$1\",\"parse_mode\":\"HTML\"}" \
120+
-d "{\"chat_id\":\"${TELEGRAM_CHAT_ID}\",\"text\":\"${escaped}\",\"parse_mode\":\"HTML\"}" \
110121
--connect-timeout 5 --max-time 10 \
111122
2>/dev/null || log "Warning: Telegram send failed"
123+
LAST_TELEGRAM_SEND=$now
124+
fi
125+
}
126+
127+
stream_to_telegram() {
128+
local line="$1"
129+
# Stream line to telegram with HTML escaping
130+
if [ -n "${TELEGRAM_BOT_TOKEN}" ] && [ -n "${TELEGRAM_CHAT_ID}" ]; then
131+
local escaped=$(echo -e "${line}" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' | head -c 3900)
132+
# Rate limit protection
133+
local now=$(date +%s)
134+
local diff=$((now - LAST_TELEGRAM_SEND))
135+
if [ $diff -lt 3 ]; then
136+
return
137+
fi
138+
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
139+
-H "Content-Type: application/json" \
140+
-d "{\"chat_id\":\"${TELEGRAM_CHAT_ID}\",\"text\":\"${escaped}\"}" \
141+
--connect-timeout 2 --max-time 5 \
142+
2>/dev/null || true
143+
LAST_TELEGRAM_SEND=$now
112144
fi
113145
}
114146

@@ -294,8 +326,13 @@ Instructions:
294326
Comment on the issue at each major step."
295327

296328
emit_event "status" '{"status":"CODING","detail":"Claude Code starting"}'
297-
CLAUDE_EXIT=0
298-
timeout "${AGENT_TIMEOUT}" claude -p "${PROMPT}" --allowedTools "Bash,Read,Write,Edit,Glob,Grep" 2>&1 || CLAUDE_EXIT=$?
329+
CLAUDE_LOG="/tmp/claude_output_${ISSUE}.log"
330+
timeout "${AGENT_TIMEOUT}" claude -p "${PROMPT}" --allowedTools "Bash,Read,Write,Edit,Glob,Grep" 2>&1 | \
331+
tee "${CLAUDE_LOG}" | \
332+
while IFS= read -r line; do
333+
stream_to_telegram "${line}"
334+
done
335+
CLAUDE_EXIT=${PIPESTATUS[0]:-$?}
299336
emit_event "command" "{\"cmd\":\"claude\",\"exit_code\":${CLAUDE_EXIT},\"timeout\":${AGENT_TIMEOUT}}"
300337

301338
if [ "${CLAUDE_EXIT}" -eq 124 ]; then
@@ -307,7 +344,13 @@ fi
307344

308345
# === 6b. Run tests and capture results ===
309346
report_status "TESTING" "Running zig build test"
310-
TEST_OUTPUT=$(zig build test 2>&1) && TEST_EXIT=0 || TEST_EXIT=$?
347+
TEST_LOG="/tmp/test_output_${ISSUE}.log"
348+
zig build test 2>&1 | tee "${TEST_LOG}" | \
349+
while IFS= read -r line; do
350+
stream_to_telegram "${line}"
351+
done
352+
TEST_EXIT=${PIPESTATUS[0]:-$?}
353+
TEST_OUTPUT=$(cat "${TEST_LOG}")
311354
TESTS_PASSED=$(echo "${TEST_OUTPUT}" | grep -c "OK" || echo "0")
312355
TESTS_TOTAL=$(echo "${TEST_OUTPUT}" | grep -cE "OK|FAIL" || echo "0")
313356
if [ "${TEST_EXIT}" -ne 0 ]; then

0 commit comments

Comments
 (0)