agentflow-runtime 1.1.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.
- agentflow_runtime-1.1.0/.gitignore +88 -0
- agentflow_runtime-1.1.0/CHANGELOG.md +400 -0
- agentflow_runtime-1.1.0/LICENSE +21 -0
- agentflow_runtime-1.1.0/PKG-INFO +55 -0
- agentflow_runtime-1.1.0/README.md +182 -0
- agentflow_runtime-1.1.0/pyproject.toml +320 -0
- agentflow_runtime-1.1.0/requirements.txt +4 -0
- agentflow_runtime-1.1.0/src/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/constants.py +3 -0
- agentflow_runtime-1.1.0/src/ingestion/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/ingestion/cdc/__init__.py +5 -0
- agentflow_runtime-1.1.0/src/ingestion/cdc/normalizer.py +186 -0
- agentflow_runtime-1.1.0/src/ingestion/connectors/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/ingestion/connectors/mysql_cdc.py +63 -0
- agentflow_runtime-1.1.0/src/ingestion/connectors/postgres_cdc.py +68 -0
- agentflow_runtime-1.1.0/src/ingestion/producers/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/ingestion/producers/event_producer.py +237 -0
- agentflow_runtime-1.1.0/src/ingestion/schemas/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/ingestion/schemas/events.py +147 -0
- agentflow_runtime-1.1.0/src/ingestion/tenant_router.py +80 -0
- agentflow_runtime-1.1.0/src/logger.py +41 -0
- agentflow_runtime-1.1.0/src/orchestration/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/orchestration/dags/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/orchestration/dags/daily_batch.py +201 -0
- agentflow_runtime-1.1.0/src/processing/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/processing/event_replayer.py +250 -0
- agentflow_runtime-1.1.0/src/processing/flink_jobs/Dockerfile +55 -0
- agentflow_runtime-1.1.0/src/processing/flink_jobs/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/processing/flink_jobs/checkpointing.py +32 -0
- agentflow_runtime-1.1.0/src/processing/flink_jobs/session_aggregation.py +212 -0
- agentflow_runtime-1.1.0/src/processing/flink_jobs/session_aggregator.py +199 -0
- agentflow_runtime-1.1.0/src/processing/flink_jobs/stream_processor.py +316 -0
- agentflow_runtime-1.1.0/src/processing/iceberg_sink.py +348 -0
- agentflow_runtime-1.1.0/src/processing/local_pipeline.py +452 -0
- agentflow_runtime-1.1.0/src/processing/outbox.py +273 -0
- agentflow_runtime-1.1.0/src/processing/tracing.py +36 -0
- agentflow_runtime-1.1.0/src/processing/transformations/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/processing/transformations/enrichment.py +125 -0
- agentflow_runtime-1.1.0/src/quality/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/quality/monitors/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/quality/monitors/freshness_monitor.py +166 -0
- agentflow_runtime-1.1.0/src/quality/monitors/metrics_collector.py +367 -0
- agentflow_runtime-1.1.0/src/quality/validators/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/quality/validators/schema_validator.py +119 -0
- agentflow_runtime-1.1.0/src/quality/validators/semantic_validator.py +202 -0
- agentflow_runtime-1.1.0/src/serving/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/serving/api/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/serving/api/alert_dispatcher.py +51 -0
- agentflow_runtime-1.1.0/src/serving/api/alerts/__init__.py +38 -0
- agentflow_runtime-1.1.0/src/serving/api/alerts/dispatcher.py +299 -0
- agentflow_runtime-1.1.0/src/serving/api/alerts/escalation.py +290 -0
- agentflow_runtime-1.1.0/src/serving/api/alerts/evaluator.py +81 -0
- agentflow_runtime-1.1.0/src/serving/api/alerts/history.py +115 -0
- agentflow_runtime-1.1.0/src/serving/api/analytics.py +543 -0
- agentflow_runtime-1.1.0/src/serving/api/auth/__init__.py +46 -0
- agentflow_runtime-1.1.0/src/serving/api/auth/key_rotation.py +400 -0
- agentflow_runtime-1.1.0/src/serving/api/auth/manager.py +406 -0
- agentflow_runtime-1.1.0/src/serving/api/auth/middleware.py +331 -0
- agentflow_runtime-1.1.0/src/serving/api/main.py +390 -0
- agentflow_runtime-1.1.0/src/serving/api/middleware/logging.py +41 -0
- agentflow_runtime-1.1.0/src/serving/api/middleware/tracing.py +51 -0
- agentflow_runtime-1.1.0/src/serving/api/rate_limiter.py +76 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/admin.py +150 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/admin_ui.py +93 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/agent_query.py +639 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/alerts.py +134 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/batch.py +231 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/contracts.py +98 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/deadletter.py +337 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/lineage.py +218 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/search.py +103 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/slo.py +231 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/stream.py +141 -0
- agentflow_runtime-1.1.0/src/serving/api/routers/webhooks.py +93 -0
- agentflow_runtime-1.1.0/src/serving/api/security.py +83 -0
- agentflow_runtime-1.1.0/src/serving/api/telemetry.py +66 -0
- agentflow_runtime-1.1.0/src/serving/api/templates/admin.html +214 -0
- agentflow_runtime-1.1.0/src/serving/api/versioning.py +328 -0
- agentflow_runtime-1.1.0/src/serving/api/webhook_dispatcher.py +423 -0
- agentflow_runtime-1.1.0/src/serving/backends/__init__.py +117 -0
- agentflow_runtime-1.1.0/src/serving/backends/clickhouse_backend.py +310 -0
- agentflow_runtime-1.1.0/src/serving/backends/duckdb_backend.py +268 -0
- agentflow_runtime-1.1.0/src/serving/cache.py +169 -0
- agentflow_runtime-1.1.0/src/serving/db_pool.py +105 -0
- agentflow_runtime-1.1.0/src/serving/masking.py +122 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/__init__.py +0 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/catalog.py +177 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/contract_registry.py +258 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/entity_type_registry.py +107 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/nl_engine.py +189 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/__init__.py +3 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/contracts.py +47 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/engine.py +81 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/entity_queries.py +221 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/metric_queries.py +84 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/nl_queries.py +305 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/sql_builder.py +113 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query/sql_guard.py +3 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/query_engine.py +5 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/schema_evolution.py +175 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/search_index.py +337 -0
- agentflow_runtime-1.1.0/src/serving/semantic_layer/sql_guard.py +56 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.eggs/
|
|
8
|
+
|
|
9
|
+
.env
|
|
10
|
+
.env.local
|
|
11
|
+
*.pem
|
|
12
|
+
*.key
|
|
13
|
+
|
|
14
|
+
# Local secrets — copy from .example and fill with real values
|
|
15
|
+
docker/kafka-connect/secrets/postgres.properties
|
|
16
|
+
docker/kafka-connect/secrets/mysql.properties
|
|
17
|
+
|
|
18
|
+
.venv/
|
|
19
|
+
venv/
|
|
20
|
+
env/
|
|
21
|
+
|
|
22
|
+
.idea/
|
|
23
|
+
.vscode/
|
|
24
|
+
*.swp
|
|
25
|
+
*.swo
|
|
26
|
+
|
|
27
|
+
*.log
|
|
28
|
+
logs/
|
|
29
|
+
|
|
30
|
+
.terraform/
|
|
31
|
+
*.tfstate
|
|
32
|
+
*.tfstate.backup
|
|
33
|
+
.terraform.lock.hcl
|
|
34
|
+
|
|
35
|
+
data/
|
|
36
|
+
checkpoints/
|
|
37
|
+
*.parquet
|
|
38
|
+
*.avro
|
|
39
|
+
|
|
40
|
+
.pytest_cache/
|
|
41
|
+
htmlcov/
|
|
42
|
+
.coverage
|
|
43
|
+
coverage.xml
|
|
44
|
+
|
|
45
|
+
docker-compose.override.yml
|
|
46
|
+
|
|
47
|
+
# runtime artifacts
|
|
48
|
+
*.duckdb
|
|
49
|
+
*.duckdb.wal
|
|
50
|
+
.artifacts/
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.iceberg/
|
|
53
|
+
.tmp/
|
|
54
|
+
.dora/
|
|
55
|
+
.bandit-baseline.json
|
|
56
|
+
!.bandit-baseline.json
|
|
57
|
+
|
|
58
|
+
# DuckDB runtime state
|
|
59
|
+
*.duckdb.tmp/
|
|
60
|
+
|
|
61
|
+
# Node
|
|
62
|
+
node_modules/
|
|
63
|
+
|
|
64
|
+
# Mutation testing output
|
|
65
|
+
mutants/
|
|
66
|
+
|
|
67
|
+
# Session notes (root-level temp .md created during Codex/Claude sessions).
|
|
68
|
+
# NOTE: BCG_audit.md was removed from this list on 2026-04-19 -
|
|
69
|
+
# it was a release artifact, not a session note.
|
|
70
|
+
/codex_res.md
|
|
71
|
+
/res_co.md
|
|
72
|
+
/rep.md
|
|
73
|
+
/more_help.md
|
|
74
|
+
/About_DE_project.md
|
|
75
|
+
/RELEASING.md
|
|
76
|
+
sdk/agentflow/**/__pycache__/
|
|
77
|
+
sdk/agentflow/**/*.py[cod]
|
|
78
|
+
integrations/agentflow_integrations/**/__pycache__/
|
|
79
|
+
integrations/agentflow_integrations/**/*.py[cod]
|
|
80
|
+
# Local Iceberg warehouse/runtime state (intentionally untracked).
|
|
81
|
+
/warehouse/agentflow/
|
|
82
|
+
# Root API usage DuckDB runtime state (intentionally untracked).
|
|
83
|
+
/agentflow_api.duckdb
|
|
84
|
+
agentflow_bench_debug*.duckdb*
|
|
85
|
+
agentflow_demo_api.duckdb*
|
|
86
|
+
|
|
87
|
+
# Security scan workdir (generated by .github/workflows/security.yml safety job)
|
|
88
|
+
.tmp-security/
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to AgentFlow are documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
### Security (audit follow-up sprint 2026-04-27/28)
|
|
8
|
+
|
|
9
|
+
Two external audits delivered against `4a13d36` (Claude Opus + Codex p1–p9,
|
|
10
|
+
archived under `docs/audits/2026-04-27/`). Six commits closed all
|
|
11
|
+
P0/P1/P2 findings.
|
|
12
|
+
|
|
13
|
+
**Tenant isolation across the control plane (Codex p1 R3/R5, p2_1 #1-3,
|
|
14
|
+
p3 #4):** `pipeline_events` and `dead_letter_events` got a
|
|
15
|
+
`tenant_id VARCHAR DEFAULT 'default'` column with backwards-compatible
|
|
16
|
+
`ALTER TABLE ADD COLUMN IF NOT EXISTS` migration in init paths. Writers
|
|
17
|
+
populate tenant from `event['tenant']` / CDC source metadata; the CDC
|
|
18
|
+
normalizer accepts an explicit `topic=` argument and falls back through
|
|
19
|
+
`event['topic']` → `cdc.<source.db>` → `source.name`. Readers in
|
|
20
|
+
`/v1/stream/events`, `/v1/lineage`, `/v1/slo`, `/v1/deadletter`
|
|
21
|
+
(stats / list / detail / replay / dismiss), and the webhook dispatcher
|
|
22
|
+
now scope to `request.state.tenant_id`. Cross-tenant regression tests
|
|
23
|
+
added.
|
|
24
|
+
|
|
25
|
+
**SQL guard centralization (Codex p2_1 #4, p2_2 #4, p3 #1):** new
|
|
26
|
+
`_prepare_nl_sql()` helper in `nl_queries.py` is the only path that
|
|
27
|
+
validates translated SQL via `validate_nl_sql()`; called from
|
|
28
|
+
`execute_nl_query`, `paginated_query`, and `explain` before tenant
|
|
29
|
+
scoping and pagination wrapping. Closes the bypass on `/v1/query`
|
|
30
|
+
(paginated) and `/v1/query/explain`. PII masking and explain
|
|
31
|
+
`tables_accessed` rewritten on `sqlglot` AST so tenant-quoted SQL like
|
|
32
|
+
`"acme"."users_enriched"` is correctly extracted (Codex p3 #3).
|
|
33
|
+
|
|
34
|
+
**Entity allowlist enforcement (Codex p2_1 #4, p3 #2):** new
|
|
35
|
+
`tenant_key_allowed_tables()` helper in `auth/manager.py`. Applied to
|
|
36
|
+
NL query / explain / paginated query, batch query/metric items,
|
|
37
|
+
`/v1/search` (intersection with tenant key allowlist + post-filter so
|
|
38
|
+
metric documents are not silently dropped for scoped keys), and
|
|
39
|
+
`/v1/metrics/{metric}`.
|
|
40
|
+
|
|
41
|
+
**Auth fail-closed + entropy + scopes (Codex p2_1 #5, p2_2 #1-3):**
|
|
42
|
+
auth middleware now fails closed with `503` when no API keys are
|
|
43
|
+
configured; opt out with `AGENTFLOW_AUTH_DISABLED=true` for local dev
|
|
44
|
+
or `app.state.auth_disabled = True` for tests. Failed-auth throttling
|
|
45
|
+
extended to `/v1/admin/*`. `X-Forwarded-For` honoured only when the
|
|
46
|
+
immediate peer is in `AGENTFLOW_TRUSTED_PROXIES`. Generated API keys
|
|
47
|
+
now use `secrets.token_urlsafe(32)` (256-bit) instead of
|
|
48
|
+
`secrets.token_hex(4)` (32-bit).
|
|
49
|
+
|
|
50
|
+
**Secret hygiene (Codex p2_2 #5/8, p9 #4-5):** rotated active webhook
|
|
51
|
+
signing secret in `config/webhooks.yaml`, replaced tracked plaintext
|
|
52
|
+
API keys in `k8s/staging/values-staging.yaml` with placeholders +
|
|
53
|
+
`.yaml.example` schema reference, env-driven
|
|
54
|
+
`docker-compose.prod.yml` (`${CLICKHOUSE_*:?}`, `${GF_SECURITY_*:?}`),
|
|
55
|
+
placeholder passwords with prod warnings in
|
|
56
|
+
`helm/kafka-connect/values.yaml`, untracked
|
|
57
|
+
`docker/kafka-connect/secrets/{postgres,mysql}.properties` + `.example`
|
|
58
|
+
templates. Tight Hatch sdist `include`/`exclude` keeps secrets,
|
|
59
|
+
workflows, notebooks, k8s, helm, sdk, integrations, tests, and docs
|
|
60
|
+
out of the runtime distribution. `X-Admin-Key`, `Cookie`, and
|
|
61
|
+
`Set-Cookie` added to redacted headers. Webhook/alert `secret` excluded
|
|
62
|
+
from list/read/update responses (returned only on create). Admin UI
|
|
63
|
+
no longer renders `X-Admin-Key` into the DOM (`data-admin-key` and
|
|
64
|
+
auto-refresh JS removed). `/v1/admin/keys` no longer returns plaintext
|
|
65
|
+
key material.
|
|
66
|
+
|
|
67
|
+
**Helm hardening (Opus P1 #4-6):** `helm/agentflow/templates/` gained
|
|
68
|
+
`networkpolicy.yaml` (default-deny + ingress on the http port + egress
|
|
69
|
+
to DNS/Redis/Kafka/ClickHouse/OTLP) and `poddisruptionbudget.yaml`
|
|
70
|
+
(`minAvailable: 1`). Pod and container `securityContext` now sets
|
|
71
|
+
`runAsNonRoot=10001`, `readOnlyRootFilesystem=true`, drops all
|
|
72
|
+
capabilities, and applies `RuntimeDefault` seccomp; a memory `emptyDir`
|
|
73
|
+
mounts at `/tmp` for Python tempfile / httpx caches. NetworkPolicy is
|
|
74
|
+
off by default (enable per cluster).
|
|
75
|
+
|
|
76
|
+
**Supply chain (Codex p9):** committed `sdk-ts/package-lock.json`
|
|
77
|
+
(closes ENOLOCK on `npm audit`); `publish-npm.yml` switched to
|
|
78
|
+
`npm ci` + `npm test` + `npm audit` before publish. New `npm-audit` job
|
|
79
|
+
added to `security.yml`. `aquasecurity/trivy-action` pinned from
|
|
80
|
+
`@master` to `0.28.0`. Safety scope now includes
|
|
81
|
+
`integrations/pyproject.toml` resolved requirements.
|
|
82
|
+
|
|
83
|
+
**Vulnerable dep bumps:** `dagster>=1.13.1` (GHSA-mjw2-v2hm-wj34
|
|
84
|
+
SQL injection via dynamic partition keys), `langchain-core>=1.2.22`
|
|
85
|
+
(CVE-2026-26013 SSRF + CVE-2026-34070 path traversal),
|
|
86
|
+
`langchain-text-splitters>=1.1.2` (GHSA-fv5p-p927-qmxr SSRF redirect
|
|
87
|
+
bypass), `langsmith>=0.7.31`. Both `pyproject.toml` and
|
|
88
|
+
`integrations/pyproject.toml`.
|
|
89
|
+
|
|
90
|
+
**OpenAPI drift gate (Codex p4 #5):** `scripts/export_openapi.py`
|
|
91
|
+
gained a `--check` mode that diffs the regenerated `docs/openapi.json`
|
|
92
|
+
and `docs/agent-tools/*.json` against committed copies. Wired into
|
|
93
|
+
`contract.yml`; `docs/agent-tools/**` and `scripts/export_openapi.py`
|
|
94
|
+
added to `contract.yml` path triggers.
|
|
95
|
+
|
|
96
|
+
**Branch protection:** `main` has 12 required status checks
|
|
97
|
+
(`lint`, `test-unit`, `test-integration`, `perf-check`,
|
|
98
|
+
`helm-schema-live`, `schema-check`, `terraform-validate`,
|
|
99
|
+
`bandit`, `safety`, `npm-audit`, `trivy`, `contract`),
|
|
100
|
+
`strict=true`, force-pushes and deletions disabled, required
|
|
101
|
+
conversation resolution. `record-deployment` was originally part
|
|
102
|
+
of this set but its bot push couldn't pre-satisfy the protected
|
|
103
|
+
branch gate; the job was removed
|
|
104
|
+
and DORA metrics fall back to the GitHub Actions API source
|
|
105
|
+
already wired into `scripts/dora_metrics.py`.
|
|
106
|
+
|
|
107
|
+
**Python SDK alignment with server v1 contract (Codex p8 F1–F10):**
|
|
108
|
+
`api_version=` parameter and `X-AgentFlow-Version` header on sync and
|
|
109
|
+
async clients; capture of server version + deprecation headers into
|
|
110
|
+
`client.last_server_version` / `last_deprecation_warning`. Async
|
|
111
|
+
contract pinning parity with sync (in-memory contract cache, async
|
|
112
|
+
`_get_contract`). `as_of: datetime|str|None` parameter for entity
|
|
113
|
+
helpers and `get_metric` (sync + async). New `EntityMeta` and
|
|
114
|
+
`MetricMeta` Pydantic models exposed via `EntityEnvelope.meta` and
|
|
115
|
+
`MetricResult.meta`. Full `CatalogResponse` payload:
|
|
116
|
+
`streaming_sources`, `audit_sources`, plus `contract_version` on
|
|
117
|
+
catalog entities and metrics. Eight new public typed methods —
|
|
118
|
+
`explain_query`, `search`, `list_contracts`, `get_contract`,
|
|
119
|
+
`diff_contracts`, `validate_contract`, `get_lineage`, `get_changelog`.
|
|
120
|
+
New public `AgentFlowClient.get_entity()`; existing typed convenience
|
|
121
|
+
methods now delegate to it. `_request` accepts a `headers=` argument;
|
|
122
|
+
public POSTs accept `idempotency_key=` so retries are permitted on
|
|
123
|
+
5xx / timeout. New `PermissionDeniedError(AgentFlowError)` for `403`.
|
|
124
|
+
`CircuitOpenError` now inherits from `AgentFlowError`. Both
|
|
125
|
+
re-exported from `agentflow.__init__.__all__`. New
|
|
126
|
+
`sdk/agentflow/py.typed` marker; Hatch include rule keeps it in the
|
|
127
|
+
wheel/sdist.
|
|
128
|
+
|
|
129
|
+
**Test coverage gaps (Codex p5):** new unit suites covering
|
|
130
|
+
previously zero-coverage modules — `tests/unit/test_clickhouse_backend.py`
|
|
131
|
+
(14 tests: SQL translation, basic-auth POST, UNKNOWN_TABLE mapping,
|
|
132
|
+
URLError mapping, table_columns fallbacks, EXPLAIN, scalar, https
|
|
133
|
+
switch, health), `tests/unit/test_freshness_monitor.py` (8 tests:
|
|
134
|
+
latency / SLA window / breach signalling / skip-reason coverage /
|
|
135
|
+
EOF vs real Kafka error / consumer.close), and
|
|
136
|
+
`tests/unit/test_event_producer.py` (9 tests: all four generators,
|
|
137
|
+
DecimalEncoder, run_producer flush on KeyboardInterrupt,
|
|
138
|
+
_delivery_report).
|
|
139
|
+
|
|
140
|
+
**Test fixture posture:** new autouse
|
|
141
|
+
`_default_open_auth` fixture in `tests/integration/conftest.py` keeps
|
|
142
|
+
the legacy "open when no keys" behaviour for integration tests that do
|
|
143
|
+
not exercise auth (sets `AGENTFLOW_AUTH_DISABLED=true`); opt out with
|
|
144
|
+
the new `requires_auth_enforcement` marker.
|
|
145
|
+
`app.state.auth_disabled = False` is reset on every lifespan startup
|
|
146
|
+
so the test bypass flag does not leak across `TestClient` instances
|
|
147
|
+
(closes Codex review P2 on auth/middleware persistence).
|
|
148
|
+
|
|
149
|
+
**Documentation hygiene (Codex p6):** TypeScript SDK examples now
|
|
150
|
+
import from `"@agentflow/client"` (was `"agentflow"`); placeholder
|
|
151
|
+
`https://api.agentflow.dev` examples replaced with
|
|
152
|
+
`http://localhost:8000`; clone URL points at
|
|
153
|
+
`brownjuly2003-code/agentflow`; `docs/quality.md` marked stale;
|
|
154
|
+
`docs/glossary.md` test counts and `docs/engineering-standards.md`
|
|
155
|
+
coverage floor (`60%`) re-aligned with CI; runbook clarifies that
|
|
156
|
+
`make demo` does start Redis via Docker; migration guide module path
|
|
157
|
+
fixed (`local_pipeline.run`); registry-not-yet-published wording
|
|
158
|
+
through README, integrations, migration, sdk/sdk-ts READMEs.
|
|
159
|
+
|
|
160
|
+
**Operational verification:** the chaos smoke hang flagged in
|
|
161
|
+
`docs/release-readiness.md` did not reproduce on the new HEAD —
|
|
162
|
+
`tests/chaos/test_chaos_smoke.py` now passes `3 in 44s` standalone with
|
|
163
|
+
`--timeout=60 --timeout-method=thread`. `app.state.auth_disabled` is
|
|
164
|
+
reset on lifespan startup so the test bypass flag does not leak across
|
|
165
|
+
`TestClient` instances. Final smoke at audit-closure HEAD:
|
|
166
|
+
`670 passed, 4 skipped` on
|
|
167
|
+
`pytest tests/unit tests/integration tests/sdk tests/contract`.
|
|
168
|
+
|
|
169
|
+
**Audits archived:** the two source audits and the two CX task specs
|
|
170
|
+
that drove the impl are kept under `docs/audits/2026-04-27/` with a
|
|
171
|
+
README that maps findings to the six closing commits.
|
|
172
|
+
|
|
173
|
+
### Added
|
|
174
|
+
|
|
175
|
+
- **Debezium/Kafka Connect CDC operationalization**: local compose now
|
|
176
|
+
brings up Postgres/MySQL source databases, Kafka Connect, Debezium
|
|
177
|
+
connector registration, and raw CDC topic bootstrap for the AgentFlow
|
|
178
|
+
demo schema.
|
|
179
|
+
- **Kafka Connect Helm chart**: `helm/kafka-connect/` defines the
|
|
180
|
+
Connect worker deployment, connector registration hooks, secrets,
|
|
181
|
+
values schema, and topic bootstrap job for Kubernetes-shaped staging.
|
|
182
|
+
- **Canonical CDC normalizer**: raw Debezium envelopes from Postgres
|
|
183
|
+
and MySQL now normalize into the AgentFlow CDC contract before
|
|
184
|
+
downstream validation and Flink processing.
|
|
185
|
+
|
|
186
|
+
### Changed
|
|
187
|
+
|
|
188
|
+
- **Kafka Connect Helm secret contract**: `helm/kafka-connect`
|
|
189
|
+
values now reject ambiguous source-credential settings. Use exactly
|
|
190
|
+
one mode: chart-created demo Secret (`secrets.create=true`) or an
|
|
191
|
+
existing Kubernetes Secret (`secrets.create=false` with
|
|
192
|
+
`secrets.existingSecret`).
|
|
193
|
+
- **CDC watermarks**: the Flink CDC path now uses source timestamps
|
|
194
|
+
from normalized Debezium records, keeping event-time behavior aligned
|
|
195
|
+
with source database changes.
|
|
196
|
+
- **Performance gate enforcement**: `scripts/check_performance.py`
|
|
197
|
+
now enforces endpoint-level p99 gates instead of only aggregate
|
|
198
|
+
benchmark status.
|
|
199
|
+
|
|
200
|
+
### Documentation
|
|
201
|
+
|
|
202
|
+
- `docs/runbook.md` now documents local CDC startup, connector status
|
|
203
|
+
checks, the optional Docker CDC integration test, cleanup, and the
|
|
204
|
+
Kafka Connect Helm source-credential modes.
|
|
205
|
+
- `docs/plans/2026-04-debezium-kafka-connect-deployment-plan.md`
|
|
206
|
+
now reflects the implemented local/Helm CDC path, including topic
|
|
207
|
+
bootstrap, schema-history topic behavior, and the explicit Helm
|
|
208
|
+
secret contract.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## [1.1.0] - 2026-04-25
|
|
213
|
+
|
|
214
|
+
See [docs/migration/v1.1.md](docs/migration/v1.1.md) for upgrade instructions from v1.0.x.
|
|
215
|
+
|
|
216
|
+
### Added
|
|
217
|
+
|
|
218
|
+
- **MCP integration** for Claude Desktop, Cursor, and Windsurf:
|
|
219
|
+
`integrations/agentflow_integrations/mcp/` ships a Model Context
|
|
220
|
+
Protocol stdio server with `entity_lookup`, `metric_query`,
|
|
221
|
+
`nl_query`, `health_check`, and `list_entities` tools wrapping the
|
|
222
|
+
public `AgentFlowClient`. Install via `pip install -e "./integrations[mcp]"`
|
|
223
|
+
and launch with `python -m agentflow_integrations.mcp`. (07cb253)
|
|
224
|
+
- **Entity type registry**: the four core entity types (`order`,
|
|
225
|
+
`user`, `product`, `session`) now load from
|
|
226
|
+
`contracts/entities/*.yaml` instead of being hardcoded inside
|
|
227
|
+
`DataCatalog`. Adding a new entity type is a YAML file plus a
|
|
228
|
+
process restart. (f9e78de)
|
|
229
|
+
- **AWS OIDC Terraform module**
|
|
230
|
+
(`infrastructure/terraform/modules/github-oidc/`): IAM OIDC provider
|
|
231
|
+
and branch/environment-scoped IAM role for GitHub Actions Terraform
|
|
232
|
+
runs. `terraform-apply.yml` now reads `vars.AWS_TERRAFORM_ROLE_ARN`
|
|
233
|
+
and uses short-lived credentials exclusively. (f1f6908)
|
|
234
|
+
- **Benchmark history** (`.github/perf-history.json`): rolling log of
|
|
235
|
+
`p50/p95/p99/throughput` appended by a `perf-history-bot` commit on
|
|
236
|
+
each `main` push. Plot the trend locally with `make perf-plot`.
|
|
237
|
+
(447440a)
|
|
238
|
+
- **Codecov integration**: `codecov.yml` config, tokenless OIDC
|
|
239
|
+
upload in `ci.yml`, README badge, and
|
|
240
|
+
`docs/operations/codecov-setup.md`. (4a02945)
|
|
241
|
+
- **Entity profiling harness**: `scripts/profile_entity.py` client
|
|
242
|
+
that hits one entity endpoint at a fixed concurrency and prints
|
|
243
|
+
`p50/p95/p99`. Paired with `docs/perf/README.md` describing the
|
|
244
|
+
py-spy workflow and stack requirements for meaningful numbers.
|
|
245
|
+
(0873c94, 13ad163)
|
|
246
|
+
- **Scheduled chaos full suite**: `chaos.yml` now runs the full
|
|
247
|
+
suite daily at `0 4 * * *` plus on `workflow_dispatch`, and files a
|
|
248
|
+
GitHub issue tagged `chaos-failure` / `severity:high` when a
|
|
249
|
+
scheduled run breaks. (4dd27fa)
|
|
250
|
+
|
|
251
|
+
### Changed
|
|
252
|
+
|
|
253
|
+
- **Package versions synced to 1.0.1** across `pyproject.toml`,
|
|
254
|
+
`sdk/pyproject.toml`, `sdk/agentflow/__init__.py`, and
|
|
255
|
+
`sdk-ts/package.json`. Pinned with `tests/unit/test_version.py`.
|
|
256
|
+
(5d54b77)
|
|
257
|
+
- **Runtime/package identity split**: the root repo now publishes as
|
|
258
|
+
`agentflow-runtime` while the Python SDK publishes as
|
|
259
|
+
`agentflow-client` and keeps the `agentflow` import path and CLI.
|
|
260
|
+
Local test/install flows now install `./sdk` explicitly instead of
|
|
261
|
+
relying on `sys.path` shims or install order.
|
|
262
|
+
- **SDK PyPI distribution renamed**: published as `agentflow-client`
|
|
263
|
+
(was planned as `agentflow` in A01, but the name was already taken
|
|
264
|
+
on PyPI by an unrelated abandoned project). Python module and API
|
|
265
|
+
unchanged - `from agentflow import ...` still works. Install with
|
|
266
|
+
`pip install agentflow-client`.
|
|
267
|
+
- **`integrations/` package bumped to 1.0.1** with the `mcp`
|
|
268
|
+
optional extra and an `agentflow-mcp` console script; the stale
|
|
269
|
+
SDK dependency now points at the public `agentflow-client>=1.0.1`
|
|
270
|
+
package. (07cb253)
|
|
271
|
+
- **28 historical plan docs archived** from `docs/plans/` to
|
|
272
|
+
`docs/plans/codex-archive/`. `docs/plans/` now only holds live
|
|
273
|
+
work. (0e9fc00)
|
|
274
|
+
|
|
275
|
+
### Documentation
|
|
276
|
+
|
|
277
|
+
- v1.1 sprint task briefs under `docs/codex-tasks/2026-04-22/`
|
|
278
|
+
(T01-T10, self-contained one-PR ТЗ). (f448626)
|
|
279
|
+
- `docs/operations/aws-oidc-setup.md`, `docs/operations/chaos-runbook.md`,
|
|
280
|
+
`docs/operations/codecov-setup.md`.
|
|
281
|
+
- `docs/contracts/how-to-add-entity.md`.
|
|
282
|
+
- `docs/perf/README.md` profiling workflow and stack caveat.
|
|
283
|
+
- `integrations/agentflow_integrations/mcp/README.md` with Claude
|
|
284
|
+
Desktop config snippet.
|
|
285
|
+
|
|
286
|
+
### Dependencies
|
|
287
|
+
|
|
288
|
+
- `pyyaml>=6,<7` added to core dependencies (previously only
|
|
289
|
+
transitively present via dagster/langchain).
|
|
290
|
+
|
|
291
|
+
### Verification
|
|
292
|
+
|
|
293
|
+
Test suite status at sprint close: **552 tests passing**, 1 skipped,
|
|
294
|
+
0 regressions.
|
|
295
|
+
|
|
296
|
+
| Suite | Count | Duration |
|
|
297
|
+
|-------|-------|----------|
|
|
298
|
+
| unit | 360 | ~60 s |
|
|
299
|
+
| property + contract + sdk | 38 | ~31 s |
|
|
300
|
+
| e2e (non-dagster) | 13 | ~63 s |
|
|
301
|
+
| integration (non-Docker) | 141 | ~108 s |
|
|
302
|
+
|
|
303
|
+
### CI repair trail
|
|
304
|
+
|
|
305
|
+
Surface-level diagnosis after push surfaced six pre-existing CI
|
|
306
|
+
breakages that predate the v1.1 sprint (first observed 2026-04-20):
|
|
307
|
+
|
|
308
|
+
- **Contract Tests** (`54c3c27`, `2cf7a7b`): root and SDK both declare
|
|
309
|
+
`name = "agentflow"`, so `pip install -e sdk/` uninstalled the root
|
|
310
|
+
package and left `src` unimportable. Dropped the separate SDK install
|
|
311
|
+
and switched to `pip install -e ".[dev,cloud]"` so pyiceberg is
|
|
312
|
+
present when the fixture boots the API.
|
|
313
|
+
- **Load Test** (`b2f8344`, `aa470df`): same missing `[cloud]` extras
|
|
314
|
+
blocked uvicorn startup — `Connection refused` on port 8011. Added
|
|
315
|
+
the extras, then bumped `AGENTFLOW_RATE_LIMIT_RPM` to `600000` so
|
|
316
|
+
the 50-user locust workload stops saturating the limiter.
|
|
317
|
+
- **Staging Deploy** (`8bedb1d`): the `.gitignore` rule `AgentFlow*`
|
|
318
|
+
swallowed `helm/agentflow/` on case-insensitive filesystems. Added
|
|
319
|
+
`!helm/agentflow/` / `!helm/agentflow/**` exceptions and committed
|
|
320
|
+
the 12-file chart that existed only on dev machines.
|
|
321
|
+
- **Security Scan** (`68ca0da`): `aquasecurity/trivy-action@0.33.1`
|
|
322
|
+
was not a real release — switched to `@master` pending a pinned
|
|
323
|
+
version from the user. The resulting Trivy run now reaches the
|
|
324
|
+
scan step but the image has unresolved HIGH/CRITICAL findings that
|
|
325
|
+
still fail the gate (next-session work).
|
|
326
|
+
- **CI lint** (`70a7b64`): ran `ruff --fix` against the 27 files with
|
|
327
|
+
auto-fixable debt; 38 of 98 errors cleared. 60 harder lint errors
|
|
328
|
+
(E501, S603, E402, N802, B904) remain — a dedicated cleanup pass
|
|
329
|
+
is still needed before the `lint` job can go green.
|
|
330
|
+
- **E2E Tests**: pre-existing `wait_for_services` timeout on the
|
|
331
|
+
docker-compose-hosted API. Not investigated this session — the
|
|
332
|
+
stack uses `docker-compose.prod.yml` which pulls a dozen services;
|
|
333
|
+
the root cause likely overlaps with the rate-limiter / Kafka
|
|
334
|
+
readiness issue and needs hands-on debugging.
|
|
335
|
+
|
|
336
|
+
Status at session close: **Contract Tests should go green after
|
|
337
|
+
`2cf7a7b` lands, Load Test after `aa470df`, Staging Deploy after
|
|
338
|
+
`8bedb1d`**. CI lint, Security Scan (Trivy findings), and E2E Tests
|
|
339
|
+
still require follow-up.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## [1.0.1] - 2026-04-20
|
|
344
|
+
|
|
345
|
+
Post-publication patches ensuring clean-clone installation works out of the box.
|
|
346
|
+
|
|
347
|
+
### Fixed
|
|
348
|
+
|
|
349
|
+
- **SDK sources missing from git tree**: `sdk/agentflow/` and `integrations/agentflow_integrations/` were not tracked, causing ImportError on fresh clones. Now included. (302883e)
|
|
350
|
+
- **Cached bytecode in tracked paths**: `.pyc` files accidentally committed alongside SDK sources - removed. (a032f16)
|
|
351
|
+
- **Cloud extras missing from setup verification**: `pyiceberg`, `bcrypt` were not installed during verification, causing cryptic test failures. `make setup` now installs `[dev,integrations,cloud]` extras. (4e86759)
|
|
352
|
+
- **Bandit missing from dev verification deps**: `bandit` wasn't in dev extras, breaking security baseline check on clean clones. (cf3a602)
|
|
353
|
+
- **Bandit baseline missing from published repo**: `.bandit-baseline.json` was gitignored - required by `test_bandit_diff.py`. Now tracked. (669c9d7)
|
|
354
|
+
|
|
355
|
+
### Verification
|
|
356
|
+
|
|
357
|
+
Fresh clone installation flow confirmed:
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
git clone https://github.com/brownjuly2003-code/agentflow
|
|
361
|
+
cd agentflow
|
|
362
|
+
python -m venv .venv
|
|
363
|
+
.venv/Scripts/python -m pip install -e '.[dev,integrations,cloud]'
|
|
364
|
+
.venv/Scripts/python -m pytest tests/unit -q # -> 340 passed
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## [1.0.0] - 2026-04-20
|
|
370
|
+
|
|
371
|
+
### Added
|
|
372
|
+
|
|
373
|
+
- Python and TypeScript SDK resilience support: retry policies, circuit breakers, batching helpers, pagination helpers, and contract pinning
|
|
374
|
+
- Minimal admin dashboard at `/admin`
|
|
375
|
+
- Chaos smoke on pull requests plus scheduled full chaos coverage
|
|
376
|
+
- Performance regression gate in CI based on `docs/benchmark-baseline.json`
|
|
377
|
+
- Terraform apply workflow with environment approval and OIDC-ready AWS auth
|
|
378
|
+
- Fly.io demo deployment config in `deploy/fly/`
|
|
379
|
+
- Public-facing docs set: API reference, competitive analysis, security audit, glossary, and publication checklist
|
|
380
|
+
|
|
381
|
+
### Changed
|
|
382
|
+
|
|
383
|
+
- Entity lookup latency from the original ~`26,000 ms` baseline to the current `43-55 ms` release range, with entity p99 at `290-320 ms` in the checked-in baseline
|
|
384
|
+
- Query safety from regex-style scoping to `sqlglot` AST validation with allowlisted tables
|
|
385
|
+
- Hot-path entity reads from string interpolation to parameterized queries
|
|
386
|
+
- SDK configuration cleaned up around `configure_resilience()` while preserving backwards compatibility for existing callers
|
|
387
|
+
|
|
388
|
+
### Fixed
|
|
389
|
+
|
|
390
|
+
- Windows DuckDB file-lock flake in rotation tests
|
|
391
|
+
- Auth auto-revoke regression after the auth module split
|
|
392
|
+
- Analytics hot-path regression caused by cache stampede and schema re-bootstrap
|
|
393
|
+
- Missing Flink Terraform `application_code_configuration`
|
|
394
|
+
|
|
395
|
+
### Security
|
|
396
|
+
|
|
397
|
+
- Parameterized queries throughout the serving hot path
|
|
398
|
+
- `sqlglot` AST validator for natural-language-to-SQL translation
|
|
399
|
+
- Bandit baseline gate so only new findings fail CI
|
|
400
|
+
- API key rotation with grace period and auto-revoke support
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AgentFlow contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentflow-runtime
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Real-time data platform serving context to AI agents
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: bcrypt<6,>=5
|
|
9
|
+
Requires-Dist: confluent-kafka<3,>=2.5
|
|
10
|
+
Requires-Dist: dagster<2,>=1.13.1
|
|
11
|
+
Requires-Dist: duckdb<2,>=1.1
|
|
12
|
+
Requires-Dist: fastapi<1,>=0.111
|
|
13
|
+
Requires-Dist: httpx<1,>=0.27
|
|
14
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2,>=1.41
|
|
15
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi<1,>=0.62b0
|
|
16
|
+
Requires-Dist: opentelemetry-instrumentation-httpx<1,>=0.62b0
|
|
17
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.41
|
|
18
|
+
Requires-Dist: pandera<1,>=0.20
|
|
19
|
+
Requires-Dist: prometheus-client<1,>=0.21
|
|
20
|
+
Requires-Dist: pyarrow<19,>=17
|
|
21
|
+
Requires-Dist: pydantic-settings<3,>=2.5
|
|
22
|
+
Requires-Dist: pydantic<3,>=2.9
|
|
23
|
+
Requires-Dist: pyyaml<7,>=6
|
|
24
|
+
Requires-Dist: sqlglot<31,>=30
|
|
25
|
+
Requires-Dist: structlog<26,>=24.4
|
|
26
|
+
Requires-Dist: uvicorn[standard]<1,>=0.30
|
|
27
|
+
Provides-Extra: cloud
|
|
28
|
+
Requires-Dist: boto3<2,>=1.35; extra == 'cloud'
|
|
29
|
+
Requires-Dist: pyiceberg[pyiceberg-core]<1,>=0.7; extra == 'cloud'
|
|
30
|
+
Provides-Extra: contract
|
|
31
|
+
Requires-Dist: schemathesis==4.10.2; extra == 'contract'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: bandit<2,>=1.9; extra == 'dev'
|
|
34
|
+
Requires-Dist: build<2,>=1.2; extra == 'dev'
|
|
35
|
+
Requires-Dist: hatchling<2,>=1.25; extra == 'dev'
|
|
36
|
+
Requires-Dist: hypothesis<7,>=6; extra == 'dev'
|
|
37
|
+
Requires-Dist: jsonschema<5,>=4; extra == 'dev'
|
|
38
|
+
Requires-Dist: mypy<2,>=1.11; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-asyncio<1,>=0.24; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-cov<6,>=5; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest<9,>=8.3; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff<1,>=0.6; extra == 'dev'
|
|
43
|
+
Requires-Dist: testcontainers[kafka]<5,>=4.9; extra == 'dev'
|
|
44
|
+
Provides-Extra: flink
|
|
45
|
+
Requires-Dist: apache-flink==1.19.1; extra == 'flink'
|
|
46
|
+
Provides-Extra: integrations
|
|
47
|
+
Requires-Dist: langchain-core<2,>=1.2.22; extra == 'integrations'
|
|
48
|
+
Requires-Dist: langchain-text-splitters<2,>=1.1.2; extra == 'integrations'
|
|
49
|
+
Requires-Dist: langchain<2,>=0.3.30; extra == 'integrations'
|
|
50
|
+
Requires-Dist: langsmith<1,>=0.7.31; extra == 'integrations'
|
|
51
|
+
Requires-Dist: llama-index-core<1,>=0.12; extra == 'integrations'
|
|
52
|
+
Provides-Extra: llm
|
|
53
|
+
Requires-Dist: anthropic<1,>=0.39; extra == 'llm'
|
|
54
|
+
Provides-Extra: load
|
|
55
|
+
Requires-Dist: locust<3,>=2.29; extra == 'load'
|