-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
248 lines (237 loc) · 9.29 KB
/
Copy pathpyproject.toml
File metadata and controls
248 lines (237 loc) · 9.29 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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# AgentContextOS — Python workspace root
# Managed by uv (https://docs.astral.sh/uv/)
[tool.uv.workspace]
members = [
"packages/core",
"packages/config",
"packages/observability",
"packages/policy",
"packages/ragctl",
"packages/backends",
"packages/parsers",
"packages/ocr",
"packages/chunker",
"packages/enricher",
"packages/pii",
"packages/embedders",
"packages/ingest",
"packages/retrieval",
"packages/query",
"packages/reranker",
"packages/packer",
"packages/graphrag",
"packages/cache",
"packages/guard",
"packages/breaker",
"packages/quota",
"packages/provenance",
"packages/feedback",
"packages/drift",
"packages/agent",
"packages/webhooks",
"packages/sso",
"packages/compliance",
"packages/injection",
"apps/gateway",
"sdks/python",
]
[dependency-groups]
dev = [
"pytest>=9.0.3",
"pytest-asyncio>=1.3.0",
"mypy>=2.1.0",
"ruff>=0.15.14",
"hypothesis>=6.152.9",
"pre-commit>=4.6.0",
"pip-audit>=2.10.0",
"pytest-cov>=7.1.0",
"types-pyyaml>=6.0.12.20260518",
# gRPC codegen tooling (Step 3.2) — proto/rag.proto stub generation +
# mypy-protobuf .pyi emission. Runtime grpcio deps live in
# apps/gateway/pyproject.toml.
"grpcio-tools>=1.66",
"mypy-protobuf>=3.6",
]
# ---------------------------------------------------------------------------
# Ruff — linting + formatting
# ---------------------------------------------------------------------------
[tool.ruff]
line-length = 100
target-version = "py312"
# Generated gRPC stubs are committed (for the drift gate) but excluded from
# lint/format — protoc/mypy-protobuf own that output format, not us.
extend-exclude = [
"apps/gateway/src/rag_gateway/_grpc_gen",
# GTM demo tooling (slide builders + adversarial safety demos) — not shipped
# code; held to a lighter bar than the workspace packages.
"scripts/demo",
]
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "S", "ANN", "T"]
ignore = [
"ANN401", # Any allowed in plugin SPIs
]
unfixable = ["B"]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101", "S105", "S106", "ANN"]
"packages/**/tests/**/*.py" = ["S101", "S105", "S106", "ANN"]
"apps/**/tests/**/*.py" = ["S101", "S105", "S106", "ANN"]
"sdks/**/tests/**/*.py" = ["S101", "S105", "S106", "ANN"]
"**/conftest.py" = ["ANN"]
# Typer uses Argument/Option as default values — B008 is a false positive here.
"**/cli.py" = ["B008"]
"**/ragctl/main.py" = ["B008"]
# FastAPI uses File/Form/Depends as default values — same B008 false positive.
"**/rag_gateway/app.py" = ["B008"]
# Scripts, code generators, and infra setup legitimately write to stdout/stderr.
# S603/S607 are also ignored for scripts/: dev tooling invokes known executables
# (git, uv, etc.) on PATH with fixed argument lists — not user input.
"scripts/**/*.py" = ["T201", "S603", "S607"]
"infra/**/*.py" = ["T201"]
"**/gen_schema*.py" = ["T201"]
# Eval harnesses are CLI-style scripts that legitimately print to stdout; the
# regression bisector (Step 5.6d) also invokes git + python (known executables,
# fixed argv) like scripts/, so it shares the S603/S607 ignore.
"eval/**/*.py" = ["T201", "S603", "S607"]
# ---------------------------------------------------------------------------
# Mypy — strict type checking
# ---------------------------------------------------------------------------
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_configs = true
ignore_missing_imports = false
plugins = ["pydantic.mypy"]
# Multiple test directories share file names across workspace packages
# (e.g. apps/gateway/tests/test_query.py vs packages/ragctl/tests/test_query.py).
# Excluding tests from mypy's module-resolution sweep avoids the
# "Duplicate module" failure while still letting strict checks cover all
# production source under packages/*/src/ and apps/*/src/. Pytest, ruff,
# and the test runner cover quality on the test side.
exclude = [
"tests/$",
"/tests/",
"_grpc_gen",
]
# Third-party libraries without py.typed or stubs (backends + parsers packages).
# gcloud.aio.* is behind the optional [gcs] extra — CI runs `uv sync` without
# it, so mypy needs to tolerate the module being absent.
[[tool.mypy.overrides]]
module = [
"asyncpg.*",
"pgvector.*",
"aiofiles.*",
"aioboto3.*",
"botocore.*",
"qdrant_client.*",
"gcloud.*",
# Postgres CDC driver — lives behind the [postgres-cdc] extra in
# rag-backends and is absent at lint time on the default install.
"psycopg.*",
# Parser libraries
"puremagic.*",
"markdown_it.*",
"bs4.*",
"pypdf.*",
"docx.*",
"pptx.*",
"openpyxl.*",
# OCR libraries (extras [tesseract] and [paddle] — may be absent at lint time)
"pytesseract.*",
"paddleocr.*",
"numpy.*",
"PIL.*",
# Chunker tokenizer (tiktoken ships extension wheels but no .pyi stubs).
"tiktoken.*",
# Enricher dependencies (langdetect + textstat ship pure-Python wheels
# but no .pyi stubs).
"langdetect.*",
"textstat.*",
# PII detector — Presidio lives behind the [presidio] extra and
# may be absent at lint time.
"presidio_analyzer.*",
# Embedder backends — each lives behind its own extra and may be
# absent at lint time.
"openai.*",
"cohere.*",
"sentence_transformers.*",
# Step 2.2 — vector retrieval backends behind their own extras.
"weaviate.*",
"pinecone.*",
"elasticsearch.*",
# Step 2.3 — in-process BM25 backend behind the [tantivy] extra.
"tantivy.*",
# Step 2.4 — knowledge-graph backends behind [neo4j] / [memgraph] /
# [networkx] extras.
"neo4j.*",
"networkx.*",
# Step 6.7c — BYOK cloud KMS providers behind [kms-gcp] / [kms-azure] /
# [kms-vault] extras; absent at lint time on the default install.
"google.cloud.*",
"azure.*",
"hvac.*",
# Step 6.8 — SSO/SCIM. defusedxml (a rag-sso core dep) ships no type stubs;
# PyJWT + signxml live behind the [oidc] / [saml] extras and are lazily
# imported, so they are absent at lint time on the default install.
"defusedxml.*",
"jwt.*",
"signxml.*",
# Step 2.9 — optional Leiden detector behind the [leiden] extra.
"leidenalg.*",
"igraph.*",
# Step 3.2 — gRPC. grpc-stubs is not pulled in by default; the generated
# _pb2 / _pb2_grpc modules ship their own .pyi (mypy-protobuf) so this
# only suppresses missing-stub errors for the grpcio runtime itself.
"grpc.*",
"grpc_reflection.*",
"grpc_health.*",
# Step 3.8 — framework adapters (agentcontextos.integrations.*). Each
# framework lives behind its own SDK extra and is absent on the default
# install; dspy additionally ships no py.typed marker.
"langchain_core.*",
"llama_index.*",
"haystack.*",
"dspy.*",
"langgraph.*",
"crewai.*",
"semantic_kernel.*",
"autogen_core.*",
]
ignore_missing_imports = true
# Generated gRPC stubs — committed but excluded from strict checks because
# protoc/mypy-protobuf output is reformatted on regen and not under our
# control. The drift gate (scripts/check_proto_drift.py) catches stale
# stubs; mypy on the surrounding service code is what matters.
[[tool.mypy.overrides]]
module = "rag_gateway._grpc_gen.*"
ignore_errors = true
# ---------------------------------------------------------------------------
# Pytest
# ---------------------------------------------------------------------------
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests", "packages"]
pythonpath = ["packages/core/src", "packages/config/src", "packages/observability/src", "packages/policy/src", "packages/ragctl/src", "packages/backends/src", "packages/parsers/src", "packages/ocr/src", "packages/chunker/src", "packages/enricher/src", "packages/pii/src", "packages/embedders/src", "packages/ingest/src", "packages/retrieval/src", "packages/query/src", "packages/reranker/src", "packages/packer/src", "packages/graphrag/src", "packages/cache/src", "packages/guard/src", "packages/breaker/src", "packages/quota/src", "packages/provenance/src", "packages/feedback/src", "packages/drift/src", "packages/agent/src", "packages/webhooks/src", "packages/sso/src", "packages/compliance/src", "packages/injection/src", "apps/gateway/src", "."]
# spi_signature.py is the SPI signature linter (Step 1.1a); referenced by name in
# docs/architecture/request-context.md. Collected alongside test_*.py files.
# coverage.py is the PolicyEngine coverage linter (Step 1.1c).
python_files = ["test_*.py", "*_test.py", "spi_signature.py", "coverage.py"]
addopts = "-x -q --tb=short --import-mode=importlib"
markers = [
"contract: SPI conformance tests",
"integration: requires running backends",
"e2e: full end-to-end stack",
"slow: takes > 10 s",
"perf: latency / load gates (in-process, no infrastructure)",
"redteam: adversarial security probe suites (prompt injection / ACL bypass / PII egress / tenant escape)",
]
# ---------------------------------------------------------------------------
# Coverage
# ---------------------------------------------------------------------------
[tool.coverage.run]
source = ["packages", "apps/gateway"]
omit = ["*/tests/*", "*/conftest.py"]
[tool.coverage.report]
show_missing = true
# fail_under re-enabled in Step 0.2 once real source code exists