llmsim 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llmsim-0.7.0/.claude/commands/ship.md +103 -0
- llmsim-0.7.0/.claude/hooks/fix-git-identity.sh +11 -0
- llmsim-0.7.0/.claude/settings.json +20 -0
- llmsim-0.7.0/.claude/skills/load-test/SKILL.md +154 -0
- llmsim-0.7.0/.claude/skills/maintenance/SKILL.md +115 -0
- llmsim-0.7.0/.dockerignore +9 -0
- llmsim-0.7.0/.github/FUNDING.yml +3 -0
- llmsim-0.7.0/.github/pull_request_template.md +20 -0
- llmsim-0.7.0/.github/workflows/bindings.yml +145 -0
- llmsim-0.7.0/.github/workflows/ci.yml +364 -0
- llmsim-0.7.0/.github/workflows/publish-js.yml +182 -0
- llmsim-0.7.0/.github/workflows/publish-python.yml +130 -0
- llmsim-0.7.0/.github/workflows/publish.yml +78 -0
- llmsim-0.7.0/.github/workflows/release.yml +128 -0
- llmsim-0.7.0/.gitignore +27 -0
- llmsim-0.7.0/AGENTS.md +250 -0
- llmsim-0.7.0/CHANGELOG.md +286 -0
- llmsim-0.7.0/CLAUDE.md +1 -0
- llmsim-0.7.0/CONTRIBUTING.md +153 -0
- llmsim-0.7.0/Cargo.lock +2928 -0
- llmsim-0.7.0/Cargo.toml +111 -0
- llmsim-0.7.0/Dockerfile +60 -0
- llmsim-0.7.0/LICENSE +21 -0
- llmsim-0.7.0/PKG-INFO +105 -0
- llmsim-0.7.0/README.md +341 -0
- llmsim-0.7.0/benchmarks/README.md +200 -0
- llmsim-0.7.0/benchmarks/config/benchmark.toml +19 -0
- llmsim-0.7.0/benchmarks/config/chaos.toml +20 -0
- llmsim-0.7.0/benchmarks/config/throughput.toml +27 -0
- llmsim-0.7.0/benchmarks/k6/chat-completions.js +211 -0
- llmsim-0.7.0/benchmarks/k6/config.js +161 -0
- llmsim-0.7.0/benchmarks/k6/endpoints.js +206 -0
- llmsim-0.7.0/benchmarks/k6/high-concurrency.js +211 -0
- llmsim-0.7.0/benchmarks/run-benchmark.sh +213 -0
- llmsim-0.7.0/benchmarks/smoke-test.sh +87 -0
- llmsim-0.7.0/benchmarks/throughput.sh +324 -0
- llmsim-0.7.0/crates/llmsim-python/.gitignore +6 -0
- llmsim-0.7.0/crates/llmsim-python/Cargo.toml +24 -0
- llmsim-0.7.0/crates/llmsim-python/README.md +72 -0
- llmsim-0.7.0/crates/llmsim-python/src/lib.rs +195 -0
- llmsim-0.7.0/crates/llmsim-python/tests/test_sdks.py +56 -0
- llmsim-0.7.0/crates/llmsim-python/tests/test_server.py +138 -0
- llmsim-0.7.0/deny.toml +30 -0
- llmsim-0.7.0/docker-compose.yml +31 -0
- llmsim-0.7.0/docs/api.md +794 -0
- llmsim-0.7.0/docs/bindings.md +125 -0
- llmsim-0.7.0/docs/images/tui.png +0 -0
- llmsim-0.7.0/docs/llmsim.cast +173 -0
- llmsim-0.7.0/docs/llmsim.webm +0 -0
- llmsim-0.7.0/docs/scenarios.md +98 -0
- llmsim-0.7.0/examples/README.md +343 -0
- llmsim-0.7.0/examples/anthropic_client.py +181 -0
- llmsim-0.7.0/examples/anthropic_curl.sh +83 -0
- llmsim-0.7.0/examples/anthropic_langchain.py +86 -0
- llmsim-0.7.0/examples/basic_usage.rs +170 -0
- llmsim-0.7.0/examples/go/anthropic_client.go +114 -0
- llmsim-0.7.0/examples/go/go.mod +21 -0
- llmsim-0.7.0/examples/go/go.sum +38 -0
- llmsim-0.7.0/examples/images_client.py +150 -0
- llmsim-0.7.0/examples/langchain_client.py +127 -0
- llmsim-0.7.0/examples/langchain_responses_client.py +200 -0
- llmsim-0.7.0/examples/list_models.py +101 -0
- llmsim-0.7.0/examples/node/anthropic_client.ts +113 -0
- llmsim-0.7.0/examples/node/images_client.ts +130 -0
- llmsim-0.7.0/examples/node/openai_client.ts +145 -0
- llmsim-0.7.0/examples/node/package-lock.json +675 -0
- llmsim-0.7.0/examples/node/package.json +11 -0
- llmsim-0.7.0/examples/node/vercel_ai_client.ts +121 -0
- llmsim-0.7.0/examples/openai_client.py +231 -0
- llmsim-0.7.0/examples/openai_websocket_client.py +209 -0
- llmsim-0.7.0/examples/openresponses_client.py +224 -0
- llmsim-0.7.0/examples/pydantic_ai_client.py +119 -0
- llmsim-0.7.0/examples/responses_client.py +294 -0
- llmsim-0.7.0/examples/responses_usage.rs +426 -0
- llmsim-0.7.0/examples/scenarios/broken-stream.json +9 -0
- llmsim-0.7.0/examples/scenarios/chat-short.json +8 -0
- llmsim-0.7.0/examples/scenarios/flaky-429.json +13 -0
- llmsim-0.7.0/examples/scenarios/long-answer.json +8 -0
- llmsim-0.7.0/examples/scenarios/parallel-tools.json +11 -0
- llmsim-0.7.0/examples/scenarios/research-3-tools.json +12 -0
- llmsim-0.7.0/examples/scenarios/slow-first-token.json +8 -0
- llmsim-0.7.0/examples/scenarios/stream-stall.json +9 -0
- llmsim-0.7.0/examples/scenarios/thinking.json +8 -0
- llmsim-0.7.0/examples/scripted_demo/main.rs +127 -0
- llmsim-0.7.0/examples/scripted_demo/scripted_demo.json +38 -0
- llmsim-0.7.0/examples/scripted_demo/scripted_demo.py +85 -0
- llmsim-0.7.0/examples/scripted_demo/scripted_demo.toml +14 -0
- llmsim-0.7.0/examples/typesafe_client.py +134 -0
- llmsim-0.7.0/justfile +90 -0
- llmsim-0.7.0/knowledge/apis/anthropic-api.md +239 -0
- llmsim-0.7.0/knowledge/apis/image-generation.md +153 -0
- llmsim-0.7.0/knowledge/apis/index.md +6 -0
- llmsim-0.7.0/knowledge/apis/responses-api.md +405 -0
- llmsim-0.7.0/knowledge/apis/typesafe-api.md +122 -0
- llmsim-0.7.0/knowledge/foundations/api-endpoints.md +203 -0
- llmsim-0.7.0/knowledge/foundations/architecture.md +427 -0
- llmsim-0.7.0/knowledge/foundations/index.md +5 -0
- llmsim-0.7.0/knowledge/foundations/language-bindings.md +85 -0
- llmsim-0.7.0/knowledge/index.md +16 -0
- llmsim-0.7.0/knowledge/knowledge-contract.md +68 -0
- llmsim-0.7.0/knowledge/log.md +16 -0
- llmsim-0.7.0/knowledge/performance/index.md +4 -0
- llmsim-0.7.0/knowledge/performance/load-testing.md +183 -0
- llmsim-0.7.0/knowledge/performance/throughput-benchmark.md +256 -0
- llmsim-0.7.0/knowledge/project/index.md +4 -0
- llmsim-0.7.0/knowledge/project/maintenance.md +92 -0
- llmsim-0.7.0/knowledge/project/release-process.md +283 -0
- llmsim-0.7.0/knowledge/simulation/index.md +4 -0
- llmsim-0.7.0/knowledge/simulation/scenarios.md +204 -0
- llmsim-0.7.0/knowledge/simulation/scripted-mode.md +196 -0
- llmsim-0.7.0/llmsim/__init__.py +179 -0
- llmsim-0.7.0/llmsim/_llmsim.pyi +18 -0
- llmsim-0.7.0/llmsim/py.typed +0 -0
- llmsim-0.7.0/pyproject.toml +56 -0
- llmsim-0.7.0/rust-toolchain.toml +4 -0
- llmsim-0.7.0/scripts/check_okf.py +195 -0
- llmsim-0.7.0/scripts/lib/common.sh +85 -0
- llmsim-0.7.0/scripts/test-knowledge-okf.sh +99 -0
- llmsim-0.7.0/src/anthropic/mod.rs +14 -0
- llmsim-0.7.0/src/anthropic/models.rs +626 -0
- llmsim-0.7.0/src/anthropic/stream.rs +376 -0
- llmsim-0.7.0/src/anthropic/thinking.rs +325 -0
- llmsim-0.7.0/src/anthropic/types.rs +539 -0
- llmsim-0.7.0/src/cli/anthropic_handlers.rs +380 -0
- llmsim-0.7.0/src/cli/config.rs +484 -0
- llmsim-0.7.0/src/cli/handlers.rs +1893 -0
- llmsim-0.7.0/src/cli/mod.rs +146 -0
- llmsim-0.7.0/src/cli/server.rs +230 -0
- llmsim-0.7.0/src/cli/state.rs +43 -0
- llmsim-0.7.0/src/cli/typesafe_handlers.rs +186 -0
- llmsim-0.7.0/src/cli/ws_handler.rs +313 -0
- llmsim-0.7.0/src/errors.rs +392 -0
- llmsim-0.7.0/src/generator.rs +395 -0
- llmsim-0.7.0/src/ids.rs +29 -0
- llmsim-0.7.0/src/image_stream.rs +256 -0
- llmsim-0.7.0/src/imagegen.rs +697 -0
- llmsim-0.7.0/src/latency.rs +428 -0
- llmsim-0.7.0/src/lib.rs +94 -0
- llmsim-0.7.0/src/main.rs +224 -0
- llmsim-0.7.0/src/openai/images.rs +318 -0
- llmsim-0.7.0/src/openai/mod.rs +9 -0
- llmsim-0.7.0/src/openai/models.rs +1205 -0
- llmsim-0.7.0/src/openai/responses.rs +1059 -0
- llmsim-0.7.0/src/openai/types.rs +704 -0
- llmsim-0.7.0/src/openai/websocket.rs +320 -0
- llmsim-0.7.0/src/openresponses/mod.rs +9 -0
- llmsim-0.7.0/src/openresponses/stream.rs +346 -0
- llmsim-0.7.0/src/openresponses/types.rs +835 -0
- llmsim-0.7.0/src/responses_stream.rs +755 -0
- llmsim-0.7.0/src/scenario.rs +1757 -0
- llmsim-0.7.0/src/scenario_stream.rs +387 -0
- llmsim-0.7.0/src/script.rs +452 -0
- llmsim-0.7.0/src/script_stream.rs +381 -0
- llmsim-0.7.0/src/stats.rs +616 -0
- llmsim-0.7.0/src/stream.rs +358 -0
- llmsim-0.7.0/src/tokens.rs +279 -0
- llmsim-0.7.0/src/tui/app.rs +498 -0
- llmsim-0.7.0/src/tui/mod.rs +9 -0
- llmsim-0.7.0/src/tui/ui.rs +492 -0
- llmsim-0.7.0/src/typesafe/judge.rs +240 -0
- llmsim-0.7.0/src/typesafe/mod.rs +17 -0
- llmsim-0.7.0/src/typesafe/models.rs +96 -0
- llmsim-0.7.0/src/typesafe/types.rs +575 -0
- llmsim-0.7.0/tests/anthropic_test.rs +725 -0
- llmsim-0.7.0/tests/images_test.rs +166 -0
- llmsim-0.7.0/tests/integration_test.rs +501 -0
- llmsim-0.7.0/tests/openai_reasoning_test.rs +79 -0
- llmsim-0.7.0/tests/scenarios_test.rs +357 -0
- llmsim-0.7.0/tests/scripted_test.rs +319 -0
- llmsim-0.7.0/tests/smoke_test.sh +325 -0
- llmsim-0.7.0/tests/typesafe_test.rs +244 -0
- llmsim-0.7.0/tests/websocket_test.rs +311 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Ship
|
|
2
|
+
|
|
3
|
+
Run the full ship flow: verify quality, ensure test coverage, update artifacts, smoke test, then push, create PR, and merge when CI is green.
|
|
4
|
+
|
|
5
|
+
This command implements the complete "Shipping" definition and Pre-PR Checklist from AGENTS.md. When the user says "ship" or "fix and ship", execute ALL phases below — not just the push/merge steps.
|
|
6
|
+
|
|
7
|
+
## Arguments
|
|
8
|
+
|
|
9
|
+
- `$ARGUMENTS` - Optional: description of what is being shipped (used for PR title/body context and to scope the quality checks)
|
|
10
|
+
|
|
11
|
+
## Instructions
|
|
12
|
+
|
|
13
|
+
### Phase 1: Pre-flight
|
|
14
|
+
|
|
15
|
+
1. Confirm we're NOT on `main` or `master`
|
|
16
|
+
2. Confirm there are no uncommitted changes (`git diff --quiet && git diff --cached --quiet`)
|
|
17
|
+
3. If uncommitted changes exist, stop and tell the user
|
|
18
|
+
|
|
19
|
+
### Phase 2: Test Coverage
|
|
20
|
+
|
|
21
|
+
Review the changes on this branch (use `git diff origin/main...HEAD` and `git log origin/main..HEAD`) and ensure comprehensive test coverage:
|
|
22
|
+
|
|
23
|
+
1. **Identify all changed code paths** — every new/modified function, endpoint, handler
|
|
24
|
+
2. **Verify existing tests cover the changes** — run `cargo test` and check for failures
|
|
25
|
+
3. **Write missing tests** for any uncovered code paths:
|
|
26
|
+
- **Positive tests**: happy path, valid inputs, expected state transitions
|
|
27
|
+
- **Negative tests**: invalid inputs, error conditions, boundary cases
|
|
28
|
+
- **Integration tests**: API endpoint tests in `tests/`
|
|
29
|
+
4. **Run all tests** to confirm green: `cargo test`
|
|
30
|
+
5. If any test fails, fix the code or test until green
|
|
31
|
+
|
|
32
|
+
### Phase 3: Artifact Updates
|
|
33
|
+
|
|
34
|
+
Review the changes and update project artifacts where applicable. Skip items that aren't affected.
|
|
35
|
+
|
|
36
|
+
1. **Knowledge** (`knowledge/`): if the change adds/modifies behavior covered by a concept, update it to stay in sync, add a `knowledge/log.md` entry for notable decisions, and run `just check-okf`
|
|
37
|
+
2. **AGENTS.md**: if the change adds new knowledge domains, skills, commands, or modifies development workflows — update the relevant section
|
|
38
|
+
3. **Documentation** (`docs/`): if the change affects user-facing APIs, configuration, or features — update the relevant docs
|
|
39
|
+
|
|
40
|
+
### Phase 4: Smoke Testing
|
|
41
|
+
|
|
42
|
+
Smoke test impacted functionality to verify it works end-to-end:
|
|
43
|
+
|
|
44
|
+
1. **Build**: `cargo build`
|
|
45
|
+
2. **API/server changes**: run `./tests/smoke_test.sh` to verify all endpoints work
|
|
46
|
+
3. If smoke testing reveals issues, fix them and loop back to Phase 2 (tests must still pass)
|
|
47
|
+
|
|
48
|
+
### Phase 5: Quality Gates
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git fetch origin main && git rebase origin/main
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- If rebase fails with conflicts, abort and tell the user to resolve manually
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
just check
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- If formatting fails, run `just fmt` to auto-fix, then retry once
|
|
61
|
+
- If still failing, stop and report
|
|
62
|
+
|
|
63
|
+
### Phase 6: Push and PR
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git push -u origin <current-branch>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Check for existing PR:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
gh pr view --json url 2>/dev/null
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
If no PR exists, create one using the PR template (`.github/pull_request_template.md`):
|
|
76
|
+
|
|
77
|
+
- **Title**: conventional commit style from the branch commits
|
|
78
|
+
- **Body**: fill in the PR template sections based on the actual changes; center it on functional change and impact, not a code-location walkthrough. Include what tests were added/verified.
|
|
79
|
+
- **Evidence**: attach a Before / After with proof — `curl`/API output, server stats/metrics, or a TUI screenshot. Say so when there is no observable behavior change.
|
|
80
|
+
- Use `gh pr create`
|
|
81
|
+
|
|
82
|
+
If a PR already exists, update it if needed and report its URL.
|
|
83
|
+
|
|
84
|
+
### Phase 7: Wait for CI and Merge
|
|
85
|
+
|
|
86
|
+
- Check CI status with `gh pr checks` (poll every 30s, up to 15 minutes)
|
|
87
|
+
- If CI is green, merge with `gh pr merge --squash --auto`
|
|
88
|
+
- If CI fails, report the failing checks and stop
|
|
89
|
+
- **NEVER** merge when CI is red
|
|
90
|
+
|
|
91
|
+
### Phase 8: Post-merge
|
|
92
|
+
|
|
93
|
+
After successful merge:
|
|
94
|
+
|
|
95
|
+
- Report the merged PR URL
|
|
96
|
+
- Done
|
|
97
|
+
|
|
98
|
+
## Notes
|
|
99
|
+
|
|
100
|
+
- This is the canonical shipping workflow. It implements the full "Shipping" definition and Pre-PR Checklist from AGENTS.md.
|
|
101
|
+
- Phases 2-4 (tests, artifacts, smoke testing) are the quality core — do NOT skip them.
|
|
102
|
+
- The `$ARGUMENTS` context helps scope which tests, specs, and smoke tests are relevant.
|
|
103
|
+
- For "fix and ship" requests: implement the fix first, then run `/ship` to validate and merge.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Exit early if not in a git repo
|
|
5
|
+
git rev-parse --git-dir >/dev/null 2>&1 || exit 0
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
9
|
+
|
|
10
|
+
source "$REPO_ROOT/scripts/lib/common.sh"
|
|
11
|
+
configure_commit_git_identity_if_needed 2>/dev/null || true
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"gitAttribution": false,
|
|
3
|
+
"attribution": {
|
|
4
|
+
"commit": "",
|
|
5
|
+
"pr": ""
|
|
6
|
+
},
|
|
7
|
+
"hooks": {
|
|
8
|
+
"SessionStart": [
|
|
9
|
+
{
|
|
10
|
+
"matcher": "",
|
|
11
|
+
"hooks": [
|
|
12
|
+
{
|
|
13
|
+
"type": "command",
|
|
14
|
+
"command": ".claude/hooks/fix-git-identity.sh"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: load-test
|
|
3
|
+
description: Run load and stress tests for llmsim using k6. Use this skill when you need to benchmark performance, validate high concurrency handling, or run smoke tests for CI validation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Load Testing Skill
|
|
7
|
+
|
|
8
|
+
## Environment Setup
|
|
9
|
+
|
|
10
|
+
### Prerequisites
|
|
11
|
+
|
|
12
|
+
**k6** must be installed. Install options:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Linux (binary)
|
|
16
|
+
curl -sLO https://github.com/grafana/k6/releases/download/v0.54.0/k6-v0.54.0-linux-amd64.tar.gz
|
|
17
|
+
tar -xzf k6-v0.54.0-linux-amd64.tar.gz
|
|
18
|
+
sudo mv k6-v0.54.0-linux-amd64/k6 /usr/local/bin/
|
|
19
|
+
|
|
20
|
+
# macOS
|
|
21
|
+
brew install k6
|
|
22
|
+
|
|
23
|
+
# Verify installation
|
|
24
|
+
k6 version
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**oha** is required only for the `throughput` profile (peak req/s ceiling +
|
|
28
|
+
parallelisation sweep). It is a Rust load generator with near-zero per-request
|
|
29
|
+
overhead, used instead of k6 when saturating the server:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cargo install oha # or: brew install oha
|
|
33
|
+
oha --version
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Build llmsim
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cargo build --release
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Running Tests
|
|
43
|
+
|
|
44
|
+
### Quick Smoke Test (Recommended for CI)
|
|
45
|
+
|
|
46
|
+
Validates the load testing setup works correctly:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
./benchmarks/smoke-test.sh
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Ultra-fast variant (3 iterations):
|
|
53
|
+
```bash
|
|
54
|
+
./benchmarks/smoke-test.sh --quick
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Load Test Profiles
|
|
58
|
+
|
|
59
|
+
| Profile | Command | Duration | VUs | Purpose |
|
|
60
|
+
|---------|---------|----------|-----|---------|
|
|
61
|
+
| Smoke | `./benchmarks/run-benchmark.sh smoke` | ~10s | 1 | Quick validation |
|
|
62
|
+
| Load | `./benchmarks/run-benchmark.sh load` | ~4 min | 10-50 | Normal load |
|
|
63
|
+
| Stress | `./benchmarks/run-benchmark.sh stress` | ~7 min | 50-500 | Breaking points |
|
|
64
|
+
| Spike | `./benchmarks/run-benchmark.sh spike` | ~2 min | 10-500 | Burst traffic |
|
|
65
|
+
| Soak | `./benchmarks/run-benchmark.sh soak` | ~32 min | 50 | Memory leaks |
|
|
66
|
+
| High Concurrency | `./benchmarks/run-benchmark.sh high-concurrency` | ~4 min | 500 | Max throughput |
|
|
67
|
+
| Throughput | `./benchmarks/run-benchmark.sh throughput` | varies | n/a | Peak req/s ceiling + parallelisation scaling (uses oha) |
|
|
68
|
+
|
|
69
|
+
### Common Options
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Use existing server (don't start new one)
|
|
73
|
+
./benchmarks/run-benchmark.sh load --no-server --port 8080
|
|
74
|
+
|
|
75
|
+
# Custom port
|
|
76
|
+
./benchmarks/run-benchmark.sh smoke --port 9000
|
|
77
|
+
|
|
78
|
+
# Output results to JSON
|
|
79
|
+
./benchmarks/run-benchmark.sh load --output results.json
|
|
80
|
+
|
|
81
|
+
# Custom VU count for high-concurrency
|
|
82
|
+
./benchmarks/run-benchmark.sh high-concurrency --vus 1000
|
|
83
|
+
|
|
84
|
+
# Chaos mode - enable error injection (rate limits, server errors)
|
|
85
|
+
./benchmarks/run-benchmark.sh load --chaos
|
|
86
|
+
|
|
87
|
+
# Custom llmsim config file
|
|
88
|
+
./benchmarks/run-benchmark.sh load --config path/to/config.toml
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Error Injection (Chaos Mode)
|
|
92
|
+
|
|
93
|
+
By default, benchmarks run with error injection **disabled** for consistent results.
|
|
94
|
+
|
|
95
|
+
Use `--chaos` to enable error injection:
|
|
96
|
+
- 10% rate limit errors (429)
|
|
97
|
+
- 5% server errors (500/503)
|
|
98
|
+
- 2% timeout errors (504)
|
|
99
|
+
|
|
100
|
+
This tests client error handling and retry logic under realistic conditions.
|
|
101
|
+
|
|
102
|
+
### Remote Testing
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
export K6_TARGET_URL="https://llmsim.example.com"
|
|
106
|
+
./benchmarks/run-benchmark.sh load --no-server
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Direct k6 Usage
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Run specific test script
|
|
113
|
+
k6 run benchmarks/k6/chat-completions.js
|
|
114
|
+
|
|
115
|
+
# With custom profile
|
|
116
|
+
k6 run --env PROFILE=stress benchmarks/k6/chat-completions.js
|
|
117
|
+
|
|
118
|
+
# With custom target
|
|
119
|
+
k6 run --env K6_TARGET_URL=http://localhost:9000 benchmarks/k6/endpoints.js
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Test Scripts
|
|
123
|
+
|
|
124
|
+
| Script | Description |
|
|
125
|
+
|--------|-------------|
|
|
126
|
+
| `chat-completions.js` | Main test - streaming/non-streaming chat completions |
|
|
127
|
+
| `endpoints.js` | All endpoints with weighted distribution |
|
|
128
|
+
| `high-concurrency.js` | Maximum concurrent connections |
|
|
129
|
+
|
|
130
|
+
## Success Criteria
|
|
131
|
+
|
|
132
|
+
Tests pass if thresholds are met:
|
|
133
|
+
|
|
134
|
+
| Profile | Max Error Rate | P95 Latency |
|
|
135
|
+
|---------|----------------|-------------|
|
|
136
|
+
| smoke | 1% | 2s |
|
|
137
|
+
| load | 5% | 3s |
|
|
138
|
+
| stress | 15% | 10s |
|
|
139
|
+
|
|
140
|
+
## Troubleshooting
|
|
141
|
+
|
|
142
|
+
**Server not responding**: Check port availability and build status
|
|
143
|
+
**High error rates in stress tests**: Expected behavior at capacity limits
|
|
144
|
+
**k6 not found**: Install k6 following instructions above
|
|
145
|
+
|
|
146
|
+
## Files
|
|
147
|
+
|
|
148
|
+
- `benchmarks/run-benchmark.sh` - Main runner script
|
|
149
|
+
- `benchmarks/smoke-test.sh` - Quick smoke test
|
|
150
|
+
- `benchmarks/config/benchmark.toml` - Default config (no errors)
|
|
151
|
+
- `benchmarks/config/chaos.toml` - Chaos mode config (error injection)
|
|
152
|
+
- `benchmarks/k6/config.js` - k6 test configuration
|
|
153
|
+
- `benchmarks/k6/*.js` - k6 test scripts
|
|
154
|
+
- `knowledge/performance/load-testing.md` - Full specification
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maintenance
|
|
3
|
+
description: Run the routine maintenance workflow for llmsim — dependency updates, model profile refresh, code-quality + audit/deny checks, and spec alignment. Use when performing the periodic maintenance pass defined in knowledge/project/maintenance.md.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Routine Maintenance Skill
|
|
7
|
+
|
|
8
|
+
This skill walks the routine-maintenance workflow defined in
|
|
9
|
+
[`knowledge/project/maintenance.md`](../../../knowledge/project/maintenance.md). Use it monthly,
|
|
10
|
+
before a minor/major release, or whenever a major-provider releases new
|
|
11
|
+
models.
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
The maintenance flow needs three Rust tools beyond the default toolchain.
|
|
16
|
+
Install them once per machine; they are not cargo-installed automatically:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Security advisory checks (RustSec)
|
|
20
|
+
cargo install cargo-audit
|
|
21
|
+
|
|
22
|
+
# License + duplicate-dep + ban policy checks
|
|
23
|
+
cargo install cargo-deny
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
CI runs both of these on every PR (`Security Audit`, `License & Dependency
|
|
27
|
+
Check` jobs), but running them locally surfaces issues *before* pushing.
|
|
28
|
+
|
|
29
|
+
The Rust toolchain itself is pinned via `rust-toolchain.toml` at the repo
|
|
30
|
+
root — rustup will pick the right channel automatically.
|
|
31
|
+
|
|
32
|
+
## Workflow
|
|
33
|
+
|
|
34
|
+
Follow the order below. Each step maps to a requirement in
|
|
35
|
+
`knowledge/project/maintenance.md`.
|
|
36
|
+
|
|
37
|
+
### 1. Dependency updates (R1)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Bring the lockfile up to the latest semver-compatible versions.
|
|
41
|
+
cargo update
|
|
42
|
+
|
|
43
|
+
# Surface major-version updates blocked by version constraints.
|
|
44
|
+
cargo update --dry-run --verbose
|
|
45
|
+
|
|
46
|
+
# Security advisories. Fails the run if RustSec has reported anything.
|
|
47
|
+
cargo audit
|
|
48
|
+
|
|
49
|
+
# License + duplicate-dep + advisory policy. Reads ./deny.toml.
|
|
50
|
+
cargo deny check
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For each entry in the `cargo update --dry-run` output, decide:
|
|
54
|
+
|
|
55
|
+
- **Apply the major bump** if the diff is small (a renamed trait import,
|
|
56
|
+
a tweaked signature) — see PR #34 for the pattern.
|
|
57
|
+
- **Skip and note** if it requires a non-trivial refactor; record the
|
|
58
|
+
reason in the maintenance PR description so the next agent doesn't
|
|
59
|
+
re-evaluate from scratch.
|
|
60
|
+
- **Watch for archived crates.** `serde_yaml` was at `0.9.34+deprecated`
|
|
61
|
+
before PR #37 migrated to TOML — `+deprecated` build metadata is a
|
|
62
|
+
red flag that no semver bump exists.
|
|
63
|
+
|
|
64
|
+
### 2. Model profile refresh (R2)
|
|
65
|
+
|
|
66
|
+
- Cross-check `src/openai/models.rs` against [models.dev](https://models.dev)
|
|
67
|
+
— context window, max output tokens, capabilities, knowledge cutoff,
|
|
68
|
+
release timestamp.
|
|
69
|
+
- Add new models from OpenAI, Anthropic, and Google (and DeepSeek where
|
|
70
|
+
appropriate). Mirror the new IDs in `default_models()` in
|
|
71
|
+
`src/cli/config.rs` so they appear in `/openai/v1/models`.
|
|
72
|
+
- Update the model table in `knowledge/foundations/architecture.md`.
|
|
73
|
+
- Add focused unit tests for each new profile (one assertion per field
|
|
74
|
+
worth caring about; see existing tests as a template).
|
|
75
|
+
|
|
76
|
+
### 3. Code-quality sweep (R3)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cargo fmt --check
|
|
80
|
+
cargo clippy --all-targets -- -D warnings
|
|
81
|
+
cargo test
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- Grep for `TODO`, `FIXME`, `HACK`, `XXX` — resolve or document.
|
|
85
|
+
- Review API handlers for input validation, panicking paths on user
|
|
86
|
+
input, and resource limits (body sizes, in-memory collection growth).
|
|
87
|
+
- Verify CORS configuration is still appropriate for the deployment
|
|
88
|
+
posture.
|
|
89
|
+
|
|
90
|
+
### 4. Spec + AGENTS.md alignment (R5 + R6)
|
|
91
|
+
|
|
92
|
+
- Read each concept in `knowledge/` and confirm it still matches the code.
|
|
93
|
+
Run `just check-okf` to keep the bundle OKF v0.2 conformant.
|
|
94
|
+
Update tables, requirement lists, and example snippets where they've
|
|
95
|
+
drifted.
|
|
96
|
+
- Verify `AGENTS.md` lists every knowledge domain, every skill, and every command.
|
|
97
|
+
- Run a quick `grep -rn "PORT_NUMBER\|version-like-string"` for known
|
|
98
|
+
stale references (e.g., the AGENTS.md default-port fix in PR #36).
|
|
99
|
+
|
|
100
|
+
## Shape of a maintenance pass
|
|
101
|
+
|
|
102
|
+
A standard pass produces three or four small PRs rather than one omnibus
|
|
103
|
+
diff:
|
|
104
|
+
|
|
105
|
+
1. **`chore(deps)`** — `cargo update` + any major bumps you decided to
|
|
106
|
+
apply. Include the clippy fix if `dtolnay/rust-toolchain` rolled to
|
|
107
|
+
a new version and surfaced new lints.
|
|
108
|
+
2. **`feat(models)`** — new model profiles + spec table updates.
|
|
109
|
+
3. **`docs(knowledge)`** — any knowledge drift discovered while reviewing the
|
|
110
|
+
code.
|
|
111
|
+
4. *(optional)* **`chore(...)` / `refactor(...)`** for anything bigger
|
|
112
|
+
that came out of the code-quality sweep.
|
|
113
|
+
|
|
114
|
+
Open each PR independently against `main` so they can be reviewed and
|
|
115
|
+
merged in isolation. See PRs #34 / #35 / #36 / #37 for a worked example.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## What changed
|
|
2
|
+
Describe the change functionally — what behavior changes and its impact on users
|
|
3
|
+
or callers. Lead with outcomes; don't walk through code locations, the diff shows
|
|
4
|
+
where and how. Keep any code-level notes short and specific.
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
Problem or motivation.
|
|
8
|
+
|
|
9
|
+
## Before / After
|
|
10
|
+
Show the effect with evidence. Include before and after whenever behavior changes —
|
|
11
|
+
CLI/API output, logs, metrics, or screenshots for UI (attach working screenshots
|
|
12
|
+
when possible). For changes with no observable behavior (pure refactor, docs), say so.
|
|
13
|
+
|
|
14
|
+
## Risk
|
|
15
|
+
- Low / Medium / High
|
|
16
|
+
- What can break
|
|
17
|
+
|
|
18
|
+
## Checklist
|
|
19
|
+
- [ ] Tests added or updated
|
|
20
|
+
- [ ] Backward compatibility considered
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# CI for the Python (PyO3/maturin) and Node (NAPI-RS) packages in crates/.
|
|
2
|
+
# Release builds for every platform live in publish-python.yml / publish-js.yml.
|
|
3
|
+
|
|
4
|
+
name: Bindings
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main]
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
CARGO_TERM_COLOR: always
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
versions:
|
|
17
|
+
name: Package versions match Cargo
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Check package.json version
|
|
22
|
+
run: |
|
|
23
|
+
CARGO_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
|
24
|
+
PKG_VERSION=$(node -p "require('./crates/llmsim-js/package.json').version")
|
|
25
|
+
if [ "$CARGO_VERSION" != "$PKG_VERSION" ]; then
|
|
26
|
+
echo "::error::crates/llmsim-js/package.json version ($PKG_VERSION) != Cargo.toml ($CARGO_VERSION)"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
echo "Versions match: $CARGO_VERSION"
|
|
30
|
+
|
|
31
|
+
python:
|
|
32
|
+
name: Python ${{ matrix.python-version }} (${{ matrix.os }})
|
|
33
|
+
runs-on: ${{ matrix.os }}
|
|
34
|
+
strategy:
|
|
35
|
+
fail-fast: false
|
|
36
|
+
matrix:
|
|
37
|
+
include:
|
|
38
|
+
- os: ubuntu-24.04
|
|
39
|
+
python-version: "3.9"
|
|
40
|
+
- os: ubuntu-24.04
|
|
41
|
+
python-version: "3.13"
|
|
42
|
+
- os: macos-latest
|
|
43
|
+
python-version: "3.13"
|
|
44
|
+
- os: windows-latest
|
|
45
|
+
python-version: "3.13"
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
- name: Install Rust toolchain
|
|
50
|
+
uses: dtolnay/rust-toolchain@1.99.0
|
|
51
|
+
|
|
52
|
+
- name: Cache cargo registry
|
|
53
|
+
uses: actions/cache@v4
|
|
54
|
+
with:
|
|
55
|
+
path: |
|
|
56
|
+
~/.cargo/registry
|
|
57
|
+
~/.cargo/git
|
|
58
|
+
target
|
|
59
|
+
key: ${{ runner.os }}-bindings-py-${{ hashFiles('**/Cargo.toml') }}
|
|
60
|
+
|
|
61
|
+
- uses: actions/setup-python@v5
|
|
62
|
+
with:
|
|
63
|
+
python-version: ${{ matrix.python-version }}
|
|
64
|
+
|
|
65
|
+
- name: Lint
|
|
66
|
+
if: matrix.python-version == '3.13' && runner.os == 'Linux'
|
|
67
|
+
working-directory: crates/llmsim-python
|
|
68
|
+
run: |
|
|
69
|
+
pip install ruff
|
|
70
|
+
ruff check .
|
|
71
|
+
ruff format --check .
|
|
72
|
+
|
|
73
|
+
- name: Build and install wheel
|
|
74
|
+
shell: bash
|
|
75
|
+
working-directory: crates/llmsim-python
|
|
76
|
+
run: |
|
|
77
|
+
python -m venv .venv
|
|
78
|
+
if [ "$RUNNER_OS" = "Windows" ]; then . .venv/Scripts/activate; else . .venv/bin/activate; fi
|
|
79
|
+
pip install maturin
|
|
80
|
+
maturin build --out dist
|
|
81
|
+
pip install --find-links dist llmsim
|
|
82
|
+
pip install pytest pytest-timeout openai anthropic
|
|
83
|
+
|
|
84
|
+
- name: Test
|
|
85
|
+
shell: bash
|
|
86
|
+
working-directory: crates/llmsim-python
|
|
87
|
+
run: |
|
|
88
|
+
if [ "$RUNNER_OS" = "Windows" ]; then . .venv/Scripts/activate; else . .venv/bin/activate; fi
|
|
89
|
+
# Run from tests/ so `import llmsim` resolves to the installed wheel,
|
|
90
|
+
# not the source directory (which has no native module).
|
|
91
|
+
cd tests && pytest -v .
|
|
92
|
+
|
|
93
|
+
node:
|
|
94
|
+
name: Node ${{ matrix.node }} (${{ matrix.os }})
|
|
95
|
+
runs-on: ${{ matrix.os }}
|
|
96
|
+
strategy:
|
|
97
|
+
fail-fast: false
|
|
98
|
+
matrix:
|
|
99
|
+
include:
|
|
100
|
+
- os: ubuntu-latest
|
|
101
|
+
node: "20"
|
|
102
|
+
- os: ubuntu-latest
|
|
103
|
+
node: "22"
|
|
104
|
+
- os: ubuntu-latest
|
|
105
|
+
node: "24"
|
|
106
|
+
- os: macos-latest
|
|
107
|
+
node: "22"
|
|
108
|
+
- os: windows-latest
|
|
109
|
+
node: "22"
|
|
110
|
+
steps:
|
|
111
|
+
- uses: actions/checkout@v4
|
|
112
|
+
|
|
113
|
+
- name: Install Rust toolchain
|
|
114
|
+
uses: dtolnay/rust-toolchain@1.99.0
|
|
115
|
+
|
|
116
|
+
- name: Cache cargo registry
|
|
117
|
+
uses: actions/cache@v4
|
|
118
|
+
with:
|
|
119
|
+
path: |
|
|
120
|
+
~/.cargo/registry
|
|
121
|
+
~/.cargo/git
|
|
122
|
+
target
|
|
123
|
+
key: ${{ runner.os }}-bindings-js-${{ hashFiles('**/Cargo.toml') }}
|
|
124
|
+
|
|
125
|
+
- uses: actions/setup-node@v4
|
|
126
|
+
with:
|
|
127
|
+
node-version: ${{ matrix.node }}
|
|
128
|
+
|
|
129
|
+
- name: Install dependencies
|
|
130
|
+
working-directory: crates/llmsim-js
|
|
131
|
+
run: npm ci
|
|
132
|
+
|
|
133
|
+
- name: Build (debug)
|
|
134
|
+
working-directory: crates/llmsim-js
|
|
135
|
+
run: npm run build:debug
|
|
136
|
+
|
|
137
|
+
- name: Test
|
|
138
|
+
shell: bash
|
|
139
|
+
working-directory: crates/llmsim-js
|
|
140
|
+
run: node --test __test__/*.test.mjs
|
|
141
|
+
|
|
142
|
+
- name: Pack dry run
|
|
143
|
+
if: runner.os == 'Linux' && matrix.node == '22'
|
|
144
|
+
working-directory: crates/llmsim-js
|
|
145
|
+
run: npm pack --dry-run
|