惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
博客园 - 司徒正美
A
About on SuperTechFans
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
爱范儿
爱范儿
I
InfoQ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
F
Fortinet All Blogs
S
SegmentFault 最新的问题
阮一峰的网络日志
阮一峰的网络日志
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
M
MIT News - Artificial intelligence
Jina AI
Jina AI
H
Help Net Security
量子位
IT之家
IT之家

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
ci: add OpenClaw performance reports · openclaw/openclaw@...
steipete · 2026-05-02 · via Recent Commits to openclaw:main

@@ -0,0 +1,335 @@

1+

name: OpenClaw Performance

2+3+

on:

4+

schedule:

5+

- cron: "11 5 * * *"

6+

workflow_dispatch:

7+

inputs:

8+

profile:

9+

description: Kova profile to run

10+

required: false

11+

default: diagnostic

12+

type: choice

13+

options:

14+

- smoke

15+

- diagnostic

16+

- soak

17+

- release

18+

repeat:

19+

description: Repeat count for non-profiled Kova runs

20+

required: false

21+

default: "3"

22+

type: string

23+

deep_profile:

24+

description: Run the deep-profile lane with CPU/heap/trace artifacts

25+

required: false

26+

default: false

27+

type: boolean

28+

live_gpt54:

29+

description: Run the live OpenAI GPT 5.4 agent-turn lane

30+

required: false

31+

default: false

32+

type: boolean

33+

fail_on_regression:

34+

description: Fail the workflow when Kova exits non-zero

35+

required: false

36+

default: false

37+

type: boolean

38+

kova_ref:

39+

description: Kova Git ref to install

40+

required: false

41+

default: 51947110f5cacb6ab2c0947594ea9628031c9fcf

42+

type: string

43+44+

permissions:

45+

contents: read

46+47+

concurrency:

48+

group: ${{ github.event_name == 'workflow_dispatch' && format('{0}-{1}', github.workflow, github.run_id) || format('{0}-{1}', github.workflow, github.ref) }}

49+

cancel-in-progress: false

50+51+

env:

52+

FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"

53+

OCM_VERSION: v0.2.15

54+

PERFORMANCE_MODEL_ID: gpt-5.4

55+

CLAWGRIT_REPORTS_TOKEN_PRESENT: ${{ secrets.CLAWGRIT_REPORTS_TOKEN != '' && 'true' || 'false' }}

56+57+

jobs:

58+

kova:

59+

name: ${{ matrix.title }}

60+

runs-on: blacksmith-16vcpu-ubuntu-2404

61+

timeout-minutes: 240

62+

strategy:

63+

fail-fast: false

64+

matrix:

65+

include:

66+

- lane: mock-provider

67+

title: Kova mock provider performance

68+

auth: mock

69+

repeat: input

70+

deep_profile: "false"

71+

live: "false"

72+

include_filters: "scenario:fresh-install scenario:gateway-performance scenario:bundled-plugin-startup scenario:bundled-runtime-deps scenario:agent-cold-warm-message"

73+

- lane: mock-deep-profile

74+

title: Kova mock provider deep profile

75+

auth: mock

76+

repeat: "1"

77+

deep_profile: "true"

78+

live: "false"

79+

include_filters: "scenario:fresh-install scenario:gateway-performance scenario:agent-cold-warm-message"

80+

- lane: live-gpt54

81+

title: Kova live OpenAI GPT 5.4 agent turn

82+

auth: live

83+

repeat: "1"

84+

deep_profile: "false"

85+

live: "true"

86+

include_filters: "scenario:agent-cold-warm-message"

87+

env:

88+

KOVA_REF: ${{ inputs.kova_ref || '51947110f5cacb6ab2c0947594ea9628031c9fcf' }}

89+

KOVA_HOME: ${{ github.workspace }}/.artifacts/kova/home/${{ matrix.lane }}

90+

REPORT_DIR: ${{ github.workspace }}/.artifacts/kova/reports/${{ matrix.lane }}

91+

BUNDLE_DIR: ${{ github.workspace }}/.artifacts/kova/bundles/${{ matrix.lane }}

92+

