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.
Files changed (75) hide show
  1. techrevati_runtime-0.1.0/.github/ISSUE_TEMPLATE/bug.md +27 -0
  2. techrevati_runtime-0.1.0/.github/ISSUE_TEMPLATE/feature.md +25 -0
  3. techrevati_runtime-0.1.0/.github/dependabot.yml +30 -0
  4. techrevati_runtime-0.1.0/.github/workflows/ci.yml +72 -0
  5. techrevati_runtime-0.1.0/.github/workflows/docs.yml +35 -0
  6. techrevati_runtime-0.1.0/.github/workflows/release.yml +38 -0
  7. techrevati_runtime-0.1.0/.gitignore +134 -0
  8. techrevati_runtime-0.1.0/.pre-commit-config.yaml +23 -0
  9. techrevati_runtime-0.1.0/CHANGELOG.md +219 -0
  10. techrevati_runtime-0.1.0/CODEOWNERS +20 -0
  11. techrevati_runtime-0.1.0/CONTRIBUTING.md +106 -0
  12. techrevati_runtime-0.1.0/LICENSE +21 -0
  13. techrevati_runtime-0.1.0/PKG-INFO +212 -0
  14. techrevati_runtime-0.1.0/README.md +173 -0
  15. techrevati_runtime-0.1.0/SECURITY.md +80 -0
  16. techrevati_runtime-0.1.0/docs/api/circuit_breaker.md +3 -0
  17. techrevati_runtime-0.1.0/docs/api/guardrails.md +3 -0
  18. techrevati_runtime-0.1.0/docs/api/handoffs.md +3 -0
  19. techrevati_runtime-0.1.0/docs/api/orchestrator.md +12 -0
  20. techrevati_runtime-0.1.0/docs/api/otel.md +5 -0
  21. techrevati_runtime-0.1.0/docs/api/retry_policy.md +3 -0
  22. techrevati_runtime-0.1.0/docs/api/sinks.md +3 -0
  23. techrevati_runtime-0.1.0/docs/api/usage_tracking.md +3 -0
  24. techrevati_runtime-0.1.0/docs/changelog.md +1 -0
  25. techrevati_runtime-0.1.0/docs/getting-started.md +207 -0
  26. techrevati_runtime-0.1.0/docs/index.md +62 -0
  27. techrevati_runtime-0.1.0/docs/migrating-from-0.0.x.md +189 -0
  28. techrevati_runtime-0.1.0/docs/patterns/agent-events.md +53 -0
  29. techrevati_runtime-0.1.0/docs/patterns/circuit-breaker.md +52 -0
  30. techrevati_runtime-0.1.0/docs/patterns/lifecycle.md +63 -0
  31. techrevati_runtime-0.1.0/docs/patterns/orchestrator.md +124 -0
  32. techrevati_runtime-0.1.0/docs/patterns/permissions.md +74 -0
  33. techrevati_runtime-0.1.0/docs/patterns/policy.md +72 -0
  34. techrevati_runtime-0.1.0/docs/patterns/quality-gate.md +49 -0
  35. techrevati_runtime-0.1.0/docs/patterns/retry.md +70 -0
  36. techrevati_runtime-0.1.0/docs/patterns/usage-tracking.md +89 -0
  37. techrevati_runtime-0.1.0/docs/tutorials/end-to-end.md +192 -0
  38. techrevati_runtime-0.1.0/examples/pricing.json +37 -0
  39. techrevati_runtime-0.1.0/examples/tiny_agent.py +135 -0
  40. techrevati_runtime-0.1.0/mkdocs.yml +71 -0
  41. techrevati_runtime-0.1.0/pyproject.toml +84 -0
  42. techrevati_runtime-0.1.0/src/techrevati/__init__.py +0 -0
  43. techrevati_runtime-0.1.0/src/techrevati/runtime/__init__.py +177 -0
  44. techrevati_runtime-0.1.0/src/techrevati/runtime/agent_events.py +270 -0
  45. techrevati_runtime-0.1.0/src/techrevati/runtime/agent_lifecycle.py +224 -0
  46. techrevati_runtime-0.1.0/src/techrevati/runtime/circuit_breaker.py +243 -0
  47. techrevati_runtime-0.1.0/src/techrevati/runtime/data/pricing.json +10 -0
  48. techrevati_runtime-0.1.0/src/techrevati/runtime/guardrails.py +138 -0
  49. techrevati_runtime-0.1.0/src/techrevati/runtime/handoffs.py +57 -0
  50. techrevati_runtime-0.1.0/src/techrevati/runtime/orchestrator.py +828 -0
  51. techrevati_runtime-0.1.0/src/techrevati/runtime/otel.py +190 -0
  52. techrevati_runtime-0.1.0/src/techrevati/runtime/permissions.py +139 -0
  53. techrevati_runtime-0.1.0/src/techrevati/runtime/policy_engine.py +243 -0
  54. techrevati_runtime-0.1.0/src/techrevati/runtime/py.typed +0 -0
  55. techrevati_runtime-0.1.0/src/techrevati/runtime/quality_gate.py +65 -0
  56. techrevati_runtime-0.1.0/src/techrevati/runtime/retry_policy.py +424 -0
  57. techrevati_runtime-0.1.0/src/techrevati/runtime/sinks.py +115 -0
  58. techrevati_runtime-0.1.0/src/techrevati/runtime/usage_tracking.py +232 -0
  59. techrevati_runtime-0.1.0/tests/__init__.py +0 -0
  60. techrevati_runtime-0.1.0/tests/test_agent_events.py +209 -0
  61. techrevati_runtime-0.1.0/tests/test_agent_lifecycle.py +155 -0
  62. techrevati_runtime-0.1.0/tests/test_async_circuit_breaker.py +169 -0
  63. techrevati_runtime-0.1.0/tests/test_async_orchestrator.py +283 -0
  64. techrevati_runtime-0.1.0/tests/test_circuit_breaker.py +339 -0
  65. techrevati_runtime-0.1.0/tests/test_guardrails.py +166 -0
  66. techrevati_runtime-0.1.0/tests/test_handoffs.py +86 -0
  67. techrevati_runtime-0.1.0/tests/test_max_iterations.py +68 -0
  68. techrevati_runtime-0.1.0/tests/test_orchestrator.py +287 -0
  69. techrevati_runtime-0.1.0/tests/test_otel.py +125 -0
  70. techrevati_runtime-0.1.0/tests/test_permissions.py +97 -0
  71. techrevati_runtime-0.1.0/tests/test_policy_engine.py +232 -0
  72. techrevati_runtime-0.1.0/tests/test_quality_gate.py +63 -0
  73. techrevati_runtime-0.1.0/tests/test_retry_policy.py +246 -0
  74. techrevati_runtime-0.1.0/tests/test_sinks.py +151 -0
  75. 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