agentflow-runtime 1.2.0__tar.gz → 1.4.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.2.0 → agentflow_runtime-1.4.0}/CHANGELOG.md +243 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/PKG-INFO +74 -39
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/README.md +65 -32
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/pyproject.toml +9 -7
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/tenant_router.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/iceberg_sink.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/local_pipeline.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/monitors/metrics_collector.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/alerts/dispatcher.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/auth/key_rotation.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/auth/manager.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/rate_limiter.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/slo.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/security.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/versioning.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/webhook_dispatcher.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/backends/__init__.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/cache.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/masking.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/contract_registry.py +2 -2
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/entity_type_registry.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/schema_evolution.py +1 -1
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/.gitignore +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/LICENSE +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/requirements.txt +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/constants.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/cdc/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/cdc/normalizer.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/connectors/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/connectors/mysql_cdc.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/connectors/postgres_cdc.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/producers/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/producers/event_producer.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/schemas/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/schemas/events.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/logger.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/orchestration/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/orchestration/dags/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/orchestration/dags/daily_batch.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/event_replayer.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/Dockerfile +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/checkpointing.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/session_aggregation.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/session_aggregator.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/stream_processor.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/outbox.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/tracing.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/transformations/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/transformations/enrichment.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/monitors/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/monitors/freshness_monitor.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/validators/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/validators/schema_validator.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/validators/semantic_validator.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/alert_dispatcher.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/alerts/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/alerts/escalation.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/alerts/evaluator.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/alerts/history.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/analytics.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/auth/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/auth/middleware.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/main.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/middleware/logging.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/middleware/tracing.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/admin.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/admin_ui.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/agent_query.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/alerts.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/batch.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/contracts.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/deadletter.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/lineage.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/search.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/stream.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/routers/webhooks.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/telemetry.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/api/templates/admin.html +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/audit_publisher.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/backends/clickhouse_backend.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/backends/duckdb_backend.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/db_pool.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/duckdb_connection.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/catalog.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/nl_engine.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/__init__.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/contracts.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/engine.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/entity_queries.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/metric_queries.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/nl_queries.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/sql_builder.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/sql_guard.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query_engine.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/search_index.py +0 -0
- {agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/sql_guard.py +0 -0
|
@@ -4,6 +4,249 @@ All notable changes to AgentFlow are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.4.0] - 2026-05-25
|
|
8
|
+
|
|
9
|
+
Maintenance release. No runtime API changes; bundles documentation,
|
|
10
|
+
CI hardening, repo hygiene, type-stub adoption, and Dependabot Tier A
|
|
11
|
+
wave 2 dependency bumps that landed in sessions 11–19.
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
- Top-level [`docs/SESSION_HANDOFF.md`](docs/SESSION_HANDOFF.md) — the
|
|
16
|
+
entry point for picking up the project cold. Includes the four
|
|
17
|
+
orientation commands to run first, the priority-tiered open work
|
|
18
|
+
(Tier A actionable Dependabot PRs, Tier B externally user-gated
|
|
19
|
+
A04/A05/A03, Tier C forward backlog), a compressed view of sessions
|
|
20
|
+
11 → 17, and the load-bearing lessons from session 17's regression
|
|
21
|
+
(Contract Tests path filter, Dependabot cascade transitive
|
|
22
|
+
conflicts, memory-staleness check before recommending). README
|
|
23
|
+
surfaces it at the top of the Documentation index.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Dependency resolver clash after the Dependabot merge cascade
|
|
28
|
+
(`#13 schemathesis 4.10 → 4.19` + `#22 pytest <9 → <10`). schemathesis
|
|
29
|
+
4.19 requires `pytest>=9`; `pytest-asyncio>=0.24,<1` capped pytest at
|
|
30
|
+
`<9` so the `contract` extra became unresolvable. Bumped to
|
|
31
|
+
`pytest-asyncio>=0.24,<2` so pytest-asyncio 1.3.0 (which supports
|
|
32
|
+
`pytest>=8.2,<10`) is installable. Same change was queued in
|
|
33
|
+
Dependabot PR #18; landing it directly here unblocks the Contract
|
|
34
|
+
Tests gate immediately.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- `.github/dependabot.yml` covering seven ecosystems on a Monday 06:00
|
|
39
|
+
Europe/Moscow weekly schedule: pip (root runtime, SDK, integrations),
|
|
40
|
+
npm (`sdk-ts/`), Docker (`Dockerfile.api`), GitHub Actions
|
|
41
|
+
(workflow pins), and Terraform (`infrastructure/terraform/`). Minor
|
|
42
|
+
and patch updates are grouped per ecosystem to keep the PR queue
|
|
43
|
+
reviewable; majors stay individual. `langchain-core`,
|
|
44
|
+
`langchain-text-splitters`, `langsmith`, and `dagster` have explicit
|
|
45
|
+
CVE-driven floors in `pyproject.toml`, so major bumps for those are
|
|
46
|
+
ignored (Dependabot still opens advisory PRs immediately for
|
|
47
|
+
GitHub-reported vulnerabilities regardless of group/interval).
|
|
48
|
+
Commit prefixes match `CONTRIBUTING.md` (`chore(deps,<scope>)`).
|
|
49
|
+
- `.editorconfig` at the repo root pinning UTF-8 + LF + trailing-whitespace
|
|
50
|
+
trim across the tree, with per-language overrides (Python 4-space /
|
|
51
|
+
100-col, JS/TS/JSON/YAML/TOML 2-space, Markdown keeps trailing
|
|
52
|
+
whitespace for hard-wrap line breaks, Makefile tabs). Aligns the
|
|
53
|
+
cross-editor behavior with what `ruff format` / `prettier` already
|
|
54
|
+
enforce in CI; aimed at contributors whose editor does not auto-pick
|
|
55
|
+
up `pyproject.toml` / `package.json` formatter config.
|
|
56
|
+
|
|
57
|
+
### Documentation
|
|
58
|
+
|
|
59
|
+
- Public-repo hygiene files added: `SECURITY.md` (private vulnerability
|
|
60
|
+
reporting policy, supported-versions table, scope/out-of-scope, 90-day
|
|
61
|
+
coordinated-disclosure default), structured `.github/ISSUE_TEMPLATE/`
|
|
62
|
+
forms (`bug_report.yml`, `feature_request.yml`, `config.yml` that
|
|
63
|
+
disables blank issues and routes reporters to security/runbook links),
|
|
64
|
+
and a `.github/PULL_REQUEST_TEMPLATE.md` with summary / type-of-change
|
|
65
|
+
/ testing / checklist sections aligned to `CONTRIBUTING.md`. All
|
|
66
|
+
cross-link to the existing on-call runbooks and CONTRIBUTING guide
|
|
67
|
+
rather than restating their contents.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
|
|
71
|
+
- `sdk/README.md` (the PyPI project page bundled into every published
|
|
72
|
+
wheel) made version-agnostic: dropped the hardcoded `1.1.0 on PyPI`
|
|
73
|
+
line that went stale at every release in favour of a CHANGELOG link
|
|
74
|
+
pinned to `main`. PyPI keeps showing the README from the bundled wheel
|
|
75
|
+
until the next publish, so this fix is forward-looking — future
|
|
76
|
+
releases will not need an SDK README touch-up just to keep the version
|
|
77
|
+
reference current.
|
|
78
|
+
- `helm/agentflow` chart aligned to current release line:
|
|
79
|
+
`Chart.yaml` `appVersion` bumped `1.0.0` → `1.3.0`, default
|
|
80
|
+
`values.yaml` `image.tag` bumped `1.1.0` → `1.3.0`, and
|
|
81
|
+
`docs/helm-deployment.md` examples follow. Helm contract tests +
|
|
82
|
+
helm lint pass; operators who pin their own registry/tag via
|
|
83
|
+
`image.repository` / `image.tag` overrides are unaffected.
|
|
84
|
+
|
|
85
|
+
### Changed
|
|
86
|
+
|
|
87
|
+
- Dependabot Tier A wave 2 — seven majors merged in session 18 (commits
|
|
88
|
+
`e2a8288 → 2333104`): `mypy <2 → <3` (dev), `hashicorp/aws ~> 5.60 →
|
|
89
|
+
~> 6.46` (Terraform), `typescript 5.9.3 → 6.0.3` (sdk-ts),
|
|
90
|
+
`actions/github-script v7 → v9` (CI), `actions/download-artifact v4 →
|
|
91
|
+
v8` (CI), `docs/build-push-action v6 → v7` (CI; included a
|
|
92
|
+
`tests/unit/test_container_attestation_workflow.py` pin bump to match
|
|
93
|
+
the new action version), `vitest 3.2.4 → 4.1.7` (sdk-ts dev). Local
|
|
94
|
+
resolver smoke (`pip install --dry-run -e ".[dev,cloud,contract]"`)
|
|
95
|
+
green on each step. Two Dependabot PRs remain intentionally deferred:
|
|
96
|
+
`apache-flink 1.x → 2.x` (pyflink datastream API break in
|
|
97
|
+
`src/processing/flink_jobs/`) and `python:3.11-slim → 3.14-slim`
|
|
98
|
+
(Docker build is not part of CI, ecosystem compat uneven).
|
|
99
|
+
|
|
100
|
+
### CI
|
|
101
|
+
|
|
102
|
+
- `contract.yml` `paths:` filter broadened to also trigger on
|
|
103
|
+
`pyproject.toml`, `sdk/pyproject.toml`, and `.github/workflows/**`.
|
|
104
|
+
This closes the session 16-17 "silent deps cascade" gap (a
|
|
105
|
+
`pyproject.toml`-only commit used to leave Contract Tests on the
|
|
106
|
+
previous, stale SHA) and the session 18 "workflow-only PR cannot
|
|
107
|
+
satisfy required contract check" gap (any workflow bump now
|
|
108
|
+
re-validates the contract suite). Terraform, sdk-ts, and Dockerfile
|
|
109
|
+
paths were left out deliberately — the contract suite is python
|
|
110
|
+
schemathesis and does not exercise those paths, so triggering it
|
|
111
|
+
there would burn CI minutes for no signal. For PRs that touch only
|
|
112
|
+
those files, the documented workaround is `gh pr merge --admin
|
|
113
|
+
--squash` after a manual `gh workflow run contract.yml --ref
|
|
114
|
+
<branch>` SUCCESS.
|
|
115
|
+
- `dora.yml` now passes `--branch origin/main` to
|
|
116
|
+
`scripts/dora_metrics.py`. Previously the script defaulted to
|
|
117
|
+
`--branch main`, which works on the `push` / `schedule` /
|
|
118
|
+
`workflow_dispatch` events but fails on `pull_request` because
|
|
119
|
+
`actions/checkout` lands in detached HEAD with no local `main`.
|
|
120
|
+
Every Dependabot PR therefore showed `dora-report: FAILURE` as
|
|
121
|
+
triage noise even though the report is not a required check. With
|
|
122
|
+
`origin/main` the ref resolves correctly in all four event
|
|
123
|
+
contexts.
|
|
124
|
+
|
|
125
|
+
### Repo settings
|
|
126
|
+
|
|
127
|
+
- Auto-merge and auto-delete-branch-on-merge enabled on
|
|
128
|
+
`brownjuly2003-code/agentflow`. `gh pr merge <N> --auto --squash`
|
|
129
|
+
is now supported, and Dependabot branches are removed
|
|
130
|
+
automatically once their PR squash-merges. The earlier session 18
|
|
131
|
+
flow (admin-merge per PR, manual `--delete-branch` flag) becomes
|
|
132
|
+
unnecessary for the common case where required checks pass on the
|
|
133
|
+
rebased SHA.
|
|
134
|
+
|
|
135
|
+
### Types
|
|
136
|
+
|
|
137
|
+
- `types-PyYAML` added to the dev extra. 16
|
|
138
|
+
`# type: ignore[import-untyped]` annotations on `import yaml` lines
|
|
139
|
+
across `src/` retired; the five remaining `# type: ignore[assignment]`
|
|
140
|
+
annotations are on the `yaml = None` fallback line inside the
|
|
141
|
+
optional-pyyaml `try/except ImportError` blocks (PyYAML is currently
|
|
142
|
+
a hard runtime dependency, but the JSON-fallback machinery in
|
|
143
|
+
`webhook_dispatcher.py`, `slo.py`, `alerts/dispatcher.py` etc. is
|
|
144
|
+
intentionally kept available — see SESSION_HANDOFF.md anti-tasks).
|
|
145
|
+
- `types-redis` added to the dev extra. Two
|
|
146
|
+
`# type: ignore[import-untyped,unused-ignore]` annotations on
|
|
147
|
+
`import redis.asyncio as redis` retired in `src/serving/cache.py`
|
|
148
|
+
and `src/serving/api/rate_limiter.py`; the `redis = None` fallback
|
|
149
|
+
keeps its `assignment` ignore for the same reason as yaml.
|
|
150
|
+
- Net change: total type-ignore count in `src/sdk` dropped 20 → 13,
|
|
151
|
+
with the `import-untyped` category eliminated entirely. `mypy src
|
|
152
|
+
sdk` still clean (0 errors, 105 files).
|
|
153
|
+
|
|
154
|
+
### Documentation
|
|
155
|
+
|
|
156
|
+
- README refreshed to `v1.3.0` reality: release-gate badge bumped, the
|
|
157
|
+
Highlights section reflects the `v1.1` → `v1.3` arc and the DV2 demo
|
|
158
|
+
triptych, the Status block summarizes what landed in each of the three
|
|
159
|
+
releases and what external gates remain, and the Documentation index
|
|
160
|
+
now links to `docs/runbooks/` alongside the existing single-page
|
|
161
|
+
`docs/runbook.md` (the singular file remains the local-dev
|
|
162
|
+
quick-reference; the plural directory is the on-call incident
|
|
163
|
+
playbooks).
|
|
164
|
+
- On-call production incident runbooks in `docs/runbooks/`: index plus five
|
|
165
|
+
symptom-keyed playbooks (`api-5xx-spike.md`, `auth-401-spike.md`,
|
|
166
|
+
`cdc-lag.md`, `load-test-regression.md`, `release-rollback.md`). Each
|
|
167
|
+
follows the eight-section format (Symptom / Severity / Owner / Detection /
|
|
168
|
+
Triage / Mitigation / Resolution / Postmortem trigger) and references real
|
|
169
|
+
signals already in the codebase: Load Test gates from
|
|
170
|
+
`tests/load/thresholds.py`, the fail-closed auth path from
|
|
171
|
+
`src/serving/api/auth/middleware.py`, the v1.3.0 release surfaces
|
|
172
|
+
(`docs/dv2-multi-branch/RELEASE_STATUS.md`,
|
|
173
|
+
`.github/workflows/publish-pypi.yml`, `.github/workflows/publish-npm.yml`),
|
|
174
|
+
and the production CDC onboarding decision record in
|
|
175
|
+
`docs/operations/cdc-production-onboarding.md`. Severity ladder aligns with
|
|
176
|
+
`docs/operations/chaos-runbook.md` so paging behavior stays consistent
|
|
177
|
+
across all incident types.
|
|
178
|
+
|
|
179
|
+
## [1.3.0] - 2026-05-24
|
|
180
|
+
|
|
181
|
+
### Added
|
|
182
|
+
|
|
183
|
+
- A04 chart hardening: `helm/kafka-connect/` now ships NetworkPolicy +
|
|
184
|
+
PodDisruptionBudget + pod/container securityContext + `/tmp` memory
|
|
185
|
+
emptyDir (parity with `helm/agentflow`). All five primitives are
|
|
186
|
+
required by `values.schema.json` and off-by-default for backwards
|
|
187
|
+
compatibility on existing clusters; production switches them on via
|
|
188
|
+
`values-staging.yaml`-style overlays. See
|
|
189
|
+
`docs/operations/cdc-production-onboarding.md` § Chart hardening
|
|
190
|
+
baseline for the production switch-on recommendations.
|
|
191
|
+
- A05 live-validation coverage extended: the
|
|
192
|
+
`tests/integration/test_helm_values_live_validation.py` suite is
|
|
193
|
+
now parametrized across both `helm/agentflow` and `helm/kafka-connect`
|
|
194
|
+
charts, running lint + install --dry-run against the live kind
|
|
195
|
+
cluster with valid + invalid value fixtures each.
|
|
196
|
+
- A05 reuse-cluster mode: `conftest.kind_cluster` honours
|
|
197
|
+
`AGENTFLOW_LIVE_REUSE_CLUSTER=1` to skip the kind create/delete cycle
|
|
198
|
+
and validate against an active `KUBECONFIG` context. Lets the
|
|
199
|
+
schema gates run against managed staging clusters (EKS/GKE/AKS)
|
|
200
|
+
without provisioning a throwaway kind cluster.
|
|
201
|
+
|
|
202
|
+
### Changed
|
|
203
|
+
|
|
204
|
+
- A03 CI hardware-gap acceptance: Load Test gates raised to 1.3x the
|
|
205
|
+
2026-04-25 CI baseline (entity p99 750 → 900 ms, query/batch
|
|
206
|
+
1000 → 1200 ms). Local SLO p99 < 200 ms unchanged. Decision record
|
|
207
|
+
+ alternatives considered: `docs/perf/ci-hardware-gap-2026-05-24.md`.
|
|
208
|
+
|
|
209
|
+
### Documentation
|
|
210
|
+
|
|
211
|
+
- DV2 web-UI screencast (`docs/dv2-multi-branch/demo_webui.mp4`,
|
|
212
|
+
~60 s, 1.6 MB) — Playwright run through Argo workflow archive
|
|
213
|
+
(4× successful `dv2-refresh` runs + DAG drill-in on the latest) and
|
|
214
|
+
the MinIO `cold-tier` bucket browser (5 per-branch prefixes), with
|
|
215
|
+
a Russian TTS voice-over. Reproducer:
|
|
216
|
+
`docs/dv2-multi-branch/demo_webui.capture.py` plus the same
|
|
217
|
+
edge-tts + ffmpeg pipeline as the terminal cast.
|
|
218
|
+
- DV2 dbt docs screencast (`docs/dv2-multi-branch/demo_dbt_docs.mp4`,
|
|
219
|
+
~55 s, 1.7 MB) — Playwright walk-through of the auto-generated dbt
|
|
220
|
+
docs site: project tree → `customer_360` columns/description →
|
|
221
|
+
`branch_pnl` with the `rv.bv_order_canonical → branch_pnl` lineage
|
|
222
|
+
graph → `returns_velocity` with lineage. Companion Pod manifest
|
|
223
|
+
`infrastructure/dv2/dbt/dbt-docs-pod.yaml` runs `dbt docs generate`
|
|
224
|
+
+ `dbt docs serve --port 8080 --host 0.0.0.0` against the in-cluster
|
|
225
|
+
ClickHouse. Reproducer: `demo_dbt_docs.capture.py` plus the same
|
|
226
|
+
TTS pipeline.
|
|
227
|
+
- Cross-link `docs/plans/2026-04-debezium-kafka-connect-deployment-plan.md`
|
|
228
|
+
to `docs/operations/cdc-production-onboarding.md` (production source
|
|
229
|
+
onboarding still blocked on decision-record fill-in) and note that
|
|
230
|
+
the DV2 demo uses ClickHouse `MaterializedPostgreSQL` as a
|
|
231
|
+
single-node alternative, not a production replacement for
|
|
232
|
+
Debezium/Kafka Connect.
|
|
233
|
+
- Exploration archive: `docs/exploration/2026-05/` collects three
|
|
234
|
+
stale May-6/7 docs-site drafts (`astro_prompt.md`, `kimi.md`,
|
|
235
|
+
`research.md`) that had been sitting untracked in the repo root.
|
|
236
|
+
|
|
237
|
+
### Fixed
|
|
238
|
+
|
|
239
|
+
- Typed `RetryPolicy.compute_delay()` intermediate `base` in
|
|
240
|
+
`sdk/agentflow/retry.py` so the function no longer returns
|
|
241
|
+
`Any`; SDK mypy is now strict-clean.
|
|
242
|
+
- CI / release / packaging lessons-learned document
|
|
243
|
+
(`docs/lessons/ci-repair-sprint-2026-04.md`) — seven concrete
|
|
244
|
+
Lesson / Apply / Concrete-trace entries covering A06 dependency
|
|
245
|
+
profiles, single-run baseline anti-pattern, FastAPI version drift,
|
|
246
|
+
PyPI namespace pre-claim, required-check self-reference deadlock,
|
|
247
|
+
fail-closed auth + `/v1/health` exemption, and the DV2 voice-over
|
|
248
|
+
pipeline.
|
|
249
|
+
|
|
7
250
|
## [1.2.0] - 2026-05-23
|
|
8
251
|
|
|
9
252
|
### Documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentflow-runtime
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Real-time data platform serving context to AI agents
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,7 +17,7 @@ Requires-Dist: opentelemetry-instrumentation-httpx<1,>=0.62b0
|
|
|
17
17
|
Requires-Dist: opentelemetry-sdk<2,>=1.41
|
|
18
18
|
Requires-Dist: pandera<1,>=0.20
|
|
19
19
|
Requires-Dist: prometheus-client<1,>=0.21
|
|
20
|
-
Requires-Dist: pyarrow<
|
|
20
|
+
Requires-Dist: pyarrow<25,>=17
|
|
21
21
|
Requires-Dist: pydantic-settings<3,>=2.5
|
|
22
22
|
Requires-Dist: pydantic<3,>=2.9
|
|
23
23
|
Requires-Dist: pyyaml<7,>=6
|
|
@@ -28,19 +28,21 @@ Provides-Extra: cloud
|
|
|
28
28
|
Requires-Dist: boto3<2,>=1.35; extra == 'cloud'
|
|
29
29
|
Requires-Dist: pyiceberg[pyiceberg-core]<1,>=0.7; extra == 'cloud'
|
|
30
30
|
Provides-Extra: contract
|
|
31
|
-
Requires-Dist: schemathesis==4.
|
|
31
|
+
Requires-Dist: schemathesis==4.19.0; extra == 'contract'
|
|
32
32
|
Provides-Extra: dev
|
|
33
33
|
Requires-Dist: bandit<2,>=1.9; extra == 'dev'
|
|
34
34
|
Requires-Dist: build<2,>=1.2; extra == 'dev'
|
|
35
35
|
Requires-Dist: hatchling<2,>=1.25; extra == 'dev'
|
|
36
36
|
Requires-Dist: hypothesis<7,>=6; extra == 'dev'
|
|
37
37
|
Requires-Dist: jsonschema<5,>=4; extra == 'dev'
|
|
38
|
-
Requires-Dist: mypy<
|
|
39
|
-
Requires-Dist: pytest-asyncio<
|
|
40
|
-
Requires-Dist: pytest-cov<
|
|
41
|
-
Requires-Dist: pytest<
|
|
38
|
+
Requires-Dist: mypy<3,>=1.11; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-asyncio<2,>=0.24; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-cov<8,>=5; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest<10,>=8.3; extra == 'dev'
|
|
42
42
|
Requires-Dist: ruff<1,>=0.6; extra == 'dev'
|
|
43
43
|
Requires-Dist: testcontainers[kafka]<5,>=4.9; extra == 'dev'
|
|
44
|
+
Requires-Dist: types-pyyaml<7,>=6; extra == 'dev'
|
|
45
|
+
Requires-Dist: types-redis<6,>=4.6; extra == 'dev'
|
|
44
46
|
Provides-Extra: flink
|
|
45
47
|
Requires-Dist: apache-flink==1.19.1; extra == 'flink'
|
|
46
48
|
Provides-Extra: integrations
|
|
@@ -59,7 +61,7 @@ Description-Content-Type: text/markdown
|
|
|
59
61
|
|
|
60
62
|
> Real-time data platform for AI agents. Live entity lookups, typed contracts, dual-language SDKs, and release-gated delivery.
|
|
61
63
|
|
|
62
|
-
[](docs/dv2-multi-branch/RELEASE_STATUS.md)
|
|
63
65
|
[](https://codecov.io/gh/brownjuly2003-code/agentflow)
|
|
64
66
|
[](pyproject.toml)
|
|
65
67
|
[](LICENSE)
|
|
@@ -77,13 +79,14 @@ AgentFlow turns that problem into one serving boundary:
|
|
|
77
79
|
|
|
78
80
|
## Highlights
|
|
79
81
|
|
|
80
|
-
- **Release
|
|
81
|
-
- **
|
|
82
|
-
- **
|
|
83
|
-
- **Dual SDK parity** for Python and TypeScript, including retry policies, circuit breakers, batching, pagination, and
|
|
84
|
-
- **
|
|
85
|
-
- **Security hardening in the hot path**: parameterized queries, `sqlglot` AST validation for NL-to-SQL, and a Bandit baseline gate for new findings only
|
|
86
|
-
- **
|
|
82
|
+
- **Release line through `v1.3.0`** on PyPI (`agentflow-runtime`, `agentflow-client`) and npm (`@yuliaedomskikh/agentflow-client`), published via OIDC Trusted Publishers with SLSA provenance attestations on every artifact. Live registry table + re-verify recipe: [docs/dv2-multi-branch/RELEASE_STATUS.md](docs/dv2-multi-branch/RELEASE_STATUS.md)
|
|
83
|
+
- **486 unit tests collected, full suite green on `main`**; CI runs 12 required status checks (lint, schema-check, test-unit, test-integration, helm-schema-live, perf-check, terraform-validate, bandit, safety, npm-audit, trivy, contract). Branch protection requires every one of them
|
|
84
|
+
- **Sub-second entity lookups**: entity p50 `38-55 ms`, entity p99 `167 ms` on local hardware (–82% from the 2026-04-23 baseline after the PII masker + tenant qualification cache wins). CI runner thresholds are documented separately in [docs/perf/ci-hardware-gap-2026-05-24.md](docs/perf/ci-hardware-gap-2026-05-24.md)
|
|
85
|
+
- **Dual SDK parity** for Python (`agentflow-client`) and TypeScript (`@yuliaedomskikh/agentflow-client`), including retry policies, circuit breakers, batching, pagination, contract pinning, idempotency keys, and `as_of` historical reads
|
|
86
|
+
- **Two CDC paths**: production-grade Debezium + Kafka Connect (Helm chart hardened with NetworkPolicy + PDB + securityContext, schema-validated on every deploy), and a ClickHouse `MaterializedPostgreSQL` per-branch fan-out for the DV2 demo cluster
|
|
87
|
+
- **Security hardening in the hot path**: tenant isolation across every read surface, parameterized queries, `sqlglot` AST validation for NL-to-SQL, fail-closed auth middleware, plaintext secret scrubbing, and a Bandit baseline gate for new findings only
|
|
88
|
+
- **On-call playbooks for production incidents** in [docs/runbooks/](docs/runbooks/README.md): symptom-keyed runbooks for API 5xx spikes, auth fail-closed regressions, CDC lag, Load Test gate failures, and PyPI/npm release rollback
|
|
89
|
+
- **DV2 demo triptych**: voice-narrated terminal cast ([demo_voiced.mp4](docs/dv2-multi-branch/demo_voiced.mp4), 92s) + web-UI screencast covering Argo Workflows and MinIO ([demo_webui.mp4](docs/dv2-multi-branch/demo_webui.mp4), 60s) + dbt docs lineage walk-through ([demo_dbt_docs.mp4](docs/dv2-multi-branch/demo_dbt_docs.mp4), 55s)
|
|
87
90
|
|
|
88
91
|
## Quick start
|
|
89
92
|
|
|
@@ -166,9 +169,11 @@ CDC source capture is standardized on Debezium/Kafka Connect; downstream consume
|
|
|
166
169
|
|
|
167
170
|
## Documentation
|
|
168
171
|
|
|
172
|
+
- [Session Handoff](docs/SESSION_HANDOFF.md) - **start here when picking up the project cold** — current HEAD, open Dependabot PRs, externally user-gated items, recent lessons (Contract Tests path filter, Dependabot cascade conflicts)
|
|
169
173
|
- [Interactive Technical Walkthrough](docs/index.md) - MkDocs Material guide with Mermaid architecture, API, SDK, deployment, observability, and troubleshooting pages
|
|
170
174
|
- [Architecture](docs/architecture.md) - system context, data flow, failure modes
|
|
171
|
-
- [Operational Runbook](docs/runbook.md) - local stack, CDC capture,
|
|
175
|
+
- [Operational Runbook](docs/runbook.md) - local stack, CDC capture, and maintenance commands
|
|
176
|
+
- [On-Call Runbooks](docs/runbooks/README.md) - production-incident playbooks (API 5xx, auth break, CDC lag, Load Test regression, release rollback)
|
|
172
177
|
- [API Reference](docs/api-reference.md) - endpoint-by-endpoint examples for curl, Python, and TypeScript
|
|
173
178
|
- [Security Audit](docs/security-audit.md) - threat model, controls, and evidence
|
|
174
179
|
- [Competitive Analysis](docs/competitive-analysis.md) - positioning and trade-offs
|
|
@@ -211,28 +216,55 @@ python scripts/bandit_diff.py .bandit-baseline.json .tmp/bandit-current.json
|
|
|
211
216
|
|
|
212
217
|
## Status
|
|
213
218
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
219
|
+
**`v1.3.0` is the current release line** (PyPI `agentflow-runtime` /
|
|
220
|
+
`agentflow-client`, npm `@yuliaedomskikh/agentflow-client`, all three
|
|
221
|
+
published 2026-05-23 via OIDC Trusted Publishers with SLSA provenance
|
|
222
|
+
attestations). Live registry table and re-verify recipe live in
|
|
223
|
+
[docs/dv2-multi-branch/RELEASE_STATUS.md](docs/dv2-multi-branch/RELEASE_STATUS.md).
|
|
224
|
+
|
|
225
|
+
The `v1.1.0` → `v1.3.0` arc landed in three increments on top of the
|
|
226
|
+
2026-04-27 audit closure sprint:
|
|
227
|
+
|
|
228
|
+
- **`v1.1.0`** — audit closure: tenant isolation across every read
|
|
229
|
+
surface, SQL guard centralization on `sqlglot`, entity allowlist
|
|
230
|
+
enforcement, fail-closed auth, secrets rotated, Helm hardening,
|
|
231
|
+
`npm audit` clean, vulnerable dep bumps, OpenAPI drift gate, 12
|
|
232
|
+
required status checks, Python SDK alignment with server v1
|
|
233
|
+
contract (F1–F10).
|
|
234
|
+
- **`v1.2.0`** — DV2 multi-branch warehouse merged to `main`: 38 DV2.0
|
|
235
|
+
tables (8 hubs / 8 links / 22+ satellites), Argo Workflows
|
|
236
|
+
`dv2-refresh` template, dbt project with 3 mart models + 12 tests,
|
|
237
|
+
per-branch CDC fan-out via ClickHouse `MaterializedPostgreSQL`, and
|
|
238
|
+
the first voice-narrated terminal cast demo.
|
|
239
|
+
- **`v1.3.0`** — `helm/kafka-connect` chart hardening matched to
|
|
240
|
+
`helm/agentflow` (NetworkPolicy + PDB + pod/container securityContext
|
|
241
|
+
+ `/tmp` emptyDir, all schema-required and off-by-default), Helm live
|
|
242
|
+
validation parametrized across both charts, A03 CI hardware-gap
|
|
243
|
+
acceptance with Load Test gates raised to 1.3x baseline, and the DV2
|
|
244
|
+
demo triptych completed (terminal + web-UI + dbt docs screencasts).
|
|
245
|
+
|
|
246
|
+
CI on `main` is fully green across all 12 required checks. Local
|
|
247
|
+
hardware sustains entity p99 `167 ms` (the local SLO target); CI runner
|
|
248
|
+
thresholds are intentionally divergent and documented in
|
|
249
|
+
[docs/perf/ci-hardware-gap-2026-05-24.md](docs/perf/ci-hardware-gap-2026-05-24.md).
|
|
250
|
+
|
|
251
|
+
**Remaining external gates** are unchanged from `v1.1` and require
|
|
252
|
+
inputs outside this repository:
|
|
253
|
+
|
|
254
|
+
- AWS OIDC role setup for real Terraform `apply`.
|
|
255
|
+
- Production CDC source onboarding (hostnames, credentials, owners,
|
|
256
|
+
private network path) — runbook ready in
|
|
257
|
+
[docs/operations/cdc-production-onboarding.md](docs/operations/cdc-production-onboarding.md).
|
|
258
|
+
- Real PMF / pricing evidence and a public benchmark on
|
|
259
|
+
production-grade hardware (`c8g.4xlarge+`).
|
|
260
|
+
- External pen-test attestation.
|
|
261
|
+
- Optional: paid larger GHA runner or self-hosted runner if the CI
|
|
262
|
+
hardware-gap thresholds need to be tightened.
|
|
263
|
+
|
|
264
|
+
The project-local Pi skill at
|
|
265
|
+
`.pi/skills/external-gate-evidence-intake` and the
|
|
266
|
+
[External Gate Evidence Intake Checklist](docs/operations/external-gate-evidence-intake.md)
|
|
267
|
+
codify what evidence must arrive before any of those gates close.
|
|
236
268
|
|
|
237
269
|
## Screenshots
|
|
238
270
|
|
|
@@ -252,4 +284,7 @@ MIT. See [LICENSE](LICENSE).
|
|
|
252
284
|
|
|
253
285
|
## Credits
|
|
254
286
|
|
|
255
|
-
Built as a data-engineering reference project
|
|
287
|
+
Built as a data-engineering reference project. Initial release cycle
|
|
288
|
+
`2026-04-10` → `2026-04-20`, post-audit hardening and DV2 extension
|
|
289
|
+
through `2026-05-23` (`v1.3.0`). Full implementation trail preserved in
|
|
290
|
+
`docs/plans/`, `docs/codex-tasks/`, and `docs/lessons/`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Real-time data platform for AI agents. Live entity lookups, typed contracts, dual-language SDKs, and release-gated delivery.
|
|
4
4
|
|
|
5
|
-
[](docs/dv2-multi-branch/RELEASE_STATUS.md)
|
|
6
6
|
[](https://codecov.io/gh/brownjuly2003-code/agentflow)
|
|
7
7
|
[](pyproject.toml)
|
|
8
8
|
[](LICENSE)
|
|
@@ -20,13 +20,14 @@ AgentFlow turns that problem into one serving boundary:
|
|
|
20
20
|
|
|
21
21
|
## Highlights
|
|
22
22
|
|
|
23
|
-
- **Release
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **Dual SDK parity** for Python and TypeScript, including retry policies, circuit breakers, batching, pagination, and
|
|
27
|
-
- **
|
|
28
|
-
- **Security hardening in the hot path**: parameterized queries, `sqlglot` AST validation for NL-to-SQL, and a Bandit baseline gate for new findings only
|
|
29
|
-
- **
|
|
23
|
+
- **Release line through `v1.3.0`** on PyPI (`agentflow-runtime`, `agentflow-client`) and npm (`@yuliaedomskikh/agentflow-client`), published via OIDC Trusted Publishers with SLSA provenance attestations on every artifact. Live registry table + re-verify recipe: [docs/dv2-multi-branch/RELEASE_STATUS.md](docs/dv2-multi-branch/RELEASE_STATUS.md)
|
|
24
|
+
- **486 unit tests collected, full suite green on `main`**; CI runs 12 required status checks (lint, schema-check, test-unit, test-integration, helm-schema-live, perf-check, terraform-validate, bandit, safety, npm-audit, trivy, contract). Branch protection requires every one of them
|
|
25
|
+
- **Sub-second entity lookups**: entity p50 `38-55 ms`, entity p99 `167 ms` on local hardware (–82% from the 2026-04-23 baseline after the PII masker + tenant qualification cache wins). CI runner thresholds are documented separately in [docs/perf/ci-hardware-gap-2026-05-24.md](docs/perf/ci-hardware-gap-2026-05-24.md)
|
|
26
|
+
- **Dual SDK parity** for Python (`agentflow-client`) and TypeScript (`@yuliaedomskikh/agentflow-client`), including retry policies, circuit breakers, batching, pagination, contract pinning, idempotency keys, and `as_of` historical reads
|
|
27
|
+
- **Two CDC paths**: production-grade Debezium + Kafka Connect (Helm chart hardened with NetworkPolicy + PDB + securityContext, schema-validated on every deploy), and a ClickHouse `MaterializedPostgreSQL` per-branch fan-out for the DV2 demo cluster
|
|
28
|
+
- **Security hardening in the hot path**: tenant isolation across every read surface, parameterized queries, `sqlglot` AST validation for NL-to-SQL, fail-closed auth middleware, plaintext secret scrubbing, and a Bandit baseline gate for new findings only
|
|
29
|
+
- **On-call playbooks for production incidents** in [docs/runbooks/](docs/runbooks/README.md): symptom-keyed runbooks for API 5xx spikes, auth fail-closed regressions, CDC lag, Load Test gate failures, and PyPI/npm release rollback
|
|
30
|
+
- **DV2 demo triptych**: voice-narrated terminal cast ([demo_voiced.mp4](docs/dv2-multi-branch/demo_voiced.mp4), 92s) + web-UI screencast covering Argo Workflows and MinIO ([demo_webui.mp4](docs/dv2-multi-branch/demo_webui.mp4), 60s) + dbt docs lineage walk-through ([demo_dbt_docs.mp4](docs/dv2-multi-branch/demo_dbt_docs.mp4), 55s)
|
|
30
31
|
|
|
31
32
|
## Quick start
|
|
32
33
|
|
|
@@ -109,9 +110,11 @@ CDC source capture is standardized on Debezium/Kafka Connect; downstream consume
|
|
|
109
110
|
|
|
110
111
|
## Documentation
|
|
111
112
|
|
|
113
|
+
- [Session Handoff](docs/SESSION_HANDOFF.md) - **start here when picking up the project cold** — current HEAD, open Dependabot PRs, externally user-gated items, recent lessons (Contract Tests path filter, Dependabot cascade conflicts)
|
|
112
114
|
- [Interactive Technical Walkthrough](docs/index.md) - MkDocs Material guide with Mermaid architecture, API, SDK, deployment, observability, and troubleshooting pages
|
|
113
115
|
- [Architecture](docs/architecture.md) - system context, data flow, failure modes
|
|
114
|
-
- [Operational Runbook](docs/runbook.md) - local stack, CDC capture,
|
|
116
|
+
- [Operational Runbook](docs/runbook.md) - local stack, CDC capture, and maintenance commands
|
|
117
|
+
- [On-Call Runbooks](docs/runbooks/README.md) - production-incident playbooks (API 5xx, auth break, CDC lag, Load Test regression, release rollback)
|
|
115
118
|
- [API Reference](docs/api-reference.md) - endpoint-by-endpoint examples for curl, Python, and TypeScript
|
|
116
119
|
- [Security Audit](docs/security-audit.md) - threat model, controls, and evidence
|
|
117
120
|
- [Competitive Analysis](docs/competitive-analysis.md) - positioning and trade-offs
|
|
@@ -154,28 +157,55 @@ python scripts/bandit_diff.py .bandit-baseline.json .tmp/bandit-current.json
|
|
|
154
157
|
|
|
155
158
|
## Status
|
|
156
159
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
160
|
+
**`v1.3.0` is the current release line** (PyPI `agentflow-runtime` /
|
|
161
|
+
`agentflow-client`, npm `@yuliaedomskikh/agentflow-client`, all three
|
|
162
|
+
published 2026-05-23 via OIDC Trusted Publishers with SLSA provenance
|
|
163
|
+
attestations). Live registry table and re-verify recipe live in
|
|
164
|
+
[docs/dv2-multi-branch/RELEASE_STATUS.md](docs/dv2-multi-branch/RELEASE_STATUS.md).
|
|
165
|
+
|
|
166
|
+
The `v1.1.0` → `v1.3.0` arc landed in three increments on top of the
|
|
167
|
+
2026-04-27 audit closure sprint:
|
|
168
|
+
|
|
169
|
+
- **`v1.1.0`** — audit closure: tenant isolation across every read
|
|
170
|
+
surface, SQL guard centralization on `sqlglot`, entity allowlist
|
|
171
|
+
enforcement, fail-closed auth, secrets rotated, Helm hardening,
|
|
172
|
+
`npm audit` clean, vulnerable dep bumps, OpenAPI drift gate, 12
|
|
173
|
+
required status checks, Python SDK alignment with server v1
|
|
174
|
+
contract (F1–F10).
|
|
175
|
+
- **`v1.2.0`** — DV2 multi-branch warehouse merged to `main`: 38 DV2.0
|
|
176
|
+
tables (8 hubs / 8 links / 22+ satellites), Argo Workflows
|
|
177
|
+
`dv2-refresh` template, dbt project with 3 mart models + 12 tests,
|
|
178
|
+
per-branch CDC fan-out via ClickHouse `MaterializedPostgreSQL`, and
|
|
179
|
+
the first voice-narrated terminal cast demo.
|
|
180
|
+
- **`v1.3.0`** — `helm/kafka-connect` chart hardening matched to
|
|
181
|
+
`helm/agentflow` (NetworkPolicy + PDB + pod/container securityContext
|
|
182
|
+
+ `/tmp` emptyDir, all schema-required and off-by-default), Helm live
|
|
183
|
+
validation parametrized across both charts, A03 CI hardware-gap
|
|
184
|
+
acceptance with Load Test gates raised to 1.3x baseline, and the DV2
|
|
185
|
+
demo triptych completed (terminal + web-UI + dbt docs screencasts).
|
|
186
|
+
|
|
187
|
+
CI on `main` is fully green across all 12 required checks. Local
|
|
188
|
+
hardware sustains entity p99 `167 ms` (the local SLO target); CI runner
|
|
189
|
+
thresholds are intentionally divergent and documented in
|
|
190
|
+
[docs/perf/ci-hardware-gap-2026-05-24.md](docs/perf/ci-hardware-gap-2026-05-24.md).
|
|
191
|
+
|
|
192
|
+
**Remaining external gates** are unchanged from `v1.1` and require
|
|
193
|
+
inputs outside this repository:
|
|
194
|
+
|
|
195
|
+
- AWS OIDC role setup for real Terraform `apply`.
|
|
196
|
+
- Production CDC source onboarding (hostnames, credentials, owners,
|
|
197
|
+
private network path) — runbook ready in
|
|
198
|
+
[docs/operations/cdc-production-onboarding.md](docs/operations/cdc-production-onboarding.md).
|
|
199
|
+
- Real PMF / pricing evidence and a public benchmark on
|
|
200
|
+
production-grade hardware (`c8g.4xlarge+`).
|
|
201
|
+
- External pen-test attestation.
|
|
202
|
+
- Optional: paid larger GHA runner or self-hosted runner if the CI
|
|
203
|
+
hardware-gap thresholds need to be tightened.
|
|
204
|
+
|
|
205
|
+
The project-local Pi skill at
|
|
206
|
+
`.pi/skills/external-gate-evidence-intake` and the
|
|
207
|
+
[External Gate Evidence Intake Checklist](docs/operations/external-gate-evidence-intake.md)
|
|
208
|
+
codify what evidence must arrive before any of those gates close.
|
|
179
209
|
|
|
180
210
|
## Screenshots
|
|
181
211
|
|
|
@@ -195,4 +225,7 @@ MIT. See [LICENSE](LICENSE).
|
|
|
195
225
|
|
|
196
226
|
## Credits
|
|
197
227
|
|
|
198
|
-
Built as a data-engineering reference project
|
|
228
|
+
Built as a data-engineering reference project. Initial release cycle
|
|
229
|
+
`2026-04-10` → `2026-04-20`, post-audit hardening and DV2 extension
|
|
230
|
+
through `2026-05-23` (`v1.3.0`). Full implementation trail preserved in
|
|
231
|
+
`docs/plans/`, `docs/codex-tasks/`, and `docs/lessons/`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentflow-runtime"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.4.0"
|
|
4
4
|
description = "Real-time data platform serving context to AI agents"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -20,7 +20,7 @@ dependencies = [
|
|
|
20
20
|
"opentelemetry-sdk>=1.41,<2",
|
|
21
21
|
"pandera>=0.20,<1",
|
|
22
22
|
"prometheus-client>=0.21,<1",
|
|
23
|
-
"pyarrow>=17,<
|
|
23
|
+
"pyarrow>=17,<25",
|
|
24
24
|
"pydantic>=2.9,<3",
|
|
25
25
|
"pydantic-settings>=2.5,<3",
|
|
26
26
|
"pyyaml>=6,<7",
|
|
@@ -55,7 +55,7 @@ integrations = [
|
|
|
55
55
|
"llama-index-core>=0.12,<1",
|
|
56
56
|
]
|
|
57
57
|
contract = [
|
|
58
|
-
"schemathesis==4.
|
|
58
|
+
"schemathesis==4.19.0",
|
|
59
59
|
]
|
|
60
60
|
dev = [
|
|
61
61
|
"bandit>=1.9,<2",
|
|
@@ -63,12 +63,14 @@ dev = [
|
|
|
63
63
|
"hatchling>=1.25,<2",
|
|
64
64
|
"hypothesis>=6,<7",
|
|
65
65
|
"jsonschema>=4,<5",
|
|
66
|
-
"pytest>=8.3,<
|
|
67
|
-
"pytest-asyncio>=0.24,<
|
|
68
|
-
"pytest-cov>=5,<
|
|
66
|
+
"pytest>=8.3,<10",
|
|
67
|
+
"pytest-asyncio>=0.24,<2",
|
|
68
|
+
"pytest-cov>=5,<8",
|
|
69
69
|
"testcontainers[kafka]>=4.9,<5",
|
|
70
70
|
"ruff>=0.6,<1",
|
|
71
|
-
"mypy>=1.11,<
|
|
71
|
+
"mypy>=1.11,<3",
|
|
72
|
+
"types-PyYAML>=6,<7",
|
|
73
|
+
"types-redis>=4.6,<6",
|
|
72
74
|
]
|
|
73
75
|
|
|
74
76
|
[build-system]
|
|
@@ -7,9 +7,9 @@ from pathlib import Path
|
|
|
7
7
|
from pydantic import BaseModel, Field
|
|
8
8
|
|
|
9
9
|
try:
|
|
10
|
-
import yaml
|
|
10
|
+
import yaml
|
|
11
11
|
except ImportError: # pragma: no cover
|
|
12
|
-
yaml = None
|
|
12
|
+
yaml = None # type: ignore[assignment]
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def default_tenants_config_path() -> Path:
|
|
@@ -7,7 +7,7 @@ from pathlib import Path
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
import pyarrow as pa
|
|
10
|
-
import yaml
|
|
10
|
+
import yaml
|
|
11
11
|
from pyiceberg.catalog import load_catalog
|
|
12
12
|
from pyiceberg.partitioning import PartitionField, PartitionSpec
|
|
13
13
|
from pyiceberg.schema import Schema
|
|
@@ -18,7 +18,7 @@ from pathlib import Path
|
|
|
18
18
|
|
|
19
19
|
import duckdb
|
|
20
20
|
import structlog
|
|
21
|
-
import yaml
|
|
21
|
+
import yaml
|
|
22
22
|
from pyiceberg.exceptions import NoSuchPropertyException, RESTError, ValidationError
|
|
23
23
|
|
|
24
24
|
from src.ingestion.producers.event_producer import (
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/monitors/metrics_collector.py
RENAMED
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
|
13
13
|
import duckdb
|
|
14
14
|
import httpx
|
|
15
15
|
import structlog
|
|
16
|
-
import yaml
|
|
16
|
+
import yaml
|
|
17
17
|
from confluent_kafka import KafkaException
|
|
18
18
|
from prometheus_client import Gauge
|
|
19
19
|
from pyiceberg.exceptions import NoSuchPropertyException, RESTError, ValidationError
|
|
@@ -12,9 +12,9 @@ from typing import Literal
|
|
|
12
12
|
from pydantic import BaseModel, Field, model_validator
|
|
13
13
|
|
|
14
14
|
try:
|
|
15
|
-
import yaml
|
|
15
|
+
import yaml
|
|
16
16
|
except ImportError: # pragma: no cover
|
|
17
|
-
yaml = None
|
|
17
|
+
yaml = None # type: ignore[assignment]
|
|
18
18
|
|
|
19
19
|
DEFAULT_ALERTS_CONFIG_PATH = Path(os.getenv("AGENTFLOW_ALERTS_FILE", "config/alerts.yaml"))
|
|
20
20
|
|
|
@@ -10,9 +10,9 @@ from datetime import UTC, datetime, timedelta
|
|
|
10
10
|
import duckdb
|
|
11
11
|
|
|
12
12
|
try:
|
|
13
|
-
import yaml
|
|
13
|
+
import yaml
|
|
14
14
|
except ImportError: # pragma: no cover
|
|
15
|
-
yaml = None
|
|
15
|
+
yaml = None # type: ignore[assignment]
|
|
16
16
|
|
|
17
17
|
from src.serving.api.security import hash_api_key
|
|
18
18
|
from src.serving.duckdb_connection import connect_duckdb
|
|
@@ -23,9 +23,9 @@ from src.constants import (
|
|
|
23
23
|
)
|
|
24
24
|
|
|
25
25
|
try:
|
|
26
|
-
import yaml
|
|
26
|
+
import yaml
|
|
27
27
|
except ImportError: # pragma: no cover
|
|
28
|
-
yaml = None
|
|
28
|
+
yaml = None # type: ignore[assignment]
|
|
29
29
|
|
|
30
30
|
from src.serving.api.rate_limiter import RateLimiter
|
|
31
31
|
from src.serving.api.security import (
|
|
@@ -11,7 +11,7 @@ from src.constants import DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
|
|
11
11
|
logger = structlog.get_logger()
|
|
12
12
|
|
|
13
13
|
try:
|
|
14
|
-
import redis.asyncio as redis
|
|
14
|
+
import redis.asyncio as redis
|
|
15
15
|
except ImportError: # pragma: no cover
|
|
16
16
|
redis = None # type: ignore[assignment]
|
|
17
17
|
|
|
@@ -9,9 +9,9 @@ from fastapi import APIRouter, HTTPException, Request
|
|
|
9
9
|
from pydantic import BaseModel, Field
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
|
-
import yaml
|
|
12
|
+
import yaml
|
|
13
13
|
except ImportError: # pragma: no cover
|
|
14
|
-
yaml = None
|
|
14
|
+
yaml = None # type: ignore[assignment]
|
|
15
15
|
|
|
16
16
|
router = APIRouter(prefix="/v1/slo", tags=["slo"])
|
|
17
17
|
|
|
@@ -10,9 +10,9 @@ from fastapi.responses import JSONResponse
|
|
|
10
10
|
from pydantic import BaseModel, Field
|
|
11
11
|
|
|
12
12
|
try:
|
|
13
|
-
import yaml
|
|
13
|
+
import yaml
|
|
14
14
|
except ImportError: # pragma: no cover
|
|
15
|
-
yaml = None
|
|
15
|
+
yaml = None # type: ignore[assignment]
|
|
16
16
|
|
|
17
17
|
SECURITY_HEADERS = {
|
|
18
18
|
"X-Content-Type-Options": "nosniff",
|
|
@@ -13,9 +13,9 @@ from fastapi import Request, Response
|
|
|
13
13
|
from fastapi.responses import JSONResponse
|
|
14
14
|
|
|
15
15
|
try:
|
|
16
|
-
import yaml
|
|
16
|
+
import yaml
|
|
17
17
|
except ImportError: # pragma: no cover
|
|
18
|
-
yaml = None
|
|
18
|
+
yaml = None # type: ignore[assignment]
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def default_api_versions_path() -> Path:
|
|
@@ -17,9 +17,9 @@ import structlog
|
|
|
17
17
|
from pydantic import BaseModel, Field
|
|
18
18
|
|
|
19
19
|
try:
|
|
20
|
-
import yaml
|
|
20
|
+
import yaml
|
|
21
21
|
except ImportError: # pragma: no cover
|
|
22
|
-
yaml = None
|
|
22
|
+
yaml = None # type: ignore[assignment]
|
|
23
23
|
|
|
24
24
|
logger = structlog.get_logger()
|
|
25
25
|
|
|
@@ -7,9 +7,9 @@ from pathlib import Path
|
|
|
7
7
|
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
9
|
try:
|
|
10
|
-
import yaml
|
|
10
|
+
import yaml
|
|
11
11
|
except ImportError: # pragma: no cover
|
|
12
|
-
yaml = None
|
|
12
|
+
yaml = None # type: ignore[assignment]
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
15
|
from src.serving.backends.duckdb_backend import DuckDBBackend
|
|
@@ -12,7 +12,7 @@ logger = structlog.get_logger()
|
|
|
12
12
|
ENTITY_TTL_SECONDS = 5
|
|
13
13
|
|
|
14
14
|
try:
|
|
15
|
-
import redis.asyncio as redis
|
|
15
|
+
import redis.asyncio as redis
|
|
16
16
|
except ImportError: # pragma: no cover
|
|
17
17
|
redis = None # type: ignore[assignment]
|
|
18
18
|
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/contract_registry.py
RENAMED
|
@@ -7,9 +7,9 @@ from pathlib import Path
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
try:
|
|
10
|
-
import yaml
|
|
10
|
+
import yaml
|
|
11
11
|
except ImportError: # pragma: no cover
|
|
12
|
-
yaml = None
|
|
12
|
+
yaml = None # type: ignore[assignment]
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def _default_contracts_dir() -> Path:
|
|
@@ -19,7 +19,7 @@ import os
|
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from typing import TYPE_CHECKING
|
|
21
21
|
|
|
22
|
-
import yaml
|
|
22
|
+
import yaml
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING: # pragma: no cover - typing only
|
|
25
25
|
from src.serving.semantic_layer.catalog import EntityDefinition as EntityDefinitionT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/connectors/postgres_cdc.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/ingestion/producers/event_producer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/checkpointing.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/session_aggregation.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/session_aggregator.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/flink_jobs/stream_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/transformations/__init__.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/processing/transformations/enrichment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/monitors/freshness_monitor.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/validators/schema_validator.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/quality/validators/semantic_validator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/backends/clickhouse_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/__init__.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/contracts.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/engine.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/nl_queries.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/sql_builder.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query/sql_guard.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/query_engine.py
RENAMED
|
File without changes
|
{agentflow_runtime-1.2.0 → agentflow_runtime-1.4.0}/src/serving/semantic_layer/search_index.py
RENAMED
|
File without changes
|
|
File without changes
|