SUMMARY_DIR: ${{ github.workspace }}/.artifacts/kova/summaries

93+

LANE_ID: ${{ matrix.lane }}

94+

PROFILE: ${{ inputs.profile || 'diagnostic' }}

95+

REQUESTED_REPEAT: ${{ inputs.repeat || '3' }}

96+

FAIL_ON_REGRESSION: ${{ inputs.fail_on_regression || 'false' }}

97+

INCLUDE_FILTERS: ${{ matrix.include_filters }}

98+

AUTH_MODE: ${{ matrix.auth }}

99+

MATRIX_REPEAT: ${{ matrix.repeat }}

100+

MATRIX_DEEP_PROFILE: ${{ matrix.deep_profile }}

101+

MATRIX_LIVE: ${{ matrix.live }}

102+

steps:

103+

- name: Decide lane

104+

id: lane

105+

shell: bash

106+

run: |

107+

set -euo pipefail

108+

run_lane=true

109+

reason=""

110+

if [[ "$LANE_ID" == "mock-deep-profile" && "${{ github.event_name }}" != "schedule" && "${{ inputs.deep_profile || 'false' }}" != "true" ]]; then

111+

run_lane=false

112+

reason="deep_profile input is false"

113+

fi

114+

if [[ "$LANE_ID" == "live-gpt54" && "${{ github.event_name }}" != "schedule" && "${{ inputs.live_gpt54 || 'false' }}" != "true" ]]; then

115+

run_lane=false

116+

reason="live_gpt54 input is false"

117+

fi

118+

echo "run=$run_lane" >> "$GITHUB_OUTPUT"

119+

if [[ "$run_lane" != "true" ]]; then

120+

echo "Skipping ${LANE_ID}: ${reason}" >> "$GITHUB_STEP_SUMMARY"

121+

fi

122+123+

- name: Checkout OpenClaw

124+

if: steps.lane.outputs.run == 'true'

125+

uses: actions/checkout@v6

126+

with:

127+

fetch-depth: 1

128+

persist-credentials: false

129+130+

- name: Set up Node environment

131+

if: steps.lane.outputs.run == 'true'

132+

uses: ./.github/actions/setup-node-env

133+

with:

134+

install-bun: "false"

135+136+

- name: Install OCM and Kova

137+

if: steps.lane.outputs.run == 'true'

138+

shell: bash

139+

run: |

140+

set -euo pipefail

141+

KOVA_SRC="${RUNNER_TEMP}/kova-src"

142+

echo "KOVA_SRC=$KOVA_SRC" >> "$GITHUB_ENV"

143+

mkdir -p "$HOME/.local/bin" "$(dirname "$KOVA_SRC")"

144+

curl -fsSL https://raw.githubusercontent.com/shakkernerd/ocm/main/install.sh \

145+

| bash -s -- --version "$OCM_VERSION" --prefix "$HOME/.local" --force

146+

git clone --filter=blob:none https://github.com/shakkernerd/Kova.git "$KOVA_SRC"

147+

git -C "$KOVA_SRC" checkout "$KOVA_REF"

148+

cat > "$HOME/.local/bin/kova" <<EOF

149+

#!/usr/bin/env bash

150+

export KOVA_HOME="${KOVA_HOME}"

151+

exec node "${KOVA_SRC}/bin/kova.mjs" "\$@"

152+

EOF

153+

chmod 0755 "$HOME/.local/bin/kova"

154+

echo "$HOME/.local/bin" >> "$GITHUB_PATH"

155+156+

- name: Pin Kova OpenAI model to GPT 5.4

157+

if: steps.lane.outputs.run == 'true'

158+

shell: bash

159+

run: |

160+

set -euo pipefail

161+

node - <<'NODE'

162+

const fs = require("node:fs");

163+

const path = require("node:path");

164+

const root = process.env.KOVA_SRC;

165+

const files = [

166+

"support/configure-openclaw-mock-auth.mjs",

167+

"support/configure-openclaw-live-auth.mjs",

168+

"support/mock-openai-server.mjs",

169+

"states/mock-openai-provider.json"

170+

];

171+

