agent-killswitch 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.
Files changed (74) hide show
  1. agent_killswitch-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +67 -0
  2. agent_killswitch-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +54 -0
  3. agent_killswitch-0.1.0/.github/workflows/ci.yml +71 -0
  4. agent_killswitch-0.1.0/.github/workflows/release.yml +68 -0
  5. agent_killswitch-0.1.0/.gitignore +46 -0
  6. agent_killswitch-0.1.0/.ruff.toml +55 -0
  7. agent_killswitch-0.1.0/CHANGELOG.md +29 -0
  8. agent_killswitch-0.1.0/CONTRIBUTING.md +117 -0
  9. agent_killswitch-0.1.0/LICENSE +190 -0
  10. agent_killswitch-0.1.0/Makefile +54 -0
  11. agent_killswitch-0.1.0/PKG-INFO +392 -0
  12. agent_killswitch-0.1.0/README.md +340 -0
  13. agent_killswitch-0.1.0/SECURITY.md +52 -0
  14. agent_killswitch-0.1.0/benchmarks/bench_kill_latency.py +101 -0
  15. agent_killswitch-0.1.0/examples/asyncio_agents.py +74 -0
  16. agent_killswitch-0.1.0/examples/basic_usage.py +75 -0
  17. agent_killswitch-0.1.0/examples/budget_kill_trigger.py +74 -0
  18. agent_killswitch-0.1.0/examples/circuit_breaker_pattern.py +94 -0
  19. agent_killswitch-0.1.0/examples/heartbeat_monitor.py +76 -0
  20. agent_killswitch-0.1.0/examples/langchain_integration.py +59 -0
  21. agent_killswitch-0.1.0/noxfile.py +64 -0
  22. agent_killswitch-0.1.0/pyproject.toml +136 -0
  23. agent_killswitch-0.1.0/src/agent_killswitch/__init__.py +76 -0
  24. agent_killswitch-0.1.0/src/agent_killswitch/_version.py +5 -0
  25. agent_killswitch-0.1.0/src/agent_killswitch/backends/__init__.py +21 -0
  26. agent_killswitch-0.1.0/src/agent_killswitch/backends/base.py +95 -0
  27. agent_killswitch-0.1.0/src/agent_killswitch/backends/memory.py +120 -0
  28. agent_killswitch-0.1.0/src/agent_killswitch/backends/redis.py +230 -0
  29. agent_killswitch-0.1.0/src/agent_killswitch/core/__init__.py +36 -0
  30. agent_killswitch-0.1.0/src/agent_killswitch/core/budget_kill.py +281 -0
  31. agent_killswitch-0.1.0/src/agent_killswitch/core/cascading.py +280 -0
  32. agent_killswitch-0.1.0/src/agent_killswitch/core/circuit_breaker.py +323 -0
  33. agent_killswitch-0.1.0/src/agent_killswitch/core/enums.py +112 -0
  34. agent_killswitch-0.1.0/src/agent_killswitch/core/heartbeat.py +313 -0
  35. agent_killswitch-0.1.0/src/agent_killswitch/core/killswitch.py +581 -0
  36. agent_killswitch-0.1.0/src/agent_killswitch/core/models.py +173 -0
  37. agent_killswitch-0.1.0/src/agent_killswitch/decorators.py +302 -0
  38. agent_killswitch-0.1.0/src/agent_killswitch/integrations/__init__.py +17 -0
  39. agent_killswitch-0.1.0/src/agent_killswitch/integrations/asyncio_tasks.py +211 -0
  40. agent_killswitch-0.1.0/src/agent_killswitch/integrations/crewai.py +151 -0
  41. agent_killswitch-0.1.0/src/agent_killswitch/integrations/langchain.py +135 -0
  42. agent_killswitch-0.1.0/src/agent_killswitch/integrations/langgraph.py +143 -0
  43. agent_killswitch-0.1.0/src/agent_killswitch/integrations/openai_agents.py +151 -0
  44. agent_killswitch-0.1.0/src/agent_killswitch/py.typed +0 -0
  45. agent_killswitch-0.1.0/tests/__init__.py +0 -0
  46. agent_killswitch-0.1.0/tests/chaos/__init__.py +0 -0
  47. agent_killswitch-0.1.0/tests/chaos/test_backend_failure.py +129 -0
  48. agent_killswitch-0.1.0/tests/chaos/test_concurrent_kills.py +135 -0
  49. agent_killswitch-0.1.0/tests/chaos/test_network_partition.py +126 -0
  50. agent_killswitch-0.1.0/tests/conftest.py +63 -0
  51. agent_killswitch-0.1.0/tests/e2e/__init__.py +0 -0
  52. agent_killswitch-0.1.0/tests/e2e/test_cascading_termination.py +104 -0
  53. agent_killswitch-0.1.0/tests/e2e/test_full_kill_flow.py +142 -0
  54. agent_killswitch-0.1.0/tests/e2e/test_heartbeat_recovery.py +109 -0
  55. agent_killswitch-0.1.0/tests/integration/__init__.py +0 -0
  56. agent_killswitch-0.1.0/tests/integration/test_asyncio_integration.py +129 -0
  57. agent_killswitch-0.1.0/tests/integration/test_framework_integrations.py +176 -0
  58. agent_killswitch-0.1.0/tests/integration/test_langchain_integration.py +96 -0
  59. agent_killswitch-0.1.0/tests/integration/test_redis_backend.py +101 -0
  60. agent_killswitch-0.1.0/tests/performance/__init__.py +0 -0
  61. agent_killswitch-0.1.0/tests/performance/test_heartbeat_overhead.py +74 -0
  62. agent_killswitch-0.1.0/tests/performance/test_kill_latency.py +110 -0
  63. agent_killswitch-0.1.0/tests/security/__init__.py +0 -0
  64. agent_killswitch-0.1.0/tests/security/test_bypass_prevention.py +117 -0
  65. agent_killswitch-0.1.0/tests/security/test_unauthorized_kill.py +94 -0
  66. agent_killswitch-0.1.0/tests/unit/__init__.py +0 -0
  67. agent_killswitch-0.1.0/tests/unit/test_backends.py +118 -0
  68. agent_killswitch-0.1.0/tests/unit/test_budget_kill.py +161 -0
  69. agent_killswitch-0.1.0/tests/unit/test_cascading.py +132 -0
  70. agent_killswitch-0.1.0/tests/unit/test_circuit_breaker.py +221 -0
  71. agent_killswitch-0.1.0/tests/unit/test_decorators.py +189 -0
  72. agent_killswitch-0.1.0/tests/unit/test_heartbeat.py +168 -0
  73. agent_killswitch-0.1.0/tests/unit/test_killswitch.py +312 -0
  74. agent_killswitch-0.1.0/tests/unit/test_models.py +196 -0
