-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
176 lines (150 loc) · 6.06 KB
/
Makefile
File metadata and controls
176 lines (150 loc) · 6.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
.PHONY: setup test lint format typecheck precommit prepush verify ci \
examples-quick examples-openai examples-anthropic examples-gemini examples-ollama \
smoke-examples \
itest docs-serve docs-build dist release docs-sync-brand
PY ?= python
setup:
$(PY) -m pip install --upgrade pip
$(PY) -m pip install -e .[dev]
test:
$(PY) -m pytest -q
lint:
ruff check .
@if command -v black >/dev/null 2>&1; then \
black --check .; \
else \
echo "[lint] black not found; skipping black check"; \
fi
format:
ruff check --fix .
@if command -v black >/dev/null 2>&1; then \
black .; \
else \
echo "[format] black not found; skipping black format"; \
fi
typecheck:
mypy .
precommit:
pre-commit run --all-files
prepush:
pre-commit run --all-files --hook-stage pre-push --show-diff-on-failure
verify: format typecheck
ci: lint typecheck test
# Fast CI profile: lints + typecheck + focused tests with coverage
ci-fast: lint typecheck
$(PY) -m pytest -m "unit or contracts or providers or examples" -q --cov=alloy --cov-report=term-missing --cov-fail-under=80
# Nightly / pre-release profile: run integration + parity_live
ci-nightly:
$(PY) -m pytest -m integration -q || true
$(PY) -m pytest -m parity_live -q || true
# Run a few fast, provider-agnostic examples with the fake backend
examples-quick:
@echo "[examples] Running quick smoke tests with ALLOY_BACKEND=fake"
ALLOY_BACKEND=fake $(PY) examples/10-commands/01_first_command.py
ALLOY_BACKEND=fake $(PY) examples/20-typed/02_dataclass_output.py
ALLOY_BACKEND=fake $(PY) examples/30-tools/01_simple_tool.py
# Provider-specific invoice extraction examples (require API keys)
examples-openai:
@if command -v dotenv >/dev/null 2>&1; then \
ALLOY_MODEL?=gpt-5-mini; \
dotenv -f .env run -- env ALLOY_MODEL=$$ALLOY_MODEL $(PY) examples/70-providers/01_same_task_openai.py; \
else \
ALLOY_MODEL?=gpt-5-mini; \
env ALLOY_MODEL=$$ALLOY_MODEL $(PY) examples/70-providers/01_same_task_openai.py; \
fi
examples-anthropic:
@if command -v dotenv >/dev/null 2>&1; then \
ALLOY_MODEL?=claude-sonnet-4-20250514; \
ALLOY_MAX_TOKENS?=512; \
dotenv -f .env run -- env ALLOY_MODEL=$$ALLOY_MODEL ALLOY_MAX_TOKENS=$$ALLOY_MAX_TOKENS $(PY) examples/70-providers/02_same_task_anthropic.py; \
else \
ALLOY_MODEL?=claude-sonnet-4-20250514; \
ALLOY_MAX_TOKENS?=512; \
env ALLOY_MODEL=$$ALLOY_MODEL ALLOY_MAX_TOKENS=$$ALLOY_MAX_TOKENS $(PY) examples/70-providers/02_same_task_anthropic.py; \
fi
examples-gemini:
@if command -v dotenv >/dev/null 2>&1; then \
ALLOY_MODEL?=gemini-2.5-flash; \
dotenv -f .env run -- env ALLOY_MODEL=$$ALLOY_MODEL $(PY) examples/70-providers/03_same_task_gemini.py; \
else \
ALLOY_MODEL?=gemini-2.5-flash; \
env ALLOY_MODEL=$$ALLOY_MODEL $(PY) examples/70-providers/03_same_task_gemini.py; \
fi
examples-ollama:
@echo "[examples] Ensure a local model is running: e.g., 'ollama run <model>'"
@if command -v dotenv >/dev/null 2>&1; then \
dotenv -f .env run -- $(PY) examples/70-providers/04_same_task_ollama.py; \
else \
$(PY) examples/70-providers/04_same_task_ollama.py; \
fi
# CI-friendly smoketest (fake backend; no provider keys)
smoke-examples:
ALLOY_BACKEND=fake $(PY) scripts/smoke_examples.py
itest:
@if command -v dotenv >/dev/null 2>&1; then \
echo "[itest] Using dotenv to load .env"; \
dotenv -f .env run -- $(PY) -m pytest -q tests/integration || \
(echo "[itest] dotenv CLI failed. Tip: pip install 'python-dotenv[cli]'"; \
echo "[itest] Falling back to running without .env"; \
$(PY) -m pytest -q tests/integration); \
else \
echo "[itest] dotenv CLI not found; running without .env"; \
echo "[itest] Tip: pip install 'python-dotenv[cli]' to load .env automatically"; \
$(PY) -m pytest -q tests/integration; \
fi
itest-openai:
@if command -v dotenv >/dev/null 2>&1; then \
dotenv -f .env run -- $(PY) -m pytest -q tests/integration/providers/test_openai_e2e.py; \
else \
$(PY) -m pytest -q tests/integration/providers/test_openai_e2e.py; \
fi
itest-anthropic:
@if command -v dotenv >/dev/null 2>&1; then \
ALLOY_IT_MODEL?=claude-sonnet-4-20250514; \
dotenv -f .env run -- env ALLOY_IT_MODEL=$$ALLOY_IT_MODEL $(PY) -m pytest -q tests/integration/providers/test_anthropic_e2e.py; \
else \
ALLOY_IT_MODEL?=claude-sonnet-4-20250514; \
env ALLOY_IT_MODEL=$$ALLOY_IT_MODEL $(PY) -m pytest -q tests/integration/providers/test_anthropic_e2e.py; \
fi
itest-gemini:
@if command -v dotenv >/dev/null 2>&1; then \
ALLOY_IT_MODEL?=gemini-1.5-pro; \
dotenv -f .env run -- env ALLOY_IT_MODEL=$$ALLOY_IT_MODEL $(PY) -m pytest -q tests/integration/providers/test_gemini_e2e.py; \
else \
ALLOY_IT_MODEL?=gemini-1.5-pro; \
env ALLOY_IT_MODEL=$$ALLOY_IT_MODEL $(PY) -m pytest -q tests/integration/providers/test_gemini_e2e.py; \
fi
itest-ollama:
@if command -v dotenv >/dev/null 2>&1; then \
ALLOY_IT_MODEL?=ollama:gpt-oss; \
dotenv -f .env run -- env ALLOY_IT_MODEL=$$ALLOY_IT_MODEL $(PY) -m pytest -q tests/integration/providers/test_ollama_e2e.py; \
else \
ALLOY_IT_MODEL?=ollama:gpt-oss; \
env ALLOY_IT_MODEL=$$ALLOY_IT_MODEL $(PY) -m pytest -q tests/integration/providers/test_ollama_e2e.py; \
fi
docs-serve:
@if command -v mkdocs >/dev/null 2>&1; then \
mkdocs serve -a 127.0.0.1:8000; \
else \
echo "[docs] mkdocs not found. Try: pip install 'alloy-ai[docs]'"; \
fi
docs-build: docs-sync-brand
@if command -v mkdocs >/dev/null 2>&1; then \
mkdocs build --strict; \
else \
echo "[docs] mkdocs not found. Try: pip install 'alloy-ai[docs]'"; \
fi
dist:
@python -m pip install --upgrade build >/dev/null 2>&1 || true
python -m build
@ls -lh dist || true
release:
@echo "Create and push a tag to publish via GitHub Actions (trusted publishing):"
@echo " git tag v$${VERSION:-0.1.1} && git push origin v$${VERSION:-0.1.1}"
@echo "Ensure PyPI trusted publishing is configured for this repo under the 'alloy-ai' project."
docs-sync-brand:
@if command -v $(PY) >/dev/null 2>&1; then \
$(PY) scripts/sync_brand_assets.py || true; \
else \
echo "[docs] python not found; skipping brand asset sync"; \
fi