Skip to content

Review fixes: tooling, enums, util module, mypy, docs (#2, #3, #5, #6, #7, #8)#13

Open
kamil-duszynski-dna wants to merge 9 commits into
mainfrom
review-fixes-2-3-5-6-7-8
Open

Review fixes: tooling, enums, util module, mypy, docs (#2, #3, #5, #6, #7, #8)#13
kamil-duszynski-dna wants to merge 9 commits into
mainfrom
review-fixes-2-3-5-6-7-8

Conversation

@kamil-duszynski-dna

Copy link
Copy Markdown
Collaborator

Summary

Addresses a batch of reviewer comments (#2, #3, #5, #6, #7, #8). Each item is a
separate commit. Based on the #9–11 branch.

Changes

  • style guidelines #8 — code style tooling. Add black (line length 88, configured in
    pyproject.toml) and flake8 (.flake8); both ship in the dev extra.
    Format the codebase and drop now-unused imports.
  • core/types.py issues #7StopReason enum. Convert StopReason from a string Literal to an
    Enum (matching Mode), so the trip reason is self-documenting in types.
  • _options.py issues #6 — config vocabulary. Rename _options.py_config.py to match the
    BreakerConfig class and drop the "knobs" wording everywhere.
  • src/core/_numbers.py issues #5util submodule. Move the internal helpers under
    monetise_circuit_breaker/util/ (numbers.py, config.py), type the numeric
    guards as Any, simplify finite_number, and add tests for the guards.
  • mypy issues #3 — mypy. A single python -m mypy run now type-checks both src/
    (strict) and tests/ (relaxed override) and passes — the plain mypy
    invocation no longer reports errors.
  • README.md issues #2 — README. Add a Development-setup section, document RetryEvent /
    StopEvent as dataclasses, clarify the on_trip sync/async wording, name the
    LangChain callback hooks, and sort the options table by mode.

Notes

Checks

black --check, flake8, python -m mypy, and pytest (116 passed) are all
green.

Address reviewer comments on the core breaker:

- Split CircuitBreaker into a base + per-mode strategies
  (_BudgetGuardBreaker / _LoopKillerBreaker); the public constructor
  dispatches on `mode`, so each strategy is free of mode branching and
  the `is None` limit checks disappear.
- Make Mode an Enum; replace the hand-rolled mode assertion with
  coerce_mode (accepts a Mode member or its string value).
- Move numeric guards to core/_numbers.py: is_positive_integer
  (tri-state) and is_non_negative_finite; drop the _describe helper.
- Remove the dead `return` after _trip (which is NoReturn).
- Rename set_token_snapshot -> set_tokens and TokenMetrics/ExtractedTokens
  fields input/output -> input_tokens/output_tokens.

Tests, README and AGENTS.md updated. mypy --strict clean.
- Clarify the type-check statement: the package (src/) is mypy --strict
  clean via `python -m mypy`; the test suite isn't held to strict typing,
  so bare `mypy --strict .` reports errors.
- Sort the repository-layout tree (dirs before files, core first) and add
  the previously-missing core/_numbers.py entry.
Drop the four identically-named with_circuit_breaker functions in favour of
per-adapter OOP runners (the word "with" collided with the keyword and the
duplicated names were a code smell):

- Add CircuitBreakerRunner base (_runner.py): captures the breaker config,
  mints a fresh breaker per run, gates the preflight estimator, resolves
  on_trip, and implements the context-manager protocol.
- Each adapter exposes a distinct subclass with a unified run() method:
  OpenAIAgentsCircuitBreakerRunner, LangChainCircuitBreakerRunner,
  ClaudeAgentCircuitBreakerRunner, LangGraphCircuitBreakerRunner.
- Canonical usage is a context manager:
      with OpenAIAgentsCircuitBreakerRunner(agent) as safe:
          await safe.run(...)

Update adapter exports, tests (incl. context-manager coverage), README and
AGENTS.md. mypy --strict clean.
Pins code layout so a contributor's editor settings can't reshape the
code. black (line length 88) owns formatting; flake8 catches unused
imports / undefined names and defers line length to black. Both ship in
the dev extra. Reformats the existing code to the committed config and
drops now-unused imports in the langchain wrapper.
Mirror Mode: StopReason is now an Enum (MAX_INPUT_TOKENS, MAX_OUTPUT_TOKENS,
MAX_RETRIES, REPEATED_STATE) instead of a string Literal, so the trip
reason is self-documenting in types and at call sites. Core trips and
comparisons use the members; tests and the README compare against them.
- Rename the module to match its BreakerConfig class and the config
  vocabulary (was _options.py).
- Drop the 'knobs' term everywhere in favour of 'config' (code + AGENTS.md).
- Rewrite the BreakerConfig docstring: 'core-breaker knobs, captured...'
  was unclear; say 'circuit-breaker configuration' plainly.
Mode is already an Enum (#9), covering the #6 Enum point.
…tests

- Group the internal helpers under monetise_circuit_breaker/util/:
  core/_numbers.py -> util/numbers.py and _config.py -> util/config.py
  (drop the underscores; the package marks the whole submodule internal).
- Type the numeric guards as Any instead of object.
- Simplify finite_number to reuse is_number (keeps the deliberate bool
  rejection that the reviewer's snippet would have dropped).
- Add tests/util/test_numbers.py covering every guard, incl. bool /
  NaN / inf / wrong-type edge cases.
mypy now checks both src/ and tests/ in one run (files + mypy_path), so the
plain 'mypy' / 'python -m mypy' the reviewer ran no longer reports errors.
src/ stays on the full strict config; tests get a relaxed tests.* override
(loosely-typed fakes, callbacks asserted to return None) disabling a few
test-only error codes. Fixed one genuine test typing gap (TripContext).
AGENTS.md updated to describe this accurately.
- Add a 'Development setup' section: clone, venv, pip install -e '.[dev]',
  and the pytest / mypy / black / flake8 commands. Note that dev pulls in
  the adapter frameworks (so the whole suite + mypy run) and give a lighter
  single-adapter install for when a heavy framework (openai-agents) won't
  resolve.
- Show RetryEvent / StopEvent as frozen dataclasses, like TripContext.
- Clarify that the on_trip callback (not the runner) may be sync or async.
- Name the LangChain on_llm_start / on_chat_model_start / on_llm_end hooks
  as BaseCallbackHandler methods, distinct from on_trip / on_event; qualify
  the LangGraph stream-event names too.
- 'swallowed' -> 'consumed' in the LangChain callback-dispatch note.
- Sort the options-reference table by mode (both, budget-guard,
  loop-killer, wrappers).
@kamil-duszynski-dna kamil-duszynski-dna self-assigned this Jun 18, 2026
@kamil-duszynski-dna kamil-duszynski-dna added the enhancement New feature or request label Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant