agentic-chaos 0.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.
- agentic_chaos-0.1.0/.github/workflows/ci.yml +107 -0
- agentic_chaos-0.1.0/.github/workflows/release-pypi.yml +46 -0
- agentic_chaos-0.1.0/.gitignore +15 -0
- agentic_chaos-0.1.0/CHANGELOG.md +67 -0
- agentic_chaos-0.1.0/LICENSE +21 -0
- agentic_chaos-0.1.0/PKG-INFO +296 -0
- agentic_chaos-0.1.0/README.md +241 -0
- agentic_chaos-0.1.0/ROADMAP.md +227 -0
- agentic_chaos-0.1.0/examples/chaos_advanced_faults_demo.py +63 -0
- agentic_chaos-0.1.0/examples/chaos_customer_support_demo.py +125 -0
- agentic_chaos-0.1.0/examples/chaos_with_agenticlens_demo.py +83 -0
- agentic_chaos-0.1.0/pyproject.toml +98 -0
- agentic_chaos-0.1.0/src/agentic_chaos/__init__.py +18 -0
- agentic_chaos-0.1.0/src/agentic_chaos/agents/__init__.py +3 -0
- agentic_chaos-0.1.0/src/agentic_chaos/chaos/__init__.py +32 -0
- agentic_chaos-0.1.0/src/agentic_chaos/chaos/context.py +51 -0
- agentic_chaos-0.1.0/src/agentic_chaos/chaos/faults.py +294 -0
- agentic_chaos-0.1.0/src/agentic_chaos/chaos/inject.py +53 -0
- agentic_chaos-0.1.0/src/agentic_chaos/chaos/session.py +50 -0
- agentic_chaos-0.1.0/src/agentic_chaos/cli/__init__.py +0 -0
- agentic_chaos-0.1.0/src/agentic_chaos/cli/main.py +133 -0
- agentic_chaos-0.1.0/src/agentic_chaos/cli/render.py +36 -0
- agentic_chaos-0.1.0/src/agentic_chaos/drift/__init__.py +4 -0
- agentic_chaos-0.1.0/src/agentic_chaos/integrations/__init__.py +8 -0
- agentic_chaos-0.1.0/src/agentic_chaos/integrations/agenticlens.py +41 -0
- agentic_chaos-0.1.0/src/agentic_chaos/models/__init__.py +4 -0
- agentic_chaos-0.1.0/src/agentic_chaos/models/chaos_event.py +27 -0
- agentic_chaos-0.1.0/src/agentic_chaos/models/report.py +26 -0
- agentic_chaos-0.1.0/tests/test_chaos_event.py +28 -0
- agentic_chaos-0.1.0/tests/test_cli.py +146 -0
- agentic_chaos-0.1.0/tests/test_faults.py +172 -0
- agentic_chaos-0.1.0/tests/test_inject.py +105 -0
- agentic_chaos-0.1.0/tests/test_integrations_agenticlens.py +77 -0
- agentic_chaos-0.1.0/tests/test_report.py +26 -0
- agentic_chaos-0.1.0/uv.lock +1337 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
# Proves agentic-chaos works with zero agenticlens installed: no sibling
|
|
10
|
+
# checkout, no [tool.uv.sources] override in play, just the core package.
|
|
11
|
+
test-core:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v3
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
25
|
+
run: uv python install ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
# --frozen: uv.lock resolves the agenticlens extra too (a local path
|
|
28
|
+
# source), so a normal `uv sync`/`uv run` tries to validate/refresh that
|
|
29
|
+
# entry even when the extra isn't requested -- and fails here since
|
|
30
|
+
# there's no sibling agenticlens checkout in this job. --frozen installs
|
|
31
|
+
# straight from the committed lock without touching it.
|
|
32
|
+
- name: Install dependencies (no agenticlens extra)
|
|
33
|
+
run: uv sync --extra dev --frozen --python ${{ matrix.python-version }}
|
|
34
|
+
|
|
35
|
+
- name: Lint (ruff check)
|
|
36
|
+
run: uv run --frozen ruff check .
|
|
37
|
+
|
|
38
|
+
- name: Format check (ruff format)
|
|
39
|
+
run: uv run --frozen ruff format --check .
|
|
40
|
+
|
|
41
|
+
- name: Type check (mypy)
|
|
42
|
+
run: uv run --frozen mypy
|
|
43
|
+
|
|
44
|
+
- name: Test (pytest) -- agenticlens integration tests auto-skip via importorskip
|
|
45
|
+
run: uv run --frozen pytest
|
|
46
|
+
|
|
47
|
+
# Covers agentic_chaos.integrations.agenticlens, which needs the optional
|
|
48
|
+
# extra installed. Both checkouts land as siblings under $GITHUB_WORKSPACE
|
|
49
|
+
# (.../agentic-chaos and .../agenticlens) so agentic-chaos's
|
|
50
|
+
# `[tool.uv.sources] agenticlens = { path = "../agenticlens" }` resolves
|
|
51
|
+
# correctly. actions/checkout refuses paths outside the workspace, so a
|
|
52
|
+
# literal `../agenticlens` path doesn't work here.
|
|
53
|
+
test-agenticlens-integration:
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- name: Check out agentic-chaos
|
|
57
|
+
uses: actions/checkout@v4
|
|
58
|
+
with:
|
|
59
|
+
path: agentic-chaos
|
|
60
|
+
|
|
61
|
+
- name: Check out agenticlens (local dependency, not yet published with chaos_events support)
|
|
62
|
+
uses: actions/checkout@v4
|
|
63
|
+
with:
|
|
64
|
+
repository: DeepAgentLabs/agenticlens
|
|
65
|
+
path: agenticlens
|
|
66
|
+
|
|
67
|
+
- name: Install uv
|
|
68
|
+
uses: astral-sh/setup-uv@v3
|
|
69
|
+
with:
|
|
70
|
+
enable-cache: true
|
|
71
|
+
|
|
72
|
+
- name: Set up Python
|
|
73
|
+
run: uv python install 3.12
|
|
74
|
+
|
|
75
|
+
- name: Install dependencies (with the optional agenticlens extra)
|
|
76
|
+
working-directory: agentic-chaos
|
|
77
|
+
run: uv sync --extra dev --extra agenticlens --python 3.12
|
|
78
|
+
|
|
79
|
+
- name: Type check (mypy) -- exercises the integration module against the real package
|
|
80
|
+
working-directory: agentic-chaos
|
|
81
|
+
run: uv run mypy
|
|
82
|
+
|
|
83
|
+
- name: Test (pytest)
|
|
84
|
+
working-directory: agentic-chaos
|
|
85
|
+
run: uv run pytest
|
|
86
|
+
|
|
87
|
+
# Proves the built distribution's own metadata has no hard agenticlens
|
|
88
|
+
# dependency -- built with only the core dev extra, no sibling checkout.
|
|
89
|
+
package:
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
needs: [test-core, test-agenticlens-integration]
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
- name: Install uv
|
|
95
|
+
uses: astral-sh/setup-uv@v3
|
|
96
|
+
with:
|
|
97
|
+
enable-cache: true
|
|
98
|
+
- name: Set up Python
|
|
99
|
+
run: uv python install 3.12
|
|
100
|
+
# --frozen: see the comment on the same flag in test-core -- no sibling
|
|
101
|
+
# agenticlens checkout here, and the agenticlens extra isn't requested.
|
|
102
|
+
- name: Install dependencies
|
|
103
|
+
run: uv sync --extra dev --frozen --python 3.12
|
|
104
|
+
- name: Build distributions
|
|
105
|
+
run: |
|
|
106
|
+
uv run --frozen python -m build
|
|
107
|
+
uv run --frozen python -m twine check dist/*
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: publish-pypi
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- name: Build distributions
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
python -m pip install build twine
|
|
25
|
+
python -m build
|
|
26
|
+
python -m twine check dist/*
|
|
27
|
+
- name: Upload distributions
|
|
28
|
+
uses: actions/upload-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: python-package-distributions
|
|
31
|
+
path: dist/
|
|
32
|
+
|
|
33
|
+
publish-pypi:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
needs: build
|
|
36
|
+
environment: pypi
|
|
37
|
+
permissions:
|
|
38
|
+
id-token: write # required for PyPI Trusted Publishing (OIDC) -- no API token/secret needed
|
|
39
|
+
steps:
|
|
40
|
+
- name: Download distributions
|
|
41
|
+
uses: actions/download-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: python-package-distributions
|
|
44
|
+
path: dist/
|
|
45
|
+
- name: Publish to PyPI
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `.github/workflows/release-pypi.yml`: publishes to PyPI on a `v*` tag push
|
|
10
|
+
or a published GitHub Release, via Trusted Publishing (OIDC) against the
|
|
11
|
+
`pypi` environment -- no stored API token.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- `uv sync --extra dev` (and CI) failed outright for anyone without a sibling
|
|
16
|
+
`agenticlens` checkout: `[tool.uv.sources]`'s local path override for the
|
|
17
|
+
optional `agenticlens` extra made `uv` try to validate/refresh that extra
|
|
18
|
+
on *every* sync, even when it wasn't requested. Fixed by using `--frozen`
|
|
19
|
+
wherever the sibling checkout isn't guaranteed (README's plain install
|
|
20
|
+
instructions, CI's `test-core` and `package` jobs) -- see README's
|
|
21
|
+
Installation/Development sections.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **`agenticlens` is no longer a required dependency.** `agentic_chaos.chaos`
|
|
26
|
+
(`chaos_call`, `chaos_session`, the fault types) and the CLI now work
|
|
27
|
+
standalone against any Python callable, no other package needed.
|
|
28
|
+
`chaos_call()` takes plain `step_id`/`step_name` strings instead of an
|
|
29
|
+
AgenticLens `StepHandle`.
|
|
30
|
+
- `agentic-chaos chaos run --save` now writes this package's own standalone
|
|
31
|
+
`ChaosReport` (`id`, `name`, `start_time`, `end_time`, `chaos_events`)
|
|
32
|
+
instead of requiring the target script to build an AgenticLens `Workflow`
|
|
33
|
+
via `profile()`. A `ChaosReport`'s JSON is still valid AgenticLens
|
|
34
|
+
`Workflow` JSON (same field names, no `steps`), so `agenticlens analyze`
|
|
35
|
+
still works on it directly if you have AgenticLens installed -- interop
|
|
36
|
+
through a shared JSON shape, not a code dependency.
|
|
37
|
+
- `agentic-chaos chaos run` now catches an uncaught exception from the target
|
|
38
|
+
script, still renders/saves whatever chaos events were recorded, and exits
|
|
39
|
+
non-zero -- previously an unhandled fault would crash the CLI before
|
|
40
|
+
`--save` ran.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- `examples/chaos_advanced_faults_demo.py`: `TokenTimeoutFault(mode="delay")`
|
|
45
|
+
and a custom `SilentDegradationFault(degrade_fn=...)`, the two fault
|
|
46
|
+
options that weren't demonstrated anywhere outside the tests. README's
|
|
47
|
+
Fault Types section links to it and the other examples now have an index
|
|
48
|
+
table.
|
|
49
|
+
- `agentic_chaos.integrations.agenticlens` (optional, `pip install
|
|
50
|
+
agentic-chaos[agenticlens]`): `attach_events()` merges a chaos session's
|
|
51
|
+
events onto an AgenticLens `Workflow`; `step_kwargs()` extracts
|
|
52
|
+
`step_id`/`step_name` from a `StepHandle`. Neither `agentic_chaos`'s core
|
|
53
|
+
nor its CLI imports this module or `agenticlens`.
|
|
54
|
+
`examples/chaos_with_agenticlens_demo.py` shows the full round trip.
|
|
55
|
+
- `agentic_chaos.chaos` — the LLM Chaos Toolkit (v0.1 milestone):
|
|
56
|
+
- `chaos_session()` / `chaos_call()` — explicit, contextvar-based fault
|
|
57
|
+
injection API.
|
|
58
|
+
- Three fault types: `TokenTimeoutFault`, `RateLimitStormFault`,
|
|
59
|
+
`SilentDegradationFault`.
|
|
60
|
+
- `agentic-chaos chaos run` CLI command.
|
|
61
|
+
- `chaos_events` schema (v1.1), documented in agenticlens's
|
|
62
|
+
`docs/workflow-schema-spec.md`.
|
|
63
|
+
- `agenticlens.recommenders.ChaosImpactRecommender` — thin adapter (in the
|
|
64
|
+
agenticlens repo) that reads `chaos_events` and reports resilience findings
|
|
65
|
+
alongside AgenticLens's existing cost/latency recommendations.
|
|
66
|
+
- Placeholder `agentic_chaos.agents` (v0.2) and `agentic_chaos.drift` (v0.3)
|
|
67
|
+
modules — not yet implemented.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepAgentLabs
|
|
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,296 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentic-chaos
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Standalone fault injection toolkit for LLM calls and agentic workflows, with an optional AgenticLens integration.
|
|
5
|
+
Project-URL: Homepage, https://github.com/DeepAgentLabs/agentic-chaos
|
|
6
|
+
Project-URL: Repository, https://github.com/DeepAgentLabs/agentic-chaos
|
|
7
|
+
Project-URL: Issues, https://github.com/DeepAgentLabs/agentic-chaos/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/DeepAgentLabs/agentic-chaos/blob/main/CHANGELOG.md
|
|
9
|
+
Author: agentic-chaos Contributors
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 DeepAgentLabs
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Keywords: agents,chaos-engineering,fault-injection,llm,observability,resilience
|
|
33
|
+
Classifier: Development Status :: 3 - Alpha
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
41
|
+
Requires-Python: >=3.10
|
|
42
|
+
Requires-Dist: pydantic<3,>=2.0
|
|
43
|
+
Requires-Dist: rich>=13.0
|
|
44
|
+
Requires-Dist: typer>=0.12
|
|
45
|
+
Provides-Extra: agenticlens
|
|
46
|
+
Requires-Dist: agenticlens>=0.1.3; extra == 'agenticlens'
|
|
47
|
+
Provides-Extra: dev
|
|
48
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
49
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
50
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
51
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
52
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
53
|
+
Requires-Dist: twine>=5.1; extra == 'dev'
|
|
54
|
+
Description-Content-Type: text/markdown
|
|
55
|
+
|
|
56
|
+
# agentic-chaos
|
|
57
|
+
|
|
58
|
+
`agentic-chaos` is a standalone fault-injection toolkit for LLM calls and
|
|
59
|
+
agentic workflows. It deliberately breaks your app — hung completions,
|
|
60
|
+
provider rate-limit storms, silently corrupted output — and reports what
|
|
61
|
+
happened. It has **no required dependency on any other package**, including
|
|
62
|
+
[AgenticLens](https://github.com/DeepAgentLabs/agenticlens): `pip install
|
|
63
|
+
agentic-chaos` and use it against any plain Python callable.
|
|
64
|
+
|
|
65
|
+
If you also use AgenticLens, an optional integration lets you merge chaos
|
|
66
|
+
events straight into an AgenticLens `Workflow`, so `agenticlens analyze`
|
|
67
|
+
reports on cost/latency and chaos impact together — see
|
|
68
|
+
[Optional: AgenticLens Integration](#optional-agenticlens-integration) below.
|
|
69
|
+
Neither package imports the other at the core level; the two are independent
|
|
70
|
+
tools that happen to compose.
|
|
71
|
+
|
|
72
|
+
## Status
|
|
73
|
+
|
|
74
|
+
`agentic-chaos` is early-stage software (v0.1 — the **LLM Chaos Toolkit**).
|
|
75
|
+
Two more modules are planned: an **Agent Failure Injector** for
|
|
76
|
+
LangGraph/CrewAI/AutoGen (v0.2), and a **Prompt/Model Drift Detector** (v0.3).
|
|
77
|
+
See [ROADMAP.md](ROADMAP.md) for the full plan.
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install agentic-chaos
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
or, from source with `uv`:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/DeepAgentLabs/agentic-chaos.git
|
|
89
|
+
cd agentic-chaos
|
|
90
|
+
uv sync --extra dev --frozen
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
That's it — no other package required. (If you want the optional AgenticLens
|
|
94
|
+
integration too, see [below](#optional-agenticlens-integration).)
|
|
95
|
+
|
|
96
|
+
`--frozen` matters here: `pyproject.toml` points the (currently unpublished)
|
|
97
|
+
`agenticlens` extra at a sibling checkout via `[tool.uv.sources]`, and `uv
|
|
98
|
+
sync` without `--frozen` tries to validate/refresh the *entire* lock — every
|
|
99
|
+
extra, including ones you didn't ask for — which fails if that sibling
|
|
100
|
+
directory doesn't exist. `--frozen` installs straight from the committed
|
|
101
|
+
`uv.lock` instead. Drop it (and check out `agenticlens` as a sibling
|
|
102
|
+
directory) only if you're working on the optional integration itself — see
|
|
103
|
+
[Development](#development).
|
|
104
|
+
|
|
105
|
+
## Quickstart
|
|
106
|
+
|
|
107
|
+
Wrap the calls you want to be fragile with `chaos_call()`:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from agentic_chaos.chaos import chaos_call, TokenTimeoutError
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
chunks = chaos_call(retriever.search, user_question, faults=["token_timeout"])
|
|
114
|
+
except TokenTimeoutError:
|
|
115
|
+
chunks = [] # no fallback handled it -- this is exactly what we want to find
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Outside of a `chaos_session(...)`, `chaos_call()` is a transparent pass-through
|
|
119
|
+
— `fn(*args, **kwargs)` runs exactly as if `agentic-chaos` weren't there. So
|
|
120
|
+
the same instrumented code path is safe to ship; chaos only activates when you
|
|
121
|
+
explicitly turn it on.
|
|
122
|
+
|
|
123
|
+
Run the script under chaos from the CLI, choosing which faults are active
|
|
124
|
+
without touching the code:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
uv run agentic-chaos chaos run my_app.py --inject token_timeout,rate_limit_storm --save chaos_run.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
Chaos Events
|
|
132
|
+
Step Fault Outcome Message
|
|
133
|
+
────────────────────────────────────────────────────────────────────────────
|
|
134
|
+
Retriever token_timeout errored call hung for 2.0s then timed out
|
|
135
|
+
|
|
136
|
+
1 chaos event(s) recorded.
|
|
137
|
+
|
|
138
|
+
Saved chaos report to chaos_run.json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`chaos_run.json` is this package's own standalone report — no other library
|
|
142
|
+
needed to produce or read it.
|
|
143
|
+
|
|
144
|
+
## Fault Types (v0.1)
|
|
145
|
+
|
|
146
|
+
| Fault | `--inject` name | What it does |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| Token timeout | `token_timeout` | Hangs for `hang_seconds` (default 2.0s), then raises `TokenTimeoutError` — simulates a client-side timeout on a hung/slow completion. Pass `mode="delay"` to let the real call complete late instead of erroring. |
|
|
149
|
+
| Rate-limit storm | `rate_limit_storm` | Raises `RateLimitStormError` (with a `retry_after` hint) for the first `burst_count` calls (default 3), then passes calls through normally — simulates a provider 429/backoff cascade that eventually clears. |
|
|
150
|
+
| Silent degradation | `silent_degradation` | Calls the real function, then corrupts its text content (`.content`/`.text`/a raw string) while preserving latency and token counts. The hardest fault to detect and the highest-value one to catch — nothing in cost/latency telemetry looks wrong. |
|
|
151
|
+
|
|
152
|
+
Every fault records a `ChaosEvent` (`fault_type`, `outcome`, and — when you
|
|
153
|
+
pass `step_id`/`step_name` — the correlation you chose). Use the Python API
|
|
154
|
+
to override defaults per fault:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from agentic_chaos.chaos import chaos_session, TokenTimeoutFault, RateLimitStormFault
|
|
158
|
+
|
|
159
|
+
with chaos_session([TokenTimeoutFault(hang_seconds=5.0), RateLimitStormFault(burst_count=1)]):
|
|
160
|
+
...
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
When more than one fault is configured for a session, `chaos_call()` requires
|
|
164
|
+
you to pass `faults=[...]` at each call site to say which one applies there —
|
|
165
|
+
silently picking one for you would be surprising.
|
|
166
|
+
|
|
167
|
+
Two options worth knowing about that don't show up in the table above (see
|
|
168
|
+
[`examples/chaos_advanced_faults_demo.py`](examples/chaos_advanced_faults_demo.py)
|
|
169
|
+
for both, runnable):
|
|
170
|
+
|
|
171
|
+
- `TokenTimeoutFault(mode="delay")` — the call still succeeds, just late,
|
|
172
|
+
instead of raising `TokenTimeoutError`. Recorded outcome is `"delayed"`.
|
|
173
|
+
Useful for testing whether a slow-but-successful call degrades UX on its
|
|
174
|
+
own, separate from outright failure.
|
|
175
|
+
- `SilentDegradationFault(degrade_fn=my_fn)` — swap in your own corruption
|
|
176
|
+
logic (`my_fn(result) -> corrupted_result`) instead of the built-in text
|
|
177
|
+
garbler, e.g. to simulate a narrower, more realistic bug than wholesale
|
|
178
|
+
noise.
|
|
179
|
+
|
|
180
|
+
## CLI Reference
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Run a script with chaos active and print a chaos-events report.
|
|
184
|
+
agentic-chaos chaos run my_app.py --inject token_timeout,rate_limit_storm
|
|
185
|
+
|
|
186
|
+
# Same, saving the resulting standalone report for later inspection.
|
|
187
|
+
agentic-chaos chaos run my_app.py --inject silent_degradation --save chaos_run.json
|
|
188
|
+
|
|
189
|
+
# List available fault types.
|
|
190
|
+
agentic-chaos chaos list-faults
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`agentic-chaos agent ...` and `agentic-chaos drift ...` are placeholders for
|
|
194
|
+
the v0.2 and v0.3 modules — running them today prints a pointer to
|
|
195
|
+
[ROADMAP.md](ROADMAP.md).
|
|
196
|
+
|
|
197
|
+
## Examples
|
|
198
|
+
|
|
199
|
+
| Script | Needs | Shows |
|
|
200
|
+
| --- | --- | --- |
|
|
201
|
+
| [`examples/chaos_customer_support_demo.py`](examples/chaos_customer_support_demo.py) | nothing but `agentic_chaos` | All three faults' default behavior in one flow: a rate-limit storm the app retries through and recovers from, a token timeout it doesn't handle (fails outright), and a silent degradation (normal-looking call, corrupted output). |
|
|
202
|
+
| [`examples/chaos_advanced_faults_demo.py`](examples/chaos_advanced_faults_demo.py) | nothing but `agentic_chaos` | `TokenTimeoutFault(mode="delay")` and a custom `SilentDegradationFault(degrade_fn=...)`. |
|
|
203
|
+
| [`examples/chaos_with_agenticlens_demo.py`](examples/chaos_with_agenticlens_demo.py) | `agentic-chaos[agenticlens]` | The optional integration: `attach_events()` + `step_kwargs()` merging chaos events onto a real AgenticLens `Workflow`. |
|
|
204
|
+
|
|
205
|
+
Run any of them directly (`uv run python examples/...`), or the first two
|
|
206
|
+
under the CLI:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
uv run agentic-chaos chaos run examples/chaos_customer_support_demo.py \
|
|
210
|
+
--inject rate_limit_storm,token_timeout,silent_degradation --save /tmp/chaos_run.json
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Optional: AgenticLens Integration
|
|
214
|
+
|
|
215
|
+
If you *also* use [AgenticLens](https://github.com/DeepAgentLabs/agenticlens)
|
|
216
|
+
to profile cost/latency, install the extra:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
pip install agentic-chaos[agenticlens]
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Then correlate chaos events to AgenticLens steps and merge them onto the
|
|
223
|
+
`Workflow` yourself:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
from agenticlens import profile, step
|
|
227
|
+
from agenticlens.exporters import JSONExporter
|
|
228
|
+
from agentic_chaos.chaos import chaos_call, chaos_session, TokenTimeoutError
|
|
229
|
+
from agentic_chaos.integrations.agenticlens import attach_events, step_kwargs
|
|
230
|
+
|
|
231
|
+
with chaos_session(["token_timeout"]) as session:
|
|
232
|
+
with profile("Customer Support Agent") as workflow:
|
|
233
|
+
with step("Retriever", type="retriever", chunk_count=4) as s:
|
|
234
|
+
try:
|
|
235
|
+
chunks = chaos_call(retriever.search, user_question, **step_kwargs(s))
|
|
236
|
+
except TokenTimeoutError:
|
|
237
|
+
chunks = []
|
|
238
|
+
attach_events(session, workflow)
|
|
239
|
+
|
|
240
|
+
JSONExporter().export(workflow, "workflow.json")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
agenticlens analyze workflow.json
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
Optimization Suggestions
|
|
249
|
+
* Chaos impact: token_timeout on 'Retriever'
|
|
250
|
+
-- Injected fault 'token_timeout' hit step 'Retriever' 1 time and the call
|
|
251
|
+
raised an error each time (call hung for 2.0s then timed out). ... (~0 tokens)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
`agentic_chaos.chaos_call()`/`chaos_session()` and the CLI never import
|
|
255
|
+
AgenticLens — only `agentic_chaos.integrations.agenticlens` does, and only
|
|
256
|
+
when you import it yourself. See
|
|
257
|
+
[`examples/chaos_with_agenticlens_demo.py`](examples/chaos_with_agenticlens_demo.py)
|
|
258
|
+
for a runnable version of the above.
|
|
259
|
+
|
|
260
|
+
This works because `agentic-chaos`'s own report format (`ChaosReport`) and
|
|
261
|
+
AgenticLens's `chaos_events` field share a documented JSON shape (schema
|
|
262
|
+
v1.1, see
|
|
263
|
+
[`docs/workflow-schema-spec.md`](https://github.com/DeepAgentLabs/agenticlens/blob/main/docs/workflow-schema-spec.md)
|
|
264
|
+
in the agenticlens repo) — interop through a shared file format, not a code
|
|
265
|
+
dependency in either direction.
|
|
266
|
+
|
|
267
|
+
## Development
|
|
268
|
+
|
|
269
|
+
Without a sibling `agenticlens` checkout, use `--frozen` (see
|
|
270
|
+
[Installation](#installation) for why):
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
uv sync --extra dev --frozen
|
|
274
|
+
uv run --frozen pytest
|
|
275
|
+
uv run --frozen ruff check .
|
|
276
|
+
uv run --frozen ruff format .
|
|
277
|
+
uv run --frozen mypy
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Tests covering `agentic_chaos.integrations.agenticlens` skip automatically if
|
|
281
|
+
`agenticlens` isn't installed. To run the full suite including those, clone
|
|
282
|
+
`agenticlens` as a sibling directory and sync with the optional extra
|
|
283
|
+
(dropping `--frozen`, since now you *want* the lock to pick it up):
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
git clone https://github.com/DeepAgentLabs/agenticlens.git ../agenticlens
|
|
287
|
+
uv sync --extra dev --extra agenticlens
|
|
288
|
+
uv run pytest
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
(see [`[tool.uv.sources]`](pyproject.toml) for the local sibling-checkout override
|
|
292
|
+
used until `agenticlens` publishes a release with `chaos_events` support).
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT — see [LICENSE](LICENSE).
|