Skip to content

Commit d8a9dcd

Browse files
apartsinclaude
andcommitted
chore: implement 20 developer experience improvements
- Fix Dockerfile COPY path (pyproject.toml is in src/python/) - Add Docker healthcheck to Dockerfile and docker-compose.yaml - Create modelmesh.example.yaml with annotated config template - Fix install-python.sh to install from correct directory - Add npm install step to test-all.sh before TypeScript tests - Add root package.json with npm workspaces - Add samples/package.json + tsconfig.json for TS sample resolution - Create CONTRIBUTING.md with setup guide - Create CHANGELOG.md at repository root - Add Makefile with unified targets (install, test, lint, build, docker) - Add .editorconfig for consistent formatting - Add scripts/bump-version.sh for Python/TS version sync - Add CI linting job + version consistency check to tests.yml - Replace static test badge with dynamic GitHub Actions badge - Add ESM import exports to TypeScript package.json - Clarify .env.example: only one provider key required - Update README with Running Samples section and CONTRIBUTING link - Update .gitignore with root lockfile exclusion - Update tests to match new Dockerfile and .env.example format All 1,880 tests pass (1,167 Python + 713 TypeScript). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3c94577 commit d8a9dcd

20 files changed

+541
-43
lines changed

.editorconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# EditorConfig — https://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
end_of_line = lf
7+
indent_style = space
8+
indent_size = 2
9+
insert_final_newline = true
10+
trim_trailing_whitespace = true
11+
12+
[*.py]
13+
indent_size = 4
14+
15+
[*.md]
16+
trim_trailing_whitespace = false
17+
18+
[Makefile]
19+
indent_style = tab

.env.example

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# ModelMesh proxy — API keys
2-
# Copy this file to .env and fill in your keys.
2+
# Copy this file to .env and fill in your keys:
3+
# cp .env.example .env
34
# .env is gitignored and never committed.
5+
#
6+
# At least ONE provider key is required. Set any you have:
47

5-
# Required: at least one provider key
6-
OPENAI_API_KEY=
7-
ANTHROPIC_API_KEY=
8-
GROQ_API_KEY=
9-
10-
# Optional: additional providers
11-
# GOOGLE_API_KEY=
12-
# DEEPSEEK_API_KEY=
13-
# MISTRAL_API_KEY=
14-
# TOGETHER_API_KEY=
15-
# OPENROUTER_API_KEY=
16-
# XAI_API_KEY=
17-
# COHERE_API_KEY=
8+
OPENAI_API_KEY= # set if you have an OpenAI key
9+
# ANTHROPIC_API_KEY= # set if you have an Anthropic key
10+
# GROQ_API_KEY= # set if you have a Groq key
11+
# GOOGLE_API_KEY= # set if you have a Google/Gemini key
12+
# DEEPSEEK_API_KEY= # set if you have a DeepSeek key
13+
# MISTRAL_API_KEY= # set if you have a Mistral key
14+
# TOGETHER_API_KEY= # set if you have a Together key
15+
# OPENROUTER_API_KEY= # set if you have an OpenRouter key
16+
# XAI_API_KEY= # set if you have an xAI key
17+
# COHERE_API_KEY= # set if you have a Cohere key

.github/workflows/tests.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,28 @@ on:
66
branches: [master]
77