@@ -0,0 +1,67 @@
1
+ name: Bug Report
2
+ description: Report a bug in agent-killswitch
3
+ title: "[Bug]: "
4
+ labels: ["bug"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for reporting a bug! Please fill out the details below.
10
+
11
+ - type: textarea
12
+ id: description
13
+ attributes:
14
+ label: Description
15
+ description: What happened? What did you expect to happen?
16
+ placeholder: Describe the bug...
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: reproduction
22
+ attributes:
23
+ label: Steps to Reproduce
24
+ description: Minimal code to reproduce the issue.
25
+ placeholder: |
26
+ ```python
27
+ from agent_killswitch import KillSwitch
28
+ ks = KillSwitch()
29
+ # ...
30
+ ```
31
+ validations:
32
+ required: true
33
+
34
+ - type: input
35
+ id: version
36
+ attributes:
37
+ label: Version
38
+ description: What version of agent-killswitch are you using?
39
+ placeholder: "0.1.0"
40
+ validations:
41
+ required: true
42
+
43
+ - type: input
44
+ id: python-version
45
+ attributes:
46
+ label: Python Version
47
+ placeholder: "3.12"
48
+ validations:
49
+ required: true
50
+
51
+ - type: dropdown
52
+ id: backend
53
+ attributes:
54
+ label: Backend
55
+ options:
56
+ - InMemoryBackend (default)
57
+ - RedisBackend
58
+ - Custom backend
59
+ validations:
60
+ required: true
61
+
62
+ - type: textarea
63
+ id: logs
64
+ attributes:
65
+ label: Relevant Logs
66
+ description: Any error messages or stack traces.
67
+ render: shell
@@ -0,0 +1,54 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature for agent-killswitch
3
+ title: "[Feature]: "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for suggesting a feature! Please describe what you'd like.
10
+
11
+ - type: textarea
12
+ id: problem
13
+ attributes:
14
+ label: Problem
15
+ description: What problem does this feature solve?
16
+ placeholder: "I'm trying to... but there's no way to..."
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: solution
22
+ attributes:
23
+ label: Proposed Solution
24
+ description: How would you like this to work?
25
+ placeholder: "It would be great if..."
26
+ validations:
27
+ required: true
28
+
29
+ - type: textarea
30
+ id: alternatives
31
+ attributes:
32
+ label: Alternatives Considered
33
+ description: Any alternative solutions you've considered?
34
+
35
+ - type: dropdown
36
+ id: component
37
+ attributes:
38
+ label: Component
39
+ options:
40
+ - Core KillSwitch
41
+ - Heartbeat Monitor
42
+ - Circuit Breaker
43
+ - Budget Kill
44
+ - Cascading Termination
45
+ - Backends
46
+ - Decorators
47
+ - LangChain Integration
48
+ - LangGraph Integration
49
+ - CrewAI Integration
50
+ - OpenAI Agents Integration
51
+ - asyncio Integration
52
+ - Other
53
+ validations:
54
+ required: true
@@ -0,0 +1,71 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install -e ".[dev]"
28
+
29
+ - name: Lint
30
+ run: ruff check src/ tests/
31
+
32
+ - name: Format check
33
+ run: ruff format --check src/ tests/
34
+
35
+ - name: Unit tests
36
+ run: pytest tests/unit/ -v --timeout=30
37
+
38
+ - name: E2E tests
39
+ run: pytest tests/e2e/ -v --timeout=60
40
+
41
+ - name: Chaos tests
42
+ run: pytest tests/chaos/ -v --timeout=30
43
+
44
+ - name: Performance tests
45
+ run: pytest tests/performance/ -v --timeout=60
46
+
47
+ - name: Security tests
48
+ run: pytest tests/security/ -v --timeout=30
49
+
50
+ - name: Coverage
51
+ if: matrix.python-version == '3.12'
52
+ run: |
53
+ pytest tests/ -v --cov=agent_killswitch --cov-report=xml --timeout=60
54
+
55
+ - name: Upload coverage
56
+ if: matrix.python-version == '3.12'
57
+ uses: codecov/codecov-action@v4
58
+ with:
59
+ file: ./coverage.xml
60
+ fail_ci_if_error: false
61
+
62
+ type-check:
63
+ runs-on: ubuntu-latest
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+ - uses: actions/setup-python@v5
67
+ with:
68
+ python-version: "3.12"
69
+ - run: |
70
+ pip install -e ".[dev]"
71
+ mypy src/agent_killswitch/
@@ -0,0 +1,68 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install build tools
23
+ run: pip install build
24
+
25
+ - name: Build
26
+ run: python -m build
27
+
28
+ - name: Upload artifacts
29
+ uses: actions/upload-artifact@v4
30
+ with:
31
+ name: dist
32
+ path: dist/
33
+
34
+ publish-pypi:
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+ environment: pypi
38
+ permissions:
39
+ id-token: write
40
+ steps:
41
+ - name: Download artifacts
42
+ uses: actions/download-artifact@v4
43
+ with:
44
+ name: dist
45
+ path: dist/
46
+
47
+ - name: Publish to PyPI
48
+ uses: pypa/gh-action-pypi-publish@release/v1
49
+
50
+ github-release:
51
+ needs: build
52
+ runs-on: ubuntu-latest
53
+ permissions:
54
+ contents: write
55
+ steps:
56
+ - uses: actions/checkout@v4
57
+
58
+ - name: Download artifacts
59
+ uses: actions/download-artifact@v4
60
+ with:
61
+ name: dist
62
+ path: dist/
63
+
64
+ - name: Create GitHub Release
65
+ uses: softprops/action-gh-release@v2
66
+ with:
67
+ files: dist/*
68
+ generate_release_notes: true
@@ -0,0 +1,46 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ *.whl
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # Testing
18
+ .pytest_cache/
19
+ .benchmarks/
20
+ htmlcov/
21
+ .coverage
22
+ .coverage.*
23
+ coverage.xml
24
+ *.cover
25
+
26
+ # Type checking
27
+ .mypy_cache/
28
+
29
+ # Linting
30
+ .ruff_cache/
31
+
32
+ # IDE
33
+ .vscode/
34
+ .idea/
35
+ *.swp
36
+ *.swo
37
+ *~
38
+
39
+ # OS
40
+ .DS_Store
41
+ Thumbs.db
42
+
43
+ # Environment
44
+ .env
45
+ .env.local
46
+
@@ -0,0 +1,55 @@
1
+ # Ruff configuration for agent-killswitch
2
+ target-version = "py310"
3
+ line-length = 100
4
+
5
+ [lint]
6
+ select = [
7
+ "E", # pycodestyle errors
8
+ "W", # pycodestyle warnings
9
+ "F", # pyflakes
10
+ "I", # isort
11
+ "N", # pep8-naming
12
+ "UP", # pyupgrade
13
+ "B", # flake8-bugbear
14
+ "SIM", # flake8-simplify
15
+ "TCH", # flake8-type-checking
16
+ "RUF", # Ruff-specific rules
17
+ ]
18
+ ignore = [
19
+ "E501", # line too long (handled by formatter)
20
+ "B008", # do not perform function calls in argument defaults
21
+ "SIM108", # use ternary operator
22
+ "UP007", # use X | Y for union types (we support 3.10)
23
+
24
+ # --- Deliberate, documented exceptions ---------------------------------
25
+ # N818 "exception name should end in Error": `KillSwitchTriggered` and
26
+ # `CircuitBreakerOpen` are CONTROL-FLOW SIGNALS, not failures — the same
27
+ # category as the standard library's StopIteration, KeyboardInterrupt and
28
+ # SystemExit, none of which carry the suffix. `except KillSwitchTriggered:`
29
+ # states the intent exactly; renaming would make the API less clear.
30
+ "N818",
31
+
32
+ # TC001/TC002/TC003 "move this import into a TYPE_CHECKING block": this
33
+ # library has ZERO required runtime dependencies and imports only from the
34
+ # standard library, so guarding those imports saves no install time and no
35
+ # import time. It would only add a conditional block and quoted annotations
36
+ # to every module — cost without benefit here.
37
+ "TC001",
38
+ "TC002",
39
+ "TC003",
40
+ ]
41
+
42
+ [lint.per-file-ignores]
43
+ # RUF006 wants every asyncio task reference held in a long-lived collection. In these
44
+ # tests the task is created, awaited-through and consumed inside a single coroutine, so
45
+ # the local binding already keeps it alive for exactly as long as it must exist. The
46
+ # library code itself does hold real references - see integrations/asyncio_tasks.py.
47
+ "tests/**" = ["RUF006"]
48
+
49
+ [lint.isort]
50
+ known-first-party = ["agent_killswitch"]
51
+
52
+ [format]
53
+ quote-style = "double"
54
+ indent-style = "space"
55
+ docstring-code-format = true
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-09-07
9
+
10
+ ### Added
11
+
12
+ - Core `KillSwitch` class with tiered levels (PAUSE/STOP/KILL) and scoped targets (GLOBAL/CREW/AGENT/TASK)
13
+ - `HeartbeatMonitor` for tracking agent health with configurable intervals and miss thresholds
14
+ - `CircuitBreaker` pattern with CLOSED/OPEN/HALF_OPEN states
15
+ - `BudgetKillTrigger` for automatic kills when cost budgets are exceeded
16
+ - `CascadingTerminator` for parent-child agent hierarchy termination
17
+ - `InMemoryBackend` (zero dependencies, default)
18
+ - `RedisBackend` (optional, for distributed systems)
19
+ - Decorators: `@killswitch_protected`, `@with_heartbeat`, `@circuit_breaker`
20
+ - LangChain integration (callback handler)
21
+ - LangGraph integration (node and conditional edge)
22
+ - CrewAI integration (pre-action hook)
23
+ - OpenAI Agents SDK integration (guardrail)
24
+ - asyncio integration (task group cancellation)
25
+ - Fail-closed safety: backend failures default to KILLED state
26
+ - Full audit trail for all kill events
27
+ - Thread-safe and async-safe implementations
28
+ - Type hints on all public APIs
29
+ - py.typed marker for PEP 561
@@ -0,0 +1,117 @@
1
+ # Contributing to agent-killswitch
2
+
3
+ Thank you for your interest in contributing to agent-killswitch! This document
4
+ provides guidelines and information for contributors.
5
+
6
+ ## Development Setup
7
+
8
+ ```bash
9
+ # Clone the repository
10
+ git clone https://github.com/veerarakesh56/agent-killswitch.git
11
+ cd agent-killswitch
12
+
13
+ # Install in development mode
14
+ pip install -e ".[dev,all]"
15
+
16
+ # Run tests
17
+ make test
18
+
19
+ # Run linting
20
+ make lint
21
+
22
+ # Run type checking
23
+ make typecheck
24
+ ```
25
+
26
+ ## Running Tests
27
+
28
+ ```bash
29
+ # All tests
30
+ make test
31
+
32
+ # Specific test suites
33
+ make test-unit # Unit tests
34
+ make test-integration # Integration tests
35
+ make test-e2e # End-to-end tests
36
+ make test-chaos # Chaos/fault-injection tests
37
+ make test-perf # Performance tests
38
+ make test-security # Security tests
39
+
40
+ # With coverage
41
+ make coverage
42
+ ```
43
+
44
+ ## Code Quality
45
+
46
+ We use:
47
+ - **ruff** for linting and formatting
48
+ - **mypy** for type checking
49
+ - **pytest** for testing
50
+
51
+ Before submitting a PR:
52
+
53
+ ```bash
54
+ make lint # Check for linting errors
55
+ make format # Auto-format code
56
+ make typecheck # Run type checker
57
+ make test # Run all tests
58
+ ```
59
+
60
+ ## Architecture Principles
61
+
62
+ 1. **Zero required dependencies**: Core functionality must work with Python stdlib only
63
+ 2. **Fail-closed**: When in doubt, default to the safe state (KILLED)
64
+ 3. **Thread-safe**: All public APIs must be safe for concurrent access
65
+ 4. **Outside the reasoning path**: Kill switch operates at infrastructure level
66
+ 5. **No TTL**: Kill switches require explicit deactivation
67
+ 6. **Audit everything**: Every state change must be logged
68
+
69
+ ## Adding a New Backend
70
+
71
+ 1. Create a new file in `src/agent_killswitch/backends/`
72
+ 2. Implement the `KillSwitchBackend` protocol from `backends/base.py`
73
+ 3. Add tests in `tests/unit/test_backends.py`
74
+ 4. Document in README.md
75
+
76
+ ## Adding a New Integration
77
+
78
+ 1. Create a new file in `src/agent_killswitch/integrations/`
79
+ 2. The integration should be a thin adapter (minimal code)
80
+ 3. Framework dependency should be optional (import in function, not at module level)
81
+ 4. Add the framework to `[project.optional-dependencies]` in `pyproject.toml`
82
+ 5. Add tests in `tests/integration/`
83
+ 6. Add an example in `examples/`
84
+
85
+ ## Pull Request Process
86
+
87
+ 1. Fork the repository
88
+ 2. Create a feature branch (`git checkout -b feature/my-feature`)
89
+ 3. Make your changes
90
+ 4. Run all checks (`make lint && make typecheck && make test`)
91
+ 5. Commit with a descriptive message
92
+ 6. Push to your fork
93
+ 7. Open a Pull Request
94
+
95
+ ## Commit Message Format
96
+
97
+ We use conventional commits:
98
+
99
+ ```
100
+ feat: add new backend for DynamoDB
101
+ fix: correct race condition in heartbeat monitor
102
+ docs: update README with new examples
103
+ test: add chaos tests for network partition
104
+ refactor: simplify circuit breaker state machine
105
+ chore: update CI to test Python 3.13
106
+ ```
107
+
108
+ ## Reporting Issues
109
+
110
+ Use the issue templates on GitHub:
111
+ - **Bug Report**: For bugs and unexpected behavior
112
+ - **Feature Request**: For new features and enhancements
113
+
114
+ ## License
115
+
116
+ By contributing, you agree that your contributions will be licensed under
117
+ the Apache License 2.0.