Skip to content

Commit 24dd8ea

Browse files
authored
feat: Add performance profiling CI workflow for ChatAgent overhead be… (#3636)
1 parent d08b203 commit 24dd8ea

File tree

2 files changed

+430
-0
lines changed

2 files changed

+430
-0
lines changed

.github/workflows/profiling.yml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Performance profiling workflow - runs every 2 days to detect performance regressions
2+
3+
name: Performance Profiling
4+
5+
on:
6+
schedule:
7+
- cron: '0 0 */2 * *'
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
profiling:
15+
runs-on: ubuntu-latest
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
benchmark:
20+
- name: chatagent_overhead
21+
script: profiling/chatagent_overhead.py
22+
description: "ChatAgent overhead vs direct API calls"
23+
num_runs: 20
24+
threshold: 2.0
25+
env:
26+
RESULT_FILE: profiling/results/${{ matrix.benchmark.name }}.json
27+
BASELINE_FILE: profiling/baselines/${{ matrix.benchmark.name }}.json
28+
29+
steps:
30+
- uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76
31+
with:
32+
egress-policy: audit
33+
34+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
35+
36+
- uses: ./.github/actions/camel_install
37+
with:
38+
python-version: "3.10"
39+
40+
- run: |
41+
source .venv/bin/activate
42+
uv pip install -e ".[all]"
43+
44+
- uses: actions/cache@v4
45+
with:
46+
path: ${{ env.BASELINE_FILE }}
47+
key: profiling-${{ matrix.benchmark.name }}-${{ github.ref_name }}
48+
restore-keys: profiling-${{ matrix.benchmark.name }}-
49+
50+
- name: Run benchmark
51+
env:
52+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
53+
run: |
54+
source .venv/bin/activate
55+
mkdir -p profiling/results profiling/baselines
56+
python ${{ matrix.benchmark.script }} --num-runs ${{ matrix.benchmark.num_runs }} --output "$RESULT_FILE" --quiet
57+
58+
- name: Check regression and create summary
59+
env:
60+
THRESHOLD: ${{ matrix.benchmark.threshold }}
61+
run: |
62+
echo "## ${{ matrix.benchmark.description }}" >> $GITHUB_STEP_SUMMARY
63+
64+
if [ ! -f "$RESULT_FILE" ]; then
65+
echo "❌ Benchmark failed" >> $GITHUB_STEP_SUMMARY
66+
exit 1
67+
fi
68+
69+
# Show current results
70+
echo "### Results (threshold: ${THRESHOLD}x)" >> $GITHUB_STEP_SUMMARY
71+
echo "| Mode | Current (ms) | Baseline (ms) | Ratio | API Calls | Status |" >> $GITHUB_STEP_SUMMARY
72+
echo "|------|--------------|---------------|-------|-----------|--------|" >> $GITHUB_STEP_SUMMARY
73+
74+
FAILED=false
75+
for mode in $(jq -r '.metrics | keys[]' "$RESULT_FILE"); do
76+
CURRENT=$(jq -r ".metrics.\"$mode\".avg_overhead_ms" "$RESULT_FILE")
77+
EXPECTED_CALLS=$(jq -r ".metrics.\"$mode\".expected_api_calls" "$RESULT_FILE")
78+
INVALID_RUNS=$(jq -r ".metrics.\"$mode\".invalid_api_call_runs" "$RESULT_FILE")
79+
80+
# Check API call count
81+
if [ "$INVALID_RUNS" -gt 0 ]; then
82+
API_STATUS="❌ ${INVALID_RUNS} invalid"
83+
FAILED=true
84+
else
85+
API_STATUS="✅ ${EXPECTED_CALLS}/call"
86+
fi
87+
88+
# Check regression
89+
if [ -f "$BASELINE_FILE" ]; then
90+
BASELINE=$(jq -r ".metrics.\"$mode\".avg_overhead_ms // empty" "$BASELINE_FILE")
91+
if [ -n "$BASELINE" ] && [ "$BASELINE" != "null" ]; then
92+
RATIO=$(awk "BEGIN {printf \"%.2f\", $CURRENT / $BASELINE}")
93+
if awk "BEGIN {exit !($RATIO > $THRESHOLD)}"; then
94+
STATUS="❌ REGRESSION"
95+
FAILED=true
96+
else
97+
STATUS="✅ OK"
98+
fi
99+
echo "| $mode | $CURRENT | $BASELINE | ${RATIO}x | $API_STATUS | $STATUS |" >> $GITHUB_STEP_SUMMARY
100+
continue
101+
fi
102+
fi
103+
echo "| $mode | $CURRENT | - | - | $API_STATUS | 🆕 New |" >> $GITHUB_STEP_SUMMARY
104+
done
105+
106+
if [ "$FAILED" = "true" ]; then
107+
echo "" >> $GITHUB_STEP_SUMMARY
108+
echo "❌ **Check failed!**" >> $GITHUB_STEP_SUMMARY
109+
exit 1
110+
fi
111+
112+
- name: Update baseline
113+
if: success()
114+
run: cp "$RESULT_FILE" "$BASELINE_FILE"
115+
116+
- uses: actions/cache/save@v4
117+
if: success()
118+
with:
119+
path: ${{ env.BASELINE_FILE }}
120+
key: profiling-${{ matrix.benchmark.name }}-${{ github.ref_name }}-${{ github.run_id }}
121+
122+
- uses: actions/upload-artifact@v4
123+
if: always()
124+
with:
125+
name: profiling-${{ matrix.benchmark.name }}
126+
path: profiling/results/${{ matrix.benchmark.name }}.json
127+
retention-days: 90

0 commit comments

Comments
 (0)