for (const rel of files) {

172+

const file = path.join(root, rel);

173+

const before = fs.readFileSync(file, "utf8");

174+

const after = before.replaceAll("gpt-5.5", process.env.PERFORMANCE_MODEL_ID);

175+

fs.writeFileSync(file, after, "utf8");

176+

}

177+

NODE

178+179+

- name: Kova self-check

180+

if: steps.lane.outputs.run == 'true'

181+

run: kova self-check --json

182+183+

- name: Configure live OpenAI auth

184+

if: ${{ steps.lane.outputs.run == 'true' && matrix.live == 'true' }}

185+

env:

186+

OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

187+

OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}

188+

shell: bash

189+

run: |

190+

set -euo pipefail

191+

if [[ -z "${OPENAI_API_KEY:-}" ]]; then

192+

echo "OPENAI_API_KEY is not configured; live GPT 5.4 lane will be skipped." >> "$GITHUB_STEP_SUMMARY"

193+

exit 0

194+

fi

195+

kova setup --ci --json

196+

kova setup --non-interactive --auth env-only --provider openai --env-var OPENAI_API_KEY --json

197+198+

- name: Run Kova

199+

id: kova

200+

if: steps.lane.outputs.run == 'true'

201+

env:

202+

OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

203+

OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}

204+

shell: bash

205+

run: |

206+

set -euo pipefail

207+

mkdir -p "$REPORT_DIR" "$BUNDLE_DIR" "$SUMMARY_DIR"

208+209+

if [[ "$MATRIX_LIVE" == "true" && -z "${OPENAI_API_KEY:-}" ]]; then

210+

echo "skipped=true" >> "$GITHUB_OUTPUT"

211+

exit 0

212+

fi

213+214+

repeat="$REQUESTED_REPEAT"

215+

if [[ "$MATRIX_REPEAT" != "input" ]]; then

216+

repeat="$MATRIX_REPEAT"

217+

fi

218+219+

args=(

220+

matrix run

221+

--profile "$PROFILE"

222+

--target "local-build:${GITHUB_WORKSPACE}"

223+

--auth "$AUTH_MODE"

224+

--parallel 1

225+

--repeat "$repeat"

226+

--report-dir "$REPORT_DIR"

227+

--execute

228+

--json

229+

)

230+231+

for filter in $INCLUDE_FILTERS; do

232+

args+=(--include "$filter")

233+

done

234+235+

if [[ "$MATRIX_DEEP_PROFILE" == "true" ]]; then

236+

args+=(--deep-profile)

237+

fi

238+

if [[ "$FAIL_ON_REGRESSION" == "true" ]]; then

239+

args+=(--gate)

240+

fi

241+242+

log_path="$REPORT_DIR/${LANE_ID}.log"

243+

set +e

244+

kova "${args[@]}" 2>&1 | tee "$log_path"

245+

status=${PIPESTATUS[0]}

246+

set -e

247+248+

report_json="$(find "$REPORT_DIR" -maxdepth 1 -type f -name '*.json' -print | sort | tail -n 1)"

249+

if [[ -z "$report_json" ]]; then

250+

echo "Kova did not write a JSON report." >&2

251+

exit 1

252+

fi

253+

report_md="${report_json%.json}.md"

254+

echo "status=$status" >> "$GITHUB_OUTPUT"

255+

echo "report_json=$report_json" >> "$GITHUB_OUTPUT"

256+

echo "report_md=$report_md" >> "$GITHUB_OUTPUT"

257+258+

kova report bundle "$report_json" --output-dir "$BUNDLE_DIR" --json | tee "$BUNDLE_DIR/bundle.json"

259+260+

ref_slug="$(printf '%s' "${GITHUB_REF_NAME}" | tr -c 'A-Za-z0-9._-' '-')"

261+

run_slug="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"

262+

report_url=""

263+

if [[ "$CLAWGRIT_REPORTS_TOKEN_PRESENT" == "true" ]]; then

264+

report_url="https://github.com/openclaw/clawgrit-reports/tree/main/openclaw-performance/${ref_slug}/${run_slug}/${LANE_ID}"

265+

fi

266+

