techrevati-runtime 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.
- techrevati_runtime-0.1.0/.github/ISSUE_TEMPLATE/bug.md +27 -0
- techrevati_runtime-0.1.0/.github/ISSUE_TEMPLATE/feature.md +25 -0
- techrevati_runtime-0.1.0/.github/dependabot.yml +30 -0
- techrevati_runtime-0.1.0/.github/workflows/ci.yml +72 -0
- techrevati_runtime-0.1.0/.github/workflows/docs.yml +35 -0
- techrevati_runtime-0.1.0/.github/workflows/release.yml +38 -0
- techrevati_runtime-0.1.0/.gitignore +134 -0
- techrevati_runtime-0.1.0/.pre-commit-config.yaml +23 -0
- techrevati_runtime-0.1.0/CHANGELOG.md +219 -0
- techrevati_runtime-0.1.0/CODEOWNERS +20 -0
- techrevati_runtime-0.1.0/CONTRIBUTING.md +106 -0
- techrevati_runtime-0.1.0/LICENSE +21 -0
- techrevati_runtime-0.1.0/PKG-INFO +212 -0
- techrevati_runtime-0.1.0/README.md +173 -0
- techrevati_runtime-0.1.0/SECURITY.md +80 -0
- techrevati_runtime-0.1.0/docs/api/circuit_breaker.md +3 -0
- techrevati_runtime-0.1.0/docs/api/guardrails.md +3 -0
- techrevati_runtime-0.1.0/docs/api/handoffs.md +3 -0
- techrevati_runtime-0.1.0/docs/api/orchestrator.md +12 -0
- techrevati_runtime-0.1.0/docs/api/otel.md +5 -0
- techrevati_runtime-0.1.0/docs/api/retry_policy.md +3 -0
- techrevati_runtime-0.1.0/docs/api/sinks.md +3 -0
- techrevati_runtime-0.1.0/docs/api/usage_tracking.md +3 -0
- techrevati_runtime-0.1.0/docs/changelog.md +1 -0
- techrevati_runtime-0.1.0/docs/getting-started.md +207 -0
- techrevati_runtime-0.1.0/docs/index.md +62 -0
- techrevati_runtime-0.1.0/docs/migrating-from-0.0.x.md +189 -0
- techrevati_runtime-0.1.0/docs/patterns/agent-events.md +53 -0
- techrevati_runtime-0.1.0/docs/patterns/circuit-breaker.md +52 -0
- techrevati_runtime-0.1.0/docs/patterns/lifecycle.md +63 -0
- techrevati_runtime-0.1.0/docs/patterns/orchestrator.md +124 -0
- techrevati_runtime-0.1.0/docs/patterns/permissions.md +74 -0
- techrevati_runtime-0.1.0/docs/patterns/policy.md +72 -0
- techrevati_runtime-0.1.0/docs/patterns/quality-gate.md +49 -0
- techrevati_runtime-0.1.0/docs/patterns/retry.md +70 -0
- techrevati_runtime-0.1.0/docs/patterns/usage-tracking.md +89 -0
- techrevati_runtime-0.1.0/docs/tutorials/end-to-end.md +192 -0
- techrevati_runtime-0.1.0/examples/pricing.json +37 -0
- techrevati_runtime-0.1.0/examples/tiny_agent.py +135 -0
- techrevati_runtime-0.1.0/mkdocs.yml +71 -0
- techrevati_runtime-0.1.0/pyproject.toml +84 -0
- techrevati_runtime-0.1.0/src/techrevati/__init__.py +0 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/__init__.py +177 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/agent_events.py +270 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/agent_lifecycle.py +224 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/circuit_breaker.py +243 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/data/pricing.json +10 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/guardrails.py +138 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/handoffs.py +57 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/orchestrator.py +828 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/otel.py +190 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/permissions.py +139 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/policy_engine.py +243 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/py.typed +0 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/quality_gate.py +65 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/retry_policy.py +424 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/sinks.py +115 -0
- techrevati_runtime-0.1.0/src/techrevati/runtime/usage_tracking.py +232 -0
- techrevati_runtime-0.1.0/tests/__init__.py +0 -0
- techrevati_runtime-0.1.0/tests/test_agent_events.py +209 -0
- techrevati_runtime-0.1.0/tests/test_agent_lifecycle.py +155 -0
- techrevati_runtime-0.1.0/tests/test_async_circuit_breaker.py +169 -0
- techrevati_runtime-0.1.0/tests/test_async_orchestrator.py +283 -0
- techrevati_runtime-0.1.0/tests/test_circuit_breaker.py +339 -0
- techrevati_runtime-0.1.0/tests/test_guardrails.py +166 -0
- techrevati_runtime-0.1.0/tests/test_handoffs.py +86 -0
- techrevati_runtime-0.1.0/tests/test_max_iterations.py +68 -0
- techrevati_runtime-0.1.0/tests/test_orchestrator.py +287 -0
- techrevati_runtime-0.1.0/tests/test_otel.py +125 -0
- techrevati_runtime-0.1.0/tests/test_permissions.py +97 -0
- techrevati_runtime-0.1.0/tests/test_policy_engine.py +232 -0
- techrevati_runtime-0.1.0/tests/test_quality_gate.py +63 -0
- techrevati_runtime-0.1.0/tests/test_retry_policy.py +246 -0
- techrevati_runtime-0.1.0/tests/test_sinks.py +151 -0
- techrevati_runtime-0.1.0/tests/test_usage_tracking.py +252 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something is broken, surprising, or contradicts the docs.
|
|
4
|
+
title: ""
|
|
5
|
+
labels: bug
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**What happened**
|
|
9
|
+
<!-- One or two sentences. -->
|
|
10
|
+
|
|
11
|
+
**What you expected**
|
|
12
|
+
<!-- One or two sentences. Quote the docs section if applicable. -->
|
|
13
|
+
|
|
14
|
+
**Minimal reproduction**
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# Smallest snippet that reproduces. Use mock model/tool calls if
|
|
18
|
+
# the bug doesn't depend on a real provider.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Environment**
|
|
22
|
+
- techrevati-runtime version: `pip show techrevati-runtime | grep -i version`
|
|
23
|
+
- Python: `python --version`
|
|
24
|
+
- OS: <e.g. Linux 6.x / macOS 14 / Windows 11>
|
|
25
|
+
|
|
26
|
+
**Anything else?**
|
|
27
|
+
<!-- Logs, stack traces, screenshots, suspected root cause. -->
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: A new primitive, knob, or integration.
|
|
4
|
+
title: ""
|
|
5
|
+
labels: enhancement
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Problem**
|
|
9
|
+
<!-- What can't you do today? Be concrete — a specific agent loop,
|
|
10
|
+
a missing observability hook, a tuning knob, etc. -->
|
|
11
|
+
|
|
12
|
+
**Proposed shape**
|
|
13
|
+
<!-- API sketch. Don't worry about syntax — pseudocode is fine. -->
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
# Imagined call site:
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Alternatives considered**
|
|
20
|
+
<!-- What would you do today as a workaround? Why doesn't it scale? -->
|
|
21
|
+
|
|
22
|
+
**Industry priors**
|
|
23
|
+
<!-- Has another agent SDK (OpenAI Agents SDK, LangGraph, Anthropic
|
|
24
|
+
Claude Agent SDK, etc.) shipped something similar? Link it. We
|
|
25
|
+
prefer landing primitives that match industry conventions. -->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: pip
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
day: monday
|
|
8
|
+
open-pull-requests-limit: 5
|
|
9
|
+
labels:
|
|
10
|
+
- dependencies
|
|
11
|
+
- python
|
|
12
|
+
groups:
|
|
13
|
+
dev-tools:
|
|
14
|
+
patterns:
|
|
15
|
+
- "ruff"
|
|
16
|
+
- "mypy"
|
|
17
|
+
- "pytest*"
|
|
18
|
+
otel:
|
|
19
|
+
patterns:
|
|
20
|
+
- "opentelemetry-*"
|
|
21
|
+
|
|
22
|
+
- package-ecosystem: github-actions
|
|
23
|
+
directory: "/"
|
|
24
|
+
schedule:
|
|
25
|
+
interval: weekly
|
|
26
|
+
day: monday
|
|
27
|
+
open-pull-requests-limit: 3
|
|
28
|
+
labels:
|
|
29
|
+
- dependencies
|
|
30
|
+
- github-actions
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test on Python ${{ matrix.python-version }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
cache: pip
|
|
25
|
+
cache-dependency-path: pyproject.toml
|
|
26
|
+
|
|
27
|
+
- name: Install package + dev dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install -e ".[dev]"
|
|
31
|
+
|
|
32
|
+
- name: Lint with ruff
|
|
33
|
+
run: ruff check src/ tests/
|
|
34
|
+
|
|
35
|
+
- name: Format check with ruff
|
|
36
|
+
run: ruff format --check src/ tests/
|
|
37
|
+
|
|
38
|
+
- name: Type check with mypy
|
|
39
|
+
run: mypy src/ --strict
|
|
40
|
+
|
|
41
|
+
- name: Run tests
|
|
42
|
+
run: pytest tests/ -v --cov=src/techrevati --cov-report=term-missing --cov-report=xml
|
|
43
|
+
|
|
44
|
+
- name: Upload coverage
|
|
45
|
+
uses: codecov/codecov-action@v4
|
|
46
|
+
with:
|
|
47
|
+
files: ./coverage.xml
|
|
48
|
+
fail_ci_if_error: false
|
|
49
|
+
|
|
50
|
+
build:
|
|
51
|
+
name: Build package
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
needs: test
|
|
54
|
+
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Set up Python
|
|
59
|
+
uses: actions/setup-python@v5
|
|
60
|
+
with:
|
|
61
|
+
python-version: '3.11'
|
|
62
|
+
|
|
63
|
+
- name: Install build tools
|
|
64
|
+
run: pip install build
|
|
65
|
+
|
|
66
|
+
- name: Build distribution
|
|
67
|
+
run: python -m build
|
|
68
|
+
|
|
69
|
+
- name: Check wheel
|
|
70
|
+
run: |
|
|
71
|
+
pip install dist/*.whl
|
|
72
|
+
python -c "from techrevati import runtime; print(f'techrevati-runtime {runtime.__version__}')"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
docs:
|
|
12
|
+
name: Build and deploy docs
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v4
|
|
20
|
+
with:
|
|
21
|
+
python-version: '3.11'
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
pip install mkdocs mkdocs-material mkdocstrings[python]
|
|
27
|
+
|
|
28
|
+
- name: Build documentation
|
|
29
|
+
run: mkdocs build
|
|
30
|
+
|
|
31
|
+
- name: Deploy to GitHub Pages
|
|
32
|
+
uses: peaceiris/actions-gh-pages@v3
|
|
33
|
+
with:
|
|
34
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
35
|
+
publish_dir: ./site
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
release:
|
|
14
|
+
name: Release to PyPI
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v4
|
|
22
|
+
with:
|
|
23
|
+
python-version: '3.11'
|
|
24
|
+
|
|
25
|
+
- name: Install build tools
|
|
26
|
+
run: pip install build
|
|
27
|
+
|
|
28
|
+
- name: Build distribution
|
|
29
|
+
run: python -m build
|
|
30
|
+
|
|
31
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
32
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
33
|
+
|
|
34
|
+
- name: Create GitHub Release
|
|
35
|
+
uses: softprops/action-gh-release@v1
|
|
36
|
+
with:
|
|
37
|
+
generate_release_notes: true
|
|
38
|
+
files: dist/*
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
*.py,cover
|
|
49
|
+
.hypothesis/
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Django stuff:
|
|
57
|
+
*.log
|
|
58
|
+
local_settings.py
|
|
59
|
+
db.sqlite3
|
|
60
|
+
db.sqlite3-journal
|
|
61
|
+
|
|
62
|
+
# Flask stuff:
|
|
63
|
+
instance/
|
|
64
|
+
.webassets-cache
|
|
65
|
+
|
|
66
|
+
# Scrapy stuff:
|
|
67
|
+
.scrapy
|
|
68
|
+
|
|
69
|
+
# Sphinx documentation
|
|
70
|
+
docs/_build/
|
|
71
|
+
|
|
72
|
+
# PyBuilder
|
|
73
|
+
target/
|
|
74
|
+
|
|
75
|
+
# Jupyter Notebook
|
|
76
|
+
.ipynb_checkpoints
|
|
77
|
+
|
|
78
|
+
# IPython
|
|
79
|
+
profile_default/
|
|
80
|
+
ipython_config.py
|
|
81
|
+
|
|
82
|
+
# pyenv
|
|
83
|
+
.python-version
|
|
84
|
+
|
|
85
|
+
# pipenv
|
|
86
|
+
Pipfile.lock
|
|
87
|
+
|
|
88
|
+
# PEP 582
|
|
89
|
+
__pypackages__/
|
|
90
|
+
|
|
91
|
+
# Celery stuff
|
|
92
|
+
celerybeat-schedule
|
|
93
|
+
celerybeat.pid
|
|
94
|
+
|
|
95
|
+
# SageMath parsed files
|
|
96
|
+
*.sage.py
|
|
97
|
+
|
|
98
|
+
# Environments
|
|
99
|
+
.env
|
|
100
|
+
.venv
|
|
101
|
+
env/
|
|
102
|
+
venv/
|
|
103
|
+
ENV/
|
|
104
|
+
env.bak/
|
|
105
|
+
venv.bak/
|
|
106
|
+
|
|
107
|
+
# Spyder project settings
|
|
108
|
+
.spyderproject
|
|
109
|
+
.spyproject
|
|
110
|
+
|
|
111
|
+
# Rope project settings
|
|
112
|
+
.ropeproject
|
|
113
|
+
|
|
114
|
+
# mkdocs documentation
|
|
115
|
+
/site
|
|
116
|
+
|
|
117
|
+
# mypy
|
|
118
|
+
.mypy_cache/
|
|
119
|
+
.dmypy.json
|
|
120
|
+
dmypy.json
|
|
121
|
+
|
|
122
|
+
# Pyre type checker
|
|
123
|
+
.pyre/
|
|
124
|
+
|
|
125
|
+
# Ruff cache
|
|
126
|
+
.ruff_cache/
|
|
127
|
+
|
|
128
|
+
# IDEs
|
|
129
|
+
.idea/
|
|
130
|
+
.vscode/
|
|
131
|
+
*.swp
|
|
132
|
+
*.swo
|
|
133
|
+
*~
|
|
134
|
+
.DS_Store
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.14.5
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
10
|
+
rev: v4.5.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: trailing-whitespace
|
|
13
|
+
- id: end-of-file-fixer
|
|
14
|
+
- id: check-yaml
|
|
15
|
+
- id: check-added-large-files
|
|
16
|
+
- id: check-merge-conflict
|
|
17
|
+
|
|
18
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
19
|
+
rev: v1.18.2
|
|
20
|
+
hooks:
|
|
21
|
+
- id: mypy
|
|
22
|
+
additional_dependencies: []
|
|
23
|
+
args: [--strict]
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `techrevati-runtime` are documented here. The format
|
|
4
|
+
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); the project
|
|
5
|
+
follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html), with the
|
|
6
|
+
caveat that 0.x APIs are explicitly unstable.
|
|
7
|
+
|
|
8
|
+
## [0.1.0] — 2026-05-20
|
|
9
|
+
|
|
10
|
+
First beta release. Closes the primitive-parity gap with 2026 agent
|
|
11
|
+
SDKs and ships the async path the 0.0.x docstring had been falsely
|
|
12
|
+
advertising. APIs in this release are intended to be stable; breaking
|
|
13
|
+
changes between 0.1.x and 0.2.0 will be documented in
|
|
14
|
+
[`docs/migrating-from-0.0.x.md`](https://github.com/Techrevati/runtime/blob/main/docs/migrating-from-0.0.x.md) and
|
|
15
|
+
gated by deprecation warnings.
|
|
16
|
+
|
|
17
|
+
Consolidates the work of pre-release tags `0.1.0.dev1`, `0.1.0.dev2`,
|
|
18
|
+
`0.1.0.dev3`, and `0.1.0.rc1`. Per-sprint detail is in the git log.
|
|
19
|
+
|
|
20
|
+
### Added — Async path
|
|
21
|
+
- `AsyncCircuitBreaker` mirrors `CircuitBreaker` semantics with
|
|
22
|
+
`asyncio.Lock`, same `half_open_max_probes` serialization,
|
|
23
|
+
injectable monotonic `clock`. State independent of the sync
|
|
24
|
+
variant.
|
|
25
|
+
- `Orchestrator.asession()` returns an `AsyncOrchestrationSession`.
|
|
26
|
+
`arun_turn` and `arun_tool` drive async coro factories; sync
|
|
27
|
+
helpers (`authorize`, `evaluate_policy`, `evaluate_gate`,
|
|
28
|
+
`summary`, lifecycle methods) shared with the sync session via
|
|
29
|
+
`_SessionBase`.
|
|
30
|
+
- `aattempt_recovery(scenario, ctx, *, sleeper=asyncio.sleep)` async
|
|
31
|
+
sibling of `attempt_recovery` with injectable sleeper contract.
|
|
32
|
+
- `arun_turn(timeout=...)` enforces deadlines with
|
|
33
|
+
`asyncio.wait_for`; sync `run_turn(timeout=...)` uses a one-shot
|
|
34
|
+
`ThreadPoolExecutor`. Both raise `TurnTimeoutError` for a single
|
|
35
|
+
catchable error class across code paths.
|
|
36
|
+
- `AgentStatus.CANCELLED` terminal state. `asyncio.CancelledError`
|
|
37
|
+
out of `async with orch.asession()` transitions the worker to
|
|
38
|
+
CANCELLED and re-raises.
|
|
39
|
+
- `AsyncOrchestrationSession.pause_for_input(prompt)` async
|
|
40
|
+
human-in-the-loop hook. Transitions worker to `WAITING_FOR_INPUT`;
|
|
41
|
+
resolve from elsewhere via `session.provide_input(value)`.
|
|
42
|
+
- `RUNNING → WAITING_FOR_INPUT` is now a valid transition (was
|
|
43
|
+
missing in 0.0.x).
|
|
44
|
+
|
|
45
|
+
### Added — Industry primitive parity
|
|
46
|
+
- `MaxIterationsExceededError` + `Orchestrator(max_iterations=25)`
|
|
47
|
+
cap. Default matches OpenAI Agents SDK; counted across both
|
|
48
|
+
`run_turn` and `arun_turn`. Anthropic explicitly names stopping
|
|
49
|
+
conditions as a production-readiness requirement.
|
|
50
|
+
- `Handoff` immutable dataclass (`techrevati.runtime.handoffs`) +
|
|
51
|
+
`OrchestrationSession.handoff_to(target_role, reason, context)`.
|
|
52
|
+
Finalizes the source worker as COMPLETED, registers a fresh worker
|
|
53
|
+
for the target role under the same project_id, returns a Handoff
|
|
54
|
+
describing the delegation. Enables Anthropic's orchestrator-workers
|
|
55
|
+
pattern on top of our primitives.
|
|
56
|
+
- `Guardrail` Protocol + `GuardrailOutcome` + `GuardrailViolatedError`
|
|
57
|
+
(`techrevati.runtime.guardrails`). `Orchestrator(guardrails=[...])`
|
|
58
|
+
auto-runs `check_pre` before and `check_post` after every
|
|
59
|
+
`run_tool` / `arun_tool` invocation; first violation raises with
|
|
60
|
+
guardrail name, stage, role, tool. Mirrors the OpenAI Agents SDK
|
|
61
|
+
guardrail model.
|
|
62
|
+
- `AllowAllGuardrail` reference no-op implementation.
|
|
63
|
+
- `AgentSession` alias for `Orchestrator`. The 0.2.0 rename will
|
|
64
|
+
promote `AgentSession` to the canonical name with `Orchestrator`
|
|
65
|
+
kept as a deprecation alias; adopting the new name now is
|
|
66
|
+
forward-compatible.
|
|
67
|
+
|
|
68
|
+
### Added — Observability
|
|
69
|
+
- `EventSink` and `UsageSink` Protocols (`techrevati.runtime.sinks`),
|
|
70
|
+
plus `NoopEventSink`, `NoopUsageSink`, `RingBufferEventSink`,
|
|
71
|
+
`RingBufferUsageSink` defaults. `RingBufferEventSink` enforces a
|
|
72
|
+
configurable capacity (default 1000) so long-running sessions
|
|
73
|
+
can't balloon memory — closes the unbounded-tracker gap from
|
|
74
|
+
0.0.x.
|
|
75
|
+
- `Orchestrator(event_sink=..., usage_sink=...)` plumbs the
|
|
76
|
+
configured sinks through every session. Every `AgentEvent` the
|
|
77
|
+
session records is forwarded to the event sink; every recorded
|
|
78
|
+
turn is forwarded to the usage sink with its computed cost. A
|
|
79
|
+
misbehaving sink cannot tear down the session — emit failures
|
|
80
|
+
log and are swallowed.
|
|
81
|
+
- `OpenTelemetrySink` and `OpenTelemetryUsageSink`
|
|
82
|
+
(`techrevati.runtime.otel`, available via the new `[otel]`
|
|
83
|
+
extra). Mirrors every event as a one-shot OTel span with
|
|
84
|
+
`gen_ai.operation.name`, `gen_ai.provider.name`,
|
|
85
|
+
`gen_ai.agent.name`, optional `gen_ai.agent.id`, and `error.type`
|
|
86
|
+
on failures. Records `gen_ai.client.token.usage` histogram (with
|
|
87
|
+
`gen_ai.token.type=input|output` discriminator) and a
|
|
88
|
+
`techrevati.cost.usd` counter. Span names follow the GenAI agent
|
|
89
|
+
spans convention (`create_agent` / `invoke_agent` /
|
|
90
|
+
`execute_tool` / `invoke_workflow`).
|
|
91
|
+
- `[otel]` extra: `opentelemetry-api>=1.27`,
|
|
92
|
+
`opentelemetry-sdk>=1.27`,
|
|
93
|
+
`opentelemetry-semantic-conventions>=0.48b0`.
|
|
94
|
+
- Structured `logger.info` calls at five decision points: recovery
|
|
95
|
+
attempted, session failed, quality gate failed, handoff issued,
|
|
96
|
+
budget exceeded. All with `extra={role, phase, project_id, ...}`
|
|
97
|
+
so log shippers can pivot by role.
|
|
98
|
+
|
|
99
|
+
### Added — Docs and DX
|
|
100
|
+
- `docs/tutorials/end-to-end.md` walks every primitive composed
|
|
101
|
+
together with sync, async, and OTel switchover.
|
|
102
|
+
- `examples/tiny_agent.py` runnable companion (not bundled in
|
|
103
|
+
wheel). Smoke-tested end-to-end.
|
|
104
|
+
- `examples/pricing.json` reference template with illustrative
|
|
105
|
+
Claude / GPT pricing (not normative).
|
|
106
|
+
- `docs/api/*.md` eight `mkdocstrings`-backed API reference pages
|
|
107
|
+
via the Python handler.
|
|
108
|
+
- `docs/patterns/orchestrator.md` rewritten with
|
|
109
|
+
When-to-use / Anti-patterns / Tuning template + a prominent
|
|
110
|
+
naming-disambiguation callout separating our `Orchestrator` from
|
|
111
|
+
Anthropic's *orchestrator-workers* delegation pattern.
|
|
112
|
+
- `CONTRIBUTING.md`, `SECURITY.md`, `CODEOWNERS`,
|
|
113
|
+
`.github/dependabot.yml`, `.github/ISSUE_TEMPLATE/{bug,feature}.md`.
|
|
114
|
+
|
|
115
|
+
### Changed
|
|
116
|
+
- `evaluate_policy(elapsed_seconds=...)` is now `float | None`
|
|
117
|
+
(default `None`). When omitted, elapsed is auto-computed from
|
|
118
|
+
session start so `TimedOut` conditions finally fire. Callers
|
|
119
|
+
passing explicit `0.0` previously must migrate to pass the value
|
|
120
|
+
they actually want.
|
|
121
|
+
- `AgentRegistry` and `_SessionBase` record session start time on
|
|
122
|
+
construction.
|
|
123
|
+
- README revised end-to-end. Headline pitch matches what the
|
|
124
|
+
package now does (sync **and** async, four standard primitives,
|
|
125
|
+
OTel GenAI semconv). New *"Why not LangGraph / OpenAI Agents
|
|
126
|
+
SDK?"* positioning section. Classifier bumped from `3 - Alpha`
|
|
127
|
+
to `4 - Beta`.
|
|
128
|
+
- README tagline reflects beta status.
|
|
129
|
+
|
|
130
|
+
### Notes
|
|
131
|
+
- Tool input gating is pre-call site (role + tool name) gating +
|
|
132
|
+
post-call value gating. True input-value gating arrives when we
|
|
133
|
+
have a typed tool input model (post-0.2.0).
|
|
134
|
+
- Guardrail violations are not retried automatically — they raise.
|
|
135
|
+
- Span nesting (parent/child relationships across agent/turn/tool)
|
|
136
|
+
is not yet emitted — discrete spans + `gen_ai.agent.id` give
|
|
137
|
+
correlation. Nesting is targeted for 0.2.0.
|
|
138
|
+
- The `[dev]` extra now installs OpenTelemetry SDK packages so the
|
|
139
|
+
optional `otel` module type-checks and tests run under
|
|
140
|
+
`mypy --strict`.
|
|
141
|
+
|
|
142
|
+
## [0.0.1] — 2026-05-20
|
|
143
|
+
|
|
144
|
+
### Fixed
|
|
145
|
+
- `mypy --strict` now passes. Added `src/techrevati/__init__.py` namespace
|
|
146
|
+
marker (PEP 420) so the wheel layout no longer double-maps modules. Removed
|
|
147
|
+
`continue-on-error: true` from the CI mypy step, which had been silently
|
|
148
|
+
swallowing failures since 0.0.0.
|
|
149
|
+
- `CircuitBreaker` uses `time.monotonic` instead of `time.time` for duration
|
|
150
|
+
checks. NTP/clock jumps no longer stick the breaker open or close it early.
|
|
151
|
+
- Removed inaccurate `"Production async runtime"` claim from the package
|
|
152
|
+
docstring. Async support is targeted for 0.1.0; this version is sync only.
|
|
153
|
+
|
|
154
|
+
### Added
|
|
155
|
+
- `BudgetExceededError` plus `Orchestrator(enforce_budget=True)` flag. When
|
|
156
|
+
enabled, `run_turn` raises after the cumulative cost exceeds `budget_usd`.
|
|
157
|
+
The default remains backwards-compatible (records an event, returns
|
|
158
|
+
normally) so existing callers see no behavior change unless they opt in.
|
|
159
|
+
- `has_pricing(model)` helper. `UsageTracker.record_turn` now emits a one-time
|
|
160
|
+
`WARNING` per process per model when pricing has not been registered. This
|
|
161
|
+
closes the silent-$0 footgun where unregistered models produced no cost
|
|
162
|
+
signal.
|
|
163
|
+
- `CircuitBreaker.half_open_max_probes` (default `1`). Concurrent half-open
|
|
164
|
+
probes are now serialized; previously the lock was released before `fn()`
|
|
165
|
+
ran, letting unbounded threads stampede a recovering service. Probe in-flight
|
|
166
|
+
counting is tracked under the same lock as state transitions. Conforms to
|
|
167
|
+
the Polly default; raise to N for Resilience4j-style behavior.
|
|
168
|
+
- `CircuitBreaker.clock` parameter accepting a `Callable[[], float]`. Defaults
|
|
169
|
+
to `time.monotonic`. Test code injects a manual clock to make recovery-window
|
|
170
|
+
tests deterministic; `time.sleep` is no longer used in the test suite.
|
|
171
|
+
- `backoff_delay(jitter=...)` accepts `"none"`, `"full"`, `"equal"`, or
|
|
172
|
+
`"decorrelated"` mode strings. Bool values are still accepted for backward
|
|
173
|
+
compatibility (`True` maps to `"full"`, `False` to `"none"`). New `cap` and
|
|
174
|
+
`prev_delay` parameters support standard AWS Architecture Blog formulas
|
|
175
|
+
(Marc Brooker, exponential backoff & jitter).
|
|
176
|
+
- README "Limitations" section documenting sync-only constraint, in-memory
|
|
177
|
+
tracker growth, pricing-not-bundled default, advisory permissions, lack of
|
|
178
|
+
durable execution, and lack of OTel integration.
|
|
179
|
+
|
|
180
|
+
### Changed
|
|
181
|
+
- **Default jitter algorithm is now decorrelated** (was full-additive 25%
|
|
182
|
+
jitter). Per AWS Builders' Library, decorrelated is the fastest of the four
|
|
183
|
+
documented algorithms. The change affects code calling `backoff_delay()`
|
|
184
|
+
with default jitter; pass `jitter="equal"` for behavior closest to the
|
|
185
|
+
previous default.
|
|
186
|
+
- README tagline reflects alpha status until 0.2.0 (was "Production runtime
|
|
187
|
+
primitives ...").
|
|
188
|
+
- `[project.optional-dependencies] dev` now pins `pytest`, `pytest-cov`,
|
|
189
|
+
`mypy`, and `ruff` to exact versions matching `.pre-commit-config.yaml`.
|
|
190
|
+
Local lint and CI lint can no longer disagree.
|
|
191
|
+
- CI now installs the package with `pip install -e ".[dev]"` instead of
|
|
192
|
+
unpinned `pip install pytest pytest-cov ruff mypy`. `actions/setup-python`
|
|
193
|
+
bumped from v4 to v5 with pip caching. `codecov/codecov-action` bumped from
|
|
194
|
+
v3 to v4. The `PYTHONPATH=src` workaround in pytest is gone (now resolved
|
|
195
|
+
by the namespace marker).
|
|
196
|
+
|
|
197
|
+
## [0.0.0] — 2026-05-20
|
|
198
|
+
|
|
199
|
+
Initial public release under the `techrevati-runtime` namespace.
|
|
200
|
+
|
|
201
|
+
Provides the foundational primitives for orchestrating multi-step LLM agent
|
|
202
|
+
loops with reliability and cost visibility:
|
|
203
|
+
|
|
204
|
+
- `Orchestrator` + `OrchestrationSession` — single-loop wiring of lifecycle,
|
|
205
|
+
usage, retry classification, circuit breaker, permissions, and policy.
|
|
206
|
+
- `CircuitBreaker` — three-state fault-tolerant execution wrapper.
|
|
207
|
+
- `RecoveryContext` + `attempt_recovery` + `classify_exception` — failure
|
|
208
|
+
classification and recipe lookup.
|
|
209
|
+
- `UsageTracker` + `register_pricing` + `load_pricing_from_file` — per-model
|
|
210
|
+
cost tracking with caller-provided pricing (no bundled pricing data).
|
|
211
|
+
- `QualityGate` + `QualityLevel` — graduated pass/fail evaluation.
|
|
212
|
+
- `AgentRegistry` + `AgentWorker` — validated lifecycle state machine.
|
|
213
|
+
- `AgentEvent` — typed lifecycle events with an OpenTelemetry attribute bridge.
|
|
214
|
+
- `PermissionPolicy` + `PermissionEnforcer` — deny-first role × tool gating.
|
|
215
|
+
- `PolicyEngine` + composable conditions — declarative rule evaluator.
|
|
216
|
+
|
|
217
|
+
[0.1.0]: https://github.com/Techrevati/runtime/releases/tag/v0.1.0
|
|
218
|
+
[0.0.1]: https://github.com/Techrevati/runtime/releases/tag/v0.0.1
|
|
219
|
+
[0.0.0]: https://github.com/Techrevati/runtime/releases/tag/v0.0.0
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# GitHub CODEOWNERS — pinpoint review on touchy files.
|
|
2
|
+
# Format: <pattern> <owner> [<owner>...]
|
|
3
|
+
# Owners auto-request review on PRs touching the matched paths.
|
|
4
|
+
|
|
5
|
+
# Default fallback.
|
|
6
|
+
* @Techrevati/runtime-maintainers
|
|
7
|
+
|
|
8
|
+
# Public API surface — extra review.
|
|
9
|
+
src/techrevati/runtime/__init__.py @Techrevati/runtime-maintainers
|
|
10
|
+
src/techrevati/runtime/orchestrator.py @Techrevati/runtime-maintainers
|
|
11
|
+
|
|
12
|
+
# Release and CI infrastructure.
|
|
13
|
+
.github/ @Techrevati/runtime-maintainers
|
|
14
|
+
pyproject.toml @Techrevati/runtime-maintainers
|
|
15
|
+
.pre-commit-config.yaml @Techrevati/runtime-maintainers
|
|
16
|
+
|
|
17
|
+
# Security-sensitive primitives.
|
|
18
|
+
src/techrevati/runtime/permissions.py @Techrevati/runtime-maintainers
|
|
19
|
+
src/techrevati/runtime/guardrails.py @Techrevati/runtime-maintainers
|
|
20
|
+
SECURITY.md @Techrevati/runtime-maintainers
|