Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CodSpeed

on:
push:
branches: [master, dev]
pull_request:
branches: [master]
# `workflow_dispatch` allows CodSpeed to trigger backtest
# performance analysis in order to generate initial data.
workflow_dispatch:

permissions:
contents: read
id-token: write # for OpenID Connect authentication with CodSpeed

jobs:
benchmarks:
name: Run benchmarks
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Run benchmarks
uses: CodSpeedHQ/action@v4
with:
mode: simulation
run: pnpm bench
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</p>

<p align="center">
<a href="https://openalice.ai"><img src="https://img.shields.io/badge/Website-blue" alt="Website"></a> · <a href="https://openalice.ai/docs"><img src="https://img.shields.io/badge/Docs-green" alt="Docs"></a> · <a href="https://x.com/OpenAliceAI"><img src="https://img.shields.io/badge/X-000000?logo=x&logoColor=white" alt="X (Twitter)"></a> · <a href="https://discord.gg/zf4STmrQd8"><img src="https://img.shields.io/badge/Discord-5865F2?logo=discord&logoColor=white" alt="Discord"></a> · <a href="https://qm.qq.com/q/iSg6O4FmrC"><img src="https://img.shields.io/badge/QQ-12B7F5" alt="QQ"></a>
<a href="https://openalice.ai"><img src="https://img.shields.io/badge/Website-blue" alt="Website"></a> · <a href="https://openalice.ai/docs"><img src="https://img.shields.io/badge/Docs-green" alt="Docs"></a> · <a href="https://x.com/OpenAliceAI"><img src="https://img.shields.io/badge/X-000000?logo=x&logoColor=white" alt="X (Twitter)"></a> · <a href="https://discord.gg/zf4STmrQd8"><img src="https://img.shields.io/badge/Discord-5865F2?logo=discord&logoColor=white" alt="Discord"></a> · <a href="https://qm.qq.com/q/iSg6O4FmrC"><img src="https://img.shields.io/badge/QQ-12B7F5" alt="QQ"></a> · <a href="https://app.codspeed.io/2233admin/OpenAlice?utm_source=badge"><img src="https://img.shields.io/endpoint?url=https://codspeed.io/badge.json" alt="CodSpeed"/></a>
</p>

<p align="center">
Expand Down
60 changes: 60 additions & 0 deletions benchmarks/core.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { bench, describe } from 'vitest'

import { parseDuration } from '@/core/duration.js'
import { compareVersions, getRepoSlug } from '@/core/version.js'
import { inferCredentialVendor, resolveAnthropicAuthMode } from '@/core/credential-inference.js'

// These benchmarks cover small, pure, hot-path helpers used across the
// scheduling, version-awareness and credential-inference code paths. They are
// CPU-bound and deterministic, which makes them a good fit for CodSpeed's
// simulation instrument.

describe('parseDuration', () => {
const inputs = ['30m', '1h', '5m30s', '2h15m', '1h30m45s', ' 90s ', 'not-a-duration', '']

bench('parse a mix of valid and invalid durations', () => {
for (const input of inputs) {
parseDuration(input)
}
})
})

describe('compareVersions', () => {
const pairs: Array<[string, string]> = [
['1.2.3', '1.2.4'],
['2.0.0', '1.9.9'],
['1.0.0-beta.1', '1.0.0'],
['0.50.0-beta.1', '0.50.0-beta.2'],
['v3.4.5', '3.4.5'],
['10.0.0', '9.99.99'],
]

bench('compare a batch of semver pairs', () => {
for (const [a, b] of pairs) {
compareVersions(a, b)
}
})
})

describe('getRepoSlug', () => {
bench('derive repo slug from package.json repository url', () => {
getRepoSlug()
})
})

describe('credential inference', () => {
const cases = [
{ agent: 'claude', baseUrl: 'https://api.z.ai/v1' },
{ agent: 'codex', baseUrl: 'https://api.minimaxi.com' },
{ agent: 'opencode', baseUrl: 'https://api.moonshot.cn' },
{ agent: 'pi', baseUrl: 'https://example.com/v1' },
{ agent: 'claude', baseUrl: 'https://api.deepseek.com' },
]

bench('infer vendor + anthropic auth mode for a batch of configs', () => {
for (const c of cases) {
inferCredentialVendor(c)
resolveAnthropicAuthMode({ baseUrl: c.baseUrl })
}
})
})
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"test:watch": "vitest",
"test:e2e": "vitest run --config vitest.e2e.config.ts",
"test:bbProvider": "vitest run --config vitest.bbProvider.config.ts",
"bench": "vitest bench --run --config vitest.bench.config.ts",
"test:smoke": "tsx scripts/guardian/smoke.ts",
"postinstall": "node scripts/fix-pty-perms.mjs"
},
Expand Down Expand Up @@ -106,6 +107,7 @@
},
"devDependencies": {
"@ai-sdk/provider": "^3.0.8",
"@codspeed/vitest-plugin": "^5.7.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^25.2.3",
Expand Down
Loading
Loading