summary_path="$SUMMARY_DIR/${LANE_ID}.md"

267+

node scripts/kova-ci-summary.mjs --report "$report_json" --output "$summary_path" --lane "$LANE_ID" --report-url "$report_url"

268+

cat "$summary_path" >> "$GITHUB_STEP_SUMMARY"

269+270+

if [[ "$FAIL_ON_REGRESSION" == "true" && "$status" != "0" ]]; then

271+

exit "$status"

272+

fi

273+274+

- name: Upload Kova artifacts

275+

if: ${{ always() && steps.lane.outputs.run == 'true' }}

276+

uses: actions/upload-artifact@v5

277+

with:

278+

name: openclaw-performance-${{ matrix.lane }}-${{ github.run_id }}-${{ github.run_attempt }}

279+

path: |

280+

.artifacts/kova/reports/${{ matrix.lane }}

281+

.artifacts/kova/bundles/${{ matrix.lane }}

282+

.artifacts/kova/summaries/${{ matrix.lane }}.md

283+

if-no-files-found: ignore

284+

retention-days: ${{ matrix.deep_profile == 'true' && 14 || 30 }}

285+286+

- name: Checkout clawgrit reports

287+

if: ${{ steps.kova.outputs.report_json != '' && env.CLAWGRIT_REPORTS_TOKEN_PRESENT == 'true' }}

288+

uses: actions/checkout@v6

289+

with:

290+

repository: openclaw/clawgrit-reports

291+

path: .artifacts/clawgrit-reports

292+

token: ${{ secrets.CLAWGRIT_REPORTS_TOKEN }}

293+

persist-credentials: true

294+295+

- name: Publish to clawgrit reports

296+

if: ${{ steps.kova.outputs.report_json != '' && env.CLAWGRIT_REPORTS_TOKEN_PRESENT == 'true' }}

297+

shell: bash

298+

run: |

299+

set -euo pipefail

300+

reports_root=".artifacts/clawgrit-reports"

301+

ref_slug="$(printf '%s' "${GITHUB_REF_NAME}" | tr -c 'A-Za-z0-9._-' '-')"

302+

run_slug="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"

303+

dest="${reports_root}/openclaw-performance/${ref_slug}/${run_slug}/${LANE_ID}"

304+

mkdir -p "$dest"

305+

cp "${{ steps.kova.outputs.report_json }}" "$dest/report.json"

306+

if [[ -f "${{ steps.kova.outputs.report_md }}" ]]; then

307+

cp "${{ steps.kova.outputs.report_md }}" "$dest/report.md"

308+

fi

309+

cp "$SUMMARY_DIR/${LANE_ID}.md" "$dest/index.md"

310+

if [[ -d "$BUNDLE_DIR" ]]; then

311+

mkdir -p "$dest/bundles"

312+

cp -R "$BUNDLE_DIR"/. "$dest/bundles/"

313+

fi

314+

cat > "${reports_root}/openclaw-performance/${ref_slug}/latest-${LANE_ID}.json" <<EOF

315+

{

316+

"repository": "${GITHUB_REPOSITORY}",

317+

"ref": "${GITHUB_REF_NAME}",

318+

"sha": "${GITHUB_SHA}",

319+

"workflow": "${GITHUB_WORKFLOW}",

320+

"run_id": "${GITHUB_RUN_ID}",

321+

"run_attempt": "${GITHUB_RUN_ATTEMPT}",

322+

"lane": "${LANE_ID}",

323+

"path": "openclaw-performance/${ref_slug}/${run_slug}/${LANE_ID}"

324+

}

325+

EOF

326+327+

git -C "$reports_root" config user.name "openclaw-performance[bot]"

328+

git -C "$reports_root" config user.email "openclaw-performance[bot]@users.noreply.github.com"

329+

git -C "$reports_root" add openclaw-performance

330+

if git -C "$reports_root" diff --cached --quiet; then

331+

echo "No clawgrit report changes to publish."

332+

exit 0

333+

fi

334+

git -C "$reports_root" commit -m "perf: add OpenClaw ${LANE_ID} report ${GITHUB_SHA::12}"

335+

git -C "$reports_root" push