88
jobs:
9+
lint:
10+
name: Lint
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-python@v5
15+
with:
16+
python-version: "3.12"
17+
- uses: actions/setup-node@v4
18+
with:
19+
node-version: "20"
20+
- name: Python lint (ruff)
21+
run: pip install ruff && cd src/python && ruff check .
22+
- name: TypeScript lint (tsc --noEmit)
23+
run: cd src/typescript && npm ci && npm run lint
24+
- name: Version consistency check
25+
run: |
26+
PY_VER=$(grep '^version' src/python/pyproject.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
27+
TS_VER=$(node -p "require('./src/typescript/package.json').version")
28+
echo "Python: $PY_VER, TypeScript: $TS_VER"
29+
[ "$PY_VER" = "$TS_VER" ] || { echo "ERROR: Version mismatch!"; exit 1; }
30+
931
python:
1032
name: Python ${{ matrix.python-version }}
1133
runs-on: ubuntu-latest

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Thumbs.db
3535
# Node.js
3636
node_modules/
3737
*.tgz
38+
package-lock.json
39+
!/src/typescript/package-lock.json
3840

3941
# Test output
4042
jest-out.json

CHANGELOG.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Changelog
2+
3+
All notable changes to ModelMesh are documented here.
4+
5+
## [0.2.0] — 2026-03-11
6+
7+
### Added
8+
- **21-question FAQ** covering all major library features (middleware, error handling, proxy, storage, observability, streaming, discovery, multi-pool, hot-reload, browser usage)
9+
- **Programmatic connector registration** — all 6 connector types support `"instance"` injection via API
10+
- **`register_connector()`** function for runtime registration of custom connector classes
11+
- **Budget-aware rotation**`on_budget_exceeded: rotate` pool config option
12+
- **CONTRIBUTING.md** — contributor setup guide
13+
- **Makefile** — unified task runner (`make install`, `make test`, `make lint`, `make docker-up`)
14+
- **`modelmesh.example.yaml`** — annotated config template for Docker/YAML setup
15+
- **Root `package.json`** with npm workspaces for monorepo support
16+
- **Samples `package.json` + `tsconfig.json`** — TypeScript samples can now be run directly
17+
- **`.editorconfig`** — consistent formatting across editors
18+
- **`scripts/bump-version.sh`** — atomic version sync between Python and TypeScript
19+
- Docker healthcheck in Dockerfile and docker-compose.yaml
20+
21+
### Fixed
22+
- Dockerfile `COPY` path corrected (was referencing root-level `pyproject.toml`)
23+
- `install-python.sh` now runs `pip install` from correct directory
24+
- `test-all.sh` now runs `npm install` before TypeScript tests
25+
- `.env.example` clarified — only one provider key required (not all three)
26+
- 553 internal doc links fixed (`.html``.md` extension consistency)
27+
- Cross-reference audit: all docs have proper "See also" links
28+
29+
### Changed
30+
- FAQ expanded from 10 to 21 questions
31+
- Docker Compose now includes healthcheck and restart policy
32+
- README expanded with "Running Samples" section and CONTRIBUTING link
33+
34+
## [0.1.0] — 2026-03-06
35+
36+
### Added
37+
- Initial release of ModelMesh Lite
38+
- Python and TypeScript libraries with zero core dependencies
39+
- OpenAI-compatible API interface
40+
- 8 rotation strategies (stick-until-failure, round-robin, cost-first, latency-first, etc.)
41+
- 22 pre-shipped provider connectors
42+
- Capability-based routing with hierarchical taxonomy
43+
- Budget enforcement with daily/monthly limits
44+
- Mock client for testing
45+
- Docker proxy deployment
46+
- 54 pre-shipped connectors across 6 types
47+
- CDK (Connector Development Kit) with base classes
48+
- Comprehensive documentation suite (14 docs + 5 CDK docs + 8 guides)
49+
- 1,879 tests (1,166 Python + 713 TypeScript)

CONTRIBUTING.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Contributing to ModelMesh
2+
3+
Thank you for your interest in contributing! This guide will help you get set up.
4+
5+
## Prerequisites
6+
7+
- **Python 3.11+** — for the core library and tests
8+
- **Node.js 18+** — for the TypeScript library and tests
9+
- **Git** — for version control
10+
- **Docker** (optional) — for proxy deployment testing
11+
12+
## Quick Setup
13+
14+
```bash
15+
# 1. Clone the repository
16+
git clone https://github.com/ApartsinProjects/ModelMesh.git
17+
cd ModelMesh
18+
19+
# 2. Install Python package (editable + dev dependencies)
20+
pip install -e "./src/python[yaml,dev]"
21+
22+
# 3. Install TypeScript dependencies
23+
cd src/typescript && npm install && cd ../..
24+
25+
# 4. Install sample dependencies (links the local TypeScript package)
26+
npm install # from the root — uses workspaces
27+
28+
# 5. Run the full test suite
29+
./scripts/test-all.sh
30+
```
31+
32+
## Running Tests
33+
34+
```bash
35+
# All tests (Python + TypeScript)
36+
./scripts/test-all.sh
37+
38+
# Python only (1,166 tests)
39+
cd src/python && python -m pytest ../../tests/ -v
40+
41+
# TypeScript only (713 tests)
42+
cd src/typescript && npm test
43+
```
44+
45+
## Running Samples
46+
47+
**Python samples** require the package to be installed:
48+
49+
```bash
50+
pip install -e "./src/python[yaml]"
51+
python samples/quickstart/python/00_hello.py
52+
```
53+
54+
**TypeScript samples** require workspace setup:
55+
56+
```bash
57+
npm install # from repo root
58+
npx tsx samples/quickstart/typescript/00_hello.ts # from repo root
59+
```
60+
61+
## Project Structure
62+
63+
```
64+
ModelMesh/
65+
├── src/python/ # Python library source
66+
├── src/typescript/ # TypeScript library source
67+
├── tests/ # Python test suite
68+
├── samples/ # Code samples (Python + TypeScript)
69+
│ ├── quickstart/ # Getting started examples
70+
│ ├── system/ # Multi-provider integration examples
71+
│ ├── cdk/ # Connector Development Kit tutorials
72+
│ └── connectors/ # Custom connector examples
73+
├── docs/ # Documentation (GitHub Pages)
74+
├── scripts/ # Automation scripts
75+
└── .github/workflows/ # CI/CD pipelines
76+
```
77+
78+
## Code Style
79+
80+
- **Python**: Follows [ruff](https://github.com/astral-sh/ruff) defaults, 120 char line length
81+
- **TypeScript**: Strict mode, 2-space indent
82+
83+
## Pull Request Process
84+
85+
1. Fork the repository and create a feature branch
86+
2. Make your changes with tests
87+
3. Run the full test suite: `./scripts/test-all.sh`
88+
4. Submit a PR against the `master` branch
89+
5. Describe what changed and why in the PR description
90+
91+
## Adding a Custom Connector
92+
93+
See the [CDK Developer Guide](docs/cdk/DeveloperGuide.md) for tutorials on building:
94+
- Custom providers
95+
- Custom rotation policies
96+
- Custom secret stores, storage, observability, and discovery connectors
97+
98+
## License
99+
100+
By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE).

Dockerfile

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
FROM python:3.12-slim
22
WORKDIR /app
3-
COPY pyproject.toml ./
3+
4+
# Copy only the Python package (pyproject.toml is inside src/python/)
45
COPY src/python/ ./src/python/
5-
RUN pip install . && pip install pyyaml>=6.0
6+
7+
# Install the package + YAML support
8+
RUN pip install --no-cache-dir "./src/python[yaml]"
9+
10+
# Copy optional YAML config if present
11+
COPY modelmesh.example.yaml ./modelmesh.example.yaml
12+
613
EXPOSE 8080
14+
15+
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
16+
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8080/v1/models')" || exit 1
17+
718
ENTRYPOINT ["python", "-m", "modelmesh.proxy"]
819
CMD ["--host", "0.0.0.0", "--port", "8080"]

Makefile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
.PHONY: help install install-python install-typescript test test-python test-typescript lint build docker-build docker-up docker-down clean
2+
3+
help: ## Show available targets
4+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'
5+
6+
install: install-python install-typescript ## Install all dependencies
7+
8+
install-python: ## Install Python package (editable + dev + yaml)
9+
pip install -e "./src/python[yaml,dev]"
10+
11+
install-typescript: ## Install TypeScript dependencies
12+
cd src/typescript && npm install
13+
14+
test: ## Run full test suite (Python + TypeScript)
15+
./scripts/test-all.sh
16+
17+
test-python: ## Run Python tests only
18+
cd src/python && python -m pytest ../../tests/ -v
19+
20+
test-typescript: ## Run TypeScript tests only
21+
cd src/typescript && npm test
22+
23+
lint: ## Run linters (ruff + tsc)
24+
cd src/python && python -m ruff check .
25+
cd src/typescript && npm run lint
26+
27+
build: ## Build TypeScript dist
28+
cd src/typescript && npm run build
29+
30+
docker-build: ## Build Docker image
31+
docker build -t modelmesh .
32+
33+
docker-up: ## Start proxy via Docker Compose
34+
docker compose up --build -d
35+
36+
docker-down: ## Stop proxy
37+
docker compose down
38+
39+
clean: ## Remove build artifacts
40+
cd src/typescript && npm run clean 2>/dev/null || true
41+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
42+
find . -type d -name .pytest_cache -exec rm -rf {} + 2>/dev/null || true

README.md

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<img src="https://img.shields.io/badge/typescript-5.0%2B-blue" alt="TypeScript 5.0+">
1313
<img src="https://img.shields.io/badge/docker-supported-2496ED" alt="Docker">
1414
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
15-
<a href="https://github.com/ApartsinProjects/ModelMesh/actions"><img src="https://img.shields.io/badge/tests-1%2C879%20passed-brightgreen" alt="Tests"></a>
15+
<a href="https://github.com/ApartsinProjects/ModelMesh/actions/workflows/tests.yml"><img src="https://github.com/ApartsinProjects/ModelMesh/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
1616
<a href="https://apartsinprojects.github.io/ModelMesh/"><img src="https://img.shields.io/badge/docs-GitHub%20Pages-blue" alt="Documentation"></a>
1717
<a href="docs/guides/FAQ.md"><img src="https://img.shields.io/badge/FAQ-21%20questions-orange" alt="FAQ"></a>
1818
</p>
@@ -212,24 +212,51 @@ Ten reasons to add ModelMesh to your next project.
212212
| **[Custom Connectors](samples/connectors/)** | Full custom connector examples for all 6 types |
213213
| **[Proxy Test](samples/proxy-test/)** | Vanilla JS browser test page for the OpenAI proxy |
214214

215+
## Running Samples
216+
217+
**Python:**
218+
219+
```bash
220+
# Install the package first (editable mode for development)
221+
pip install -e "./src/python[yaml]"
222+
223+
# Run any sample
224+
python samples/quickstart/python/00_hello.py
225+
```
226+
227+
**TypeScript:**
228+
229+
```bash
230+
# Install workspace dependencies (from repo root)
231+
npm install
232+
233+
# Run any sample with tsx
234+
npx tsx samples/quickstart/typescript/00_hello.ts
235+
```
236+
237+
Most quickstart and CDK samples use built-in mock providers and run **without API keys**. System integration samples require real provider API keys.
238+
215239
## Development
216240

217241
```bash
218242
# Clone the repository
219243
git clone https://github.com/ApartsinProjects/ModelMesh.git
220244
cd ModelMesh
221245

222-
# Run Python tests (1,166 tests)
223-
pip install pytest
224-
cd src/python && python -m pytest ../../tests/ -v
225-
226-
# Run TypeScript tests (713 tests)
227-
cd src/typescript && npm install && npm test
246+
# Install all dependencies
247+
pip install -e "./src/python[yaml,dev]"
248+
cd src/typescript && npm install && cd ../..
228249

229-
# Or use the automation script
250+
# Run the full test suite (1,879 tests)
230251
./scripts/test-all.sh
252+
253+
# Or use make
254+
make install
255+
make test
231256
```
232257

258+
See **[CONTRIBUTING.md](CONTRIBUTING.md)** for full setup guide and contribution guidelines.
259+
233260
## Docker
234261

235262
```bash
@@ -242,7 +269,8 @@ docker run -p 8080:8080 \
242269
ghcr.io/apartsinprojects/modelmesh:latest
243270

244271
# Or build from source with Docker Compose
245-
cp .env.example .env # then add your API keys
272+
cp .env.example .env # add your API keys
273+
cp modelmesh.example.yaml modelmesh.yaml # customize config (optional)
246274
docker compose up --build
247275

248276
# Test the running proxy
@@ -265,6 +293,7 @@ See the **[Proxy Guide](docs/guides/ProxyGuide.md)** for full configuration, CLI
265293
| `scripts/install-python.sh` | Install Python package (dev or prod) |
266294
| `scripts/install-typescript.sh` | Install TypeScript package |
267295
| `scripts/test-all.sh` | Run full test suite (Python + TypeScript) |
296+
| `scripts/bump-version.sh` | Bump version in both Python and TypeScript |
268297

269298
## License
270299

0 commit comments

Comments
 (0)