codexloop 0.1.0__tar.gz → 0.3.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.
- {codexloop-0.1.0 → codexloop-0.3.0}/.github/workflows/ci.yml +36 -1
- codexloop-0.3.0/.github/workflows/docs.yml +40 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.github/workflows/publish-testpypi.yml +1 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.github/workflows/release-please.yml +15 -8
- {codexloop-0.1.0 → codexloop-0.3.0}/.gitignore +1 -0
- codexloop-0.3.0/.release-please-manifest.json +3 -0
- codexloop-0.3.0/CHANGELOG.md +140 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/PKG-INFO +13 -5
- {codexloop-0.1.0 → codexloop-0.3.0}/README.md +12 -4
- codexloop-0.3.0/docs/publishing.md +74 -0
- codexloop-0.3.0/mkdocs.yml +44 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/pyproject.toml +14 -1
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/__init__.py +1 -1
- codexloop-0.3.0/src/codexloop/application/interfaces/__init__.py +75 -0
- codexloop-0.3.0/src/codexloop/application/interfaces/agent.py +46 -0
- codexloop-0.3.0/src/codexloop/application/interfaces/api.py +10 -0
- codexloop-0.3.0/src/codexloop/application/interfaces/control.py +21 -0
- {codexloop-0.1.0/src/codexloop/application/usecases → codexloop-0.3.0/src/codexloop/application/interfaces}/doctor.py +7 -9
- codexloop-0.3.0/src/codexloop/application/interfaces/observability.py +42 -0
- codexloop-0.3.0/src/codexloop/application/interfaces/permissions.py +14 -0
- codexloop-0.3.0/src/codexloop/application/interfaces/storage.py +31 -0
- codexloop-0.3.0/src/codexloop/application/interfaces/system.py +16 -0
- codexloop-0.3.0/src/codexloop/application/ports.py +61 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/runner.py +115 -1
- codexloop-0.3.0/src/codexloop/application/usecases/doctor.py +18 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/usecases/run_control.py +1 -5
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/bootstrap.py +15 -2
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/app.py +24 -1
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/run.py +10 -1
- codexloop-0.3.0/src/codexloop/domain/forecast.py +271 -0
- codexloop-0.3.0/src/codexloop/domain/handoff_marker.py +107 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/loop.py +31 -2
- codexloop-0.3.0/src/codexloop/domain/verbosity.py +80 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/git_savepoints.py +5 -1
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/logging.py +21 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/rundir.py +27 -2
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/fakes.py +3 -0
- codexloop-0.3.0/tests/application/test_interfaces_convention.py +100 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/test_runner.py +66 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/cli/test_app.py +15 -1
- codexloop-0.3.0/tests/cli/test_verbosity_flags.py +48 -0
- codexloop-0.3.0/tests/domain/test_forecast.py +209 -0
- codexloop-0.3.0/tests/domain/test_handoff_marker.py +83 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_loop.py +73 -1
- codexloop-0.3.0/tests/domain/test_verbosity.py +60 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_providers_gateway_extra.py +2 -1
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_appserver_gateway.py +9 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_coverage_boost.py +24 -1
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_doctor_env.py +36 -0
- codexloop-0.3.0/tests/infrastructure/test_git_savepoints_units.py +69 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_logging_redact.py +41 -0
- codexloop-0.3.0/tests/infrastructure/test_rollout_scan.py +91 -0
- codexloop-0.3.0/tests/infrastructure/test_rundir_run_id.py +48 -0
- codexloop-0.3.0/uv.lock +2277 -0
- codexloop-0.1.0/.release-please-manifest.json +0 -3
- codexloop-0.1.0/CHANGELOG.md +0 -42
- codexloop-0.1.0/docs/publishing.md +0 -65
- codexloop-0.1.0/mkdocs.yml +0 -28
- codexloop-0.1.0/src/codexloop/application/ports.py +0 -158
- {codexloop-0.1.0 → codexloop-0.3.0}/.agents/skills/codexloop-run/SKILL.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.claude/skills/codexloop-run/SKILL.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.cursor/rules/codexloop-run.mdc +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.editorconfig +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.github/CODEOWNERS +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/.pre-commit-config.yaml +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/AGENTS.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/CLAUDE.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/CODE_OF_CONDUCT.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/CONTRIBUTING.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/LICENSE +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/SECURITY.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0001-onion-import-linter.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0002-subprocess-codex-exec.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0003-credits-exhausted.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0004-adaptive-probe-loop.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0005-layered-capacity-probe.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0006-generated-openai-rest.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0007-default-approval-sandbox.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0008-policy-via-c-flags.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0009-optional-app-server.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0010-rollout-best-effort.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0011-never-consume-resets.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/0012-minimum-codex-version.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/adr/index.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/architecture/index.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/contributing.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/getting-started.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/guides/rest-api-surface.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/index.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/plans/_shared-transplant-outline.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/plans/architecture-and-roadmap.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/plans/research-notes.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/reference/cli.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/docs/superpowers/plans/2026-08-13-codexloop-implementation.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/release-please-config.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/dto.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/usecases/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/usecases/list_threads.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/usecases/preflight.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/usecases/resume_thread.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/application/usecases/run_plan.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/asyncio.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/approval_cmd.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/capacity.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/cwd_cmd.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/doctor.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/effort_cmd.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/logs.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/model_cmd.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/prompt.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/reset.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/resume.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/runs.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/sandbox_cmd.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/savepoints.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/snapshot.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/status.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/stop.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/threads.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/unwind.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/commands/watch.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/cli/render.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/approval.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/backoff.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/budget.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/capacity.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/classify.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/completion.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/control.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/error_codes.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/errors.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/model_profile.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/plan.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/savepoint.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/savepoint_message.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/session.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/signals.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/domain/waiting.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/argv.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/events.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/gateway.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/probe.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/process.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/schema.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/scripted.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/agent/translate.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/api_baseline.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/binder.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/gateway.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/introspect.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/json_io.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/params.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/providers.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/api/registry.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/appserver/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/appserver/client.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/appserver/gateway.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/appserver/ratelimits.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/audit.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/capacity_probe.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/clock.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/config.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/control.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/doctor_env.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/events.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/lock.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/notify.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/progress.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/redact.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/rollout.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/snapshot.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/state.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/state_bus.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/infrastructure/stream_ui.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/src/codexloop/py.typed +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/test_doctor.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/test_ports.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/test_usecases.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/application/test_waiting_runner.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/cli/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/cli/test_api.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/cli/test_asyncio.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/cli/test_e2e_shim.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/cli/test_ops_commands.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/conftest.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/strategies.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_approval.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_backoff.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_budget.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_capacity.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_classify.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_completion.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_control.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_error_codes.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_model_profile.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_plan.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_savepoint.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_session.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/domain/test_waiting.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/README.md +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/clean_completion.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/done_with_marker.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/huge_line.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/malformed_line.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/tool_heavy.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/truncated_stream.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/turn_failed_429_quota.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/fixtures/jsonl/turn_failed_429_window.jsonl +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_binder.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_drift.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_gateway.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_introspect.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_json_io.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_params.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_params_extra.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/api/test_providers.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_appserver.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_argv.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_capacity_probe.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_config.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_control_and_savepoints.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_events.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_gateway.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_lock.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_probe.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_process.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_ratelimits_extra.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_rollout.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_rundir_state.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_scripted.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_snapshot.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_state_bus.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_stream_ui.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/infrastructure/test_translate.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/fixtures/agent_scripts/done.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/fixtures/agent_scripts/quota_then_topup.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/fixtures/agent_scripts/unknown_429.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/fixtures/agent_scripts/wait_long.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/fixtures/agent_scripts/window_then_done.json +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/system/conftest.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/system/test_matrix_inprocess.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/live/system/test_subprocess_smoke.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/shim/__init__.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/shim/fake_appserver.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/shim/fake_codex.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/shim/test_fake_codex.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/test_bootstrap.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/test_no_vendor_leak.py +0 -0
- {codexloop-0.1.0 → codexloop-0.3.0}/tests/test_packaging.py +0 -0
|
@@ -35,7 +35,42 @@ jobs:
|
|
|
35
35
|
- run: lint-imports
|
|
36
36
|
- run: bandit -q -r src/codexloop
|
|
37
37
|
- run: pip-audit
|
|
38
|
-
|
|
38
|
+
# Per layer, not in aggregate: a blanket floor lets a well-tested domain
|
|
39
|
+
# hide an untested adapter. pytest-cov unions --cov scopes within one
|
|
40
|
+
# invocation, so each floor needs its own run.
|
|
41
|
+
- name: Coverage floor - domain (100%)
|
|
42
|
+
run: pytest -q --cov=codexloop.domain --cov-fail-under=100
|
|
43
|
+
- name: Coverage floor - application (100%)
|
|
44
|
+
run: pytest -q --cov=codexloop.application --cov-fail-under=100
|
|
45
|
+
- name: Coverage floor - infrastructure (100%)
|
|
46
|
+
run: pytest -q --cov=codexloop.infrastructure --cov-fail-under=100
|
|
47
|
+
- name: Coverage floor - cli (100%)
|
|
48
|
+
run: pytest -q --cov=codexloop.cli --cov-fail-under=100
|
|
49
|
+
|
|
50
|
+
docs:
|
|
51
|
+
name: MkDocs builds strictly
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v7.0.1
|
|
55
|
+
- uses: actions/setup-python@v7.0.0
|
|
56
|
+
with:
|
|
57
|
+
python-version: "3.12"
|
|
58
|
+
- run: python -m pip install --upgrade pip
|
|
59
|
+
- run: pip install -e ".[docs]"
|
|
60
|
+
- run: mkdocs build --strict
|
|
61
|
+
|
|
62
|
+
uv-lock:
|
|
63
|
+
name: uv.lock is in sync with pyproject.toml
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v7.0.1
|
|
67
|
+
- uses: actions/setup-python@v7.0.0
|
|
68
|
+
with:
|
|
69
|
+
python-version: "3.12"
|
|
70
|
+
- uses: astral-sh/setup-uv@v3
|
|
71
|
+
with:
|
|
72
|
+
enable-cache: true
|
|
73
|
+
- run: uv lock --check
|
|
39
74
|
|
|
40
75
|
build:
|
|
41
76
|
name: Package builds and is installable
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: false
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.12"
|
|
25
|
+
- run: python -m pip install --upgrade pip
|
|
26
|
+
- run: pip install -e ".[docs]"
|
|
27
|
+
- run: mkdocs build --strict
|
|
28
|
+
- uses: actions/upload-pages-artifact@v3
|
|
29
|
+
with:
|
|
30
|
+
path: site
|
|
31
|
+
|
|
32
|
+
deploy:
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment:
|
|
36
|
+
name: github-pages
|
|
37
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
38
|
+
steps:
|
|
39
|
+
- id: deployment
|
|
40
|
+
uses: actions/deploy-pages@v4
|
|
@@ -5,10 +5,14 @@ on:
|
|
|
5
5
|
branches: [main]
|
|
6
6
|
workflow_dispatch:
|
|
7
7
|
inputs:
|
|
8
|
-
|
|
9
|
-
description: "
|
|
8
|
+
publish_to_pypi:
|
|
9
|
+
description: "Build and publish ref to PyPI (Trusted Publishing). Use after tagging or to retry a release."
|
|
10
10
|
type: boolean
|
|
11
11
|
default: false
|
|
12
|
+
publish_tag:
|
|
13
|
+
description: "Git tag to build/publish when publish_to_pypi=true"
|
|
14
|
+
type: string
|
|
15
|
+
default: "v0.2.0"
|
|
12
16
|
|
|
13
17
|
permissions:
|
|
14
18
|
contents: write
|
|
@@ -22,9 +26,12 @@ jobs:
|
|
|
22
26
|
release_created: ${{ steps.release.outputs.release_created }}
|
|
23
27
|
tag_name: ${{ steps.release.outputs.tag_name }}
|
|
24
28
|
steps:
|
|
25
|
-
- uses: googleapis/release-please-action@
|
|
29
|
+
- uses: googleapis/release-please-action@v5
|
|
26
30
|
id: release
|
|
27
31
|
with:
|
|
32
|
+
# Repo default branch is develop; releases must target main only
|
|
33
|
+
# (feat → develop → TestPyPI → main → tag/PyPI).
|
|
34
|
+
target-branch: main
|
|
28
35
|
release-type: python
|
|
29
36
|
config-file: release-please-config.json
|
|
30
37
|
manifest-file: .release-please-manifest.json
|
|
@@ -52,15 +59,17 @@ jobs:
|
|
|
52
59
|
packages-dir: dist/
|
|
53
60
|
print-hash: true
|
|
54
61
|
|
|
55
|
-
publish-
|
|
56
|
-
if: ${{ github.event_name == 'workflow_dispatch' && inputs.
|
|
62
|
+
publish-pypi-manual:
|
|
63
|
+
if: ${{ github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi }}
|
|
57
64
|
runs-on: ubuntu-latest
|
|
58
|
-
environment:
|
|
65
|
+
environment: pypi
|
|
59
66
|
permissions:
|
|
60
67
|
id-token: write
|
|
61
68
|
contents: read
|
|
62
69
|
steps:
|
|
63
70
|
- uses: actions/checkout@v4
|
|
71
|
+
with:
|
|
72
|
+
ref: ${{ inputs.publish_tag }}
|
|
64
73
|
- uses: actions/setup-python@v5
|
|
65
74
|
with:
|
|
66
75
|
python-version: "3.12"
|
|
@@ -69,7 +78,5 @@ jobs:
|
|
|
69
78
|
- run: twine check --strict dist/*
|
|
70
79
|
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
71
80
|
with:
|
|
72
|
-
repository-url: https://test.pypi.org/legacy/
|
|
73
81
|
packages-dir: dist/
|
|
74
|
-
skip-existing: true
|
|
75
82
|
print-hash: true
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.3.0](https://github.com/adammatthewsteinberger/codexloop/compare/v0.2.0...v0.3.0) (2026-08-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add a -v/-q verbosity ladder and third-party log control ([b58dfc0](https://github.com/adammatthewsteinberger/codexloop/commit/b58dfc017ce9af34af07cb390ea9a8efd67435d3))
|
|
9
|
+
* add capacity forecasting (measurement only, disabled by default) ([c2a362b](https://github.com/adammatthewsteinberger/codexloop/commit/c2a362bcbd111e7f87e5fb2534eb1687e50dc42d))
|
|
10
|
+
* add the wind-down decision to the run loop state machine ([033b5b2](https://github.com/adammatthewsteinberger/codexloop/commit/033b5b2ecece721832f31cd08e103738c193c812))
|
|
11
|
+
* let the caller name a run with --run-id ([e22c2d0](https://github.com/adammatthewsteinberger/codexloop/commit/e22c2d05c03db5be84ecbbd544da418130c1023c))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **tests:** remove residual SHA-collision flake in savepoints test ([#20](https://github.com/adammatthewsteinberger/codexloop/issues/20)) ([b375f71](https://github.com/adammatthewsteinberger/codexloop/commit/b375f71ba5ebda62f178bdc39bb619418932dedf))
|
|
17
|
+
|
|
18
|
+
## [0.3.0](https://github.com/adammatthewsteinberger/codexloop/compare/v0.2.0...v0.3.0) (2026-08-16)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* add a -v/-q verbosity ladder and third-party log control ([b58dfc0](https://github.com/adammatthewsteinberger/codexloop/commit/b58dfc017ce9af34af07cb390ea9a8efd67435d3))
|
|
24
|
+
* add capacity forecasting (measurement only, disabled by default) ([c2a362b](https://github.com/adammatthewsteinberger/codexloop/commit/c2a362bcbd111e7f87e5fb2534eb1687e50dc42d))
|
|
25
|
+
* add the wind-down decision to the run loop state machine ([033b5b2](https://github.com/adammatthewsteinberger/codexloop/commit/033b5b2ecece721832f31cd08e103738c193c812))
|
|
26
|
+
* let the caller name a run with --run-id ([e22c2d0](https://github.com/adammatthewsteinberger/codexloop/commit/e22c2d05c03db5be84ecbbd544da418130c1023c))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* **tests:** remove residual SHA-collision flake in savepoints test ([#20](https://github.com/adammatthewsteinberger/codexloop/issues/20)) ([b375f71](https://github.com/adammatthewsteinberger/codexloop/commit/b375f71ba5ebda62f178bdc39bb619418932dedf))
|
|
32
|
+
|
|
33
|
+
## [0.2.0](https://github.com/adammatthewsteinberger/codexloop/compare/v0.1.1...v0.2.0) (2026-08-14)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
* add app-server rate-limit probe client ([a30ef93](https://github.com/adammatthewsteinberger/codexloop/commit/a30ef9377685ef9aea8f5096e1759b0f6293574e))
|
|
39
|
+
* add application ports and fakes ([33e721d](https://github.com/adammatthewsteinberger/codexloop/commit/33e721d0dab21b38c614ab71ea7c3e47a8126fb3))
|
|
40
|
+
* add autonomous runner and run/resume use cases ([bd36f45](https://github.com/adammatthewsteinberger/codexloop/commit/bd36f457548c5969f0fd37453c2d1ab5727d3302))
|
|
41
|
+
* add backoff and adaptive wait policy ([43c70c6](https://github.com/adammatthewsteinberger/codexloop/commit/43c70c68396255e10c61907497c53dd0d1c2ba63))
|
|
42
|
+
* add bootstrap and core CLI commands ([6b6aafc](https://github.com/adammatthewsteinberger/codexloop/commit/6b6aafc94f8d2513282389f154682b1b5a97bcee))
|
|
43
|
+
* add capacity value objects ([1aa3fed](https://github.com/adammatthewsteinberger/codexloop/commit/1aa3fede743d6c5db518f869d03826788c64da5b))
|
|
44
|
+
* add clock, logging, config, rundir, state, and lock adapters ([8f7e4ad](https://github.com/adammatthewsteinberger/codexloop/commit/8f7e4ad1aad0f9a754e7ff5777898bfe5a35c5cd))
|
|
45
|
+
* add codex argv builder ([42ab842](https://github.com/adammatthewsteinberger/codexloop/commit/42ab8426e676b0c6b59bb655bfc94e4a607338ba))
|
|
46
|
+
* add control plane, savepoints, and ops CLI ([512e03f](https://github.com/adammatthewsteinberger/codexloop/commit/512e03f24eddf226425326b992eacc4732f1bc7b))
|
|
47
|
+
* add ephemeral read-only exec capacity probe ([427620b](https://github.com/adammatthewsteinberger/codexloop/commit/427620bda645389caf571bcef010d269d3457093))
|
|
48
|
+
* add error hierarchy and OpenAI error-code taxonomy ([1bf5aa2](https://github.com/adammatthewsteinberger/codexloop/commit/1bf5aa2f2805c80aeba0f37fbe6da1dcb4a59585))
|
|
49
|
+
* add generated OpenAI REST CLI surface with drift gate ([53320f8](https://github.com/adammatthewsteinberger/codexloop/commit/53320f82512869b43075d6eeaf3f6fe73a06a3dd))
|
|
50
|
+
* add optional app-server gateway, stream UI, docs, and release scaffolding ([23bfddf](https://github.com/adammatthewsteinberger/codexloop/commit/23bfddfb169cfb37e8fe60a9a80bd7f9b644bba9))
|
|
51
|
+
* add plan, budget, session, profile, approval, and control types ([07a8188](https://github.com/adammatthewsteinberger/codexloop/commit/07a8188207fa6fbac5f85114d891b266b6be1bf9))
|
|
52
|
+
* add read-only CODEX_HOME rollout tail ([071d6ab](https://github.com/adammatthewsteinberger/codexloop/commit/071d6abe526935893d7d330909e96a308e5203b2))
|
|
53
|
+
* add run-loop state machine ([582144f](https://github.com/adammatthewsteinberger/codexloop/commit/582144fcd2b5d3c327f6af36c74307a9a8818966))
|
|
54
|
+
* add scripted system harness and test-agent gate ([68a7ebf](https://github.com/adammatthewsteinberger/codexloop/commit/68a7ebf9483013f5e7fae4ff98ff2b0f5da843f0))
|
|
55
|
+
* add three-layer completion evaluation ([eee2cc3](https://github.com/adammatthewsteinberger/codexloop/commit/eee2cc3a70562126c438e1a1ba842abca9aa0db6))
|
|
56
|
+
* classify turn signals into capacity states ([f7c4162](https://github.com/adammatthewsteinberger/codexloop/commit/f7c4162048b62f83a7b7ea3f99474605f18376ef))
|
|
57
|
+
* implement codexloop M1–M5 (onion runner + REST + docs) ([1dbef91](https://github.com/adammatthewsteinberger/codexloop/commit/1dbef9118097d8b8210f6a770df8c4c05956f6ce))
|
|
58
|
+
* parse codex exec JSONL events ([1cdc76c](https://github.com/adammatthewsteinberger/codexloop/commit/1cdc76c754f0e0f023f7dc94472be59f9776d3f5))
|
|
59
|
+
* supervise codex subprocess with concurrent pumps ([1c95f6e](https://github.com/adammatthewsteinberger/codexloop/commit/1c95f6e6fe628daefe0256e5ba5fb921bfd595a5))
|
|
60
|
+
* translate JSONL and drive codex exec gateway ([6a1842c](https://github.com/adammatthewsteinberger/codexloop/commit/6a1842c3bab3b9eb57d052b2bb8f1c45b919b69f))
|
|
61
|
+
* wire composite capacity probe and adaptive wait loop ([ab682b1](https://github.com/adammatthewsteinberger/codexloop/commit/ab682b16130829e3ae7a523597213c33509dec22))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Bug Fixes
|
|
65
|
+
|
|
66
|
+
* jitter throttle waits above Retry-After ([666a4e6](https://github.com/adammatthewsteinberger/codexloop/commit/666a4e6c3d73f277946e866d33866091c225e1c8))
|
|
67
|
+
* only break session locks for known-dead pids ([712b0f4](https://github.com/adammatthewsteinberger/codexloop/commit/712b0f4a4b25d83ba27c0ca53d8278e6961efbd9))
|
|
68
|
+
* pin release-please to main ([4c974a2](https://github.com/adammatthewsteinberger/codexloop/commit/4c974a243f98d0790325929fd124c4aca72f04f7))
|
|
69
|
+
* pin release-please to main and Node 24 action ([cf19789](https://github.com/adammatthewsteinberger/codexloop/commit/cf19789c9ed4fc179f88ef6176f8b05859d05cb8))
|
|
70
|
+
* preserve remaining work across capacity-rejected turns ([d2d10c3](https://github.com/adammatthewsteinberger/codexloop/commit/d2d10c36a93084a36f48509433d9bb6865172fde))
|
|
71
|
+
* resolve all-digit SHA prefixes as save-point SHAs ([43cdde7](https://github.com/adammatthewsteinberger/codexloop/commit/43cdde7d5f65910c06ef6273e64987a391ce0488))
|
|
72
|
+
* seal onion contracts and order drain before signals ([cecf827](https://github.com/adammatthewsteinberger/codexloop/commit/cecf827e841d11df0fb34c71724415970da3ab7d))
|
|
73
|
+
* stabilize CI help and process-group cancel tests ([3fe2c6d](https://github.com/adammatthewsteinberger/codexloop/commit/3fe2c6d09f94adb0de528a74364a0d9d177ee77b))
|
|
74
|
+
* terminate fatals, apply mid-run controls, harden ops edges ([9171835](https://github.com/adammatthewsteinberger/codexloop/commit/91718359a07f5e25ffd1366c7ea8bbfba51b0a01))
|
|
75
|
+
* treat ControlCommand as the inbox union and wrap parse errors ([0885204](https://github.com/adammatthewsteinberger/codexloop/commit/08852040d2a48a14eb5b7b750fa5d02bb9314e4b))
|
|
76
|
+
* unstick version CI and keep TestPyPI on develop ([a4cf78e](https://github.com/adammatthewsteinberger/codexloop/commit/a4cf78eb32a622af03f707a5654c8da708a81f83))
|
|
77
|
+
* version CI + TestPyPI only from develop ([01d7695](https://github.com/adammatthewsteinberger/codexloop/commit/01d7695de87849b949ffd6e275b1f79126f9f2c6))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Documentation
|
|
81
|
+
|
|
82
|
+
* deploy MkDocs site to GitHub Pages ([bce3384](https://github.com/adammatthewsteinberger/codexloop/commit/bce33843a1eb7f2579fea6d895b9966abcf5f11e))
|
|
83
|
+
* GitHub Pages MkDocs site ([e1c286b](https://github.com/adammatthewsteinberger/codexloop/commit/e1c286bef14b63f5b337548eb99bad94b917f21a))
|
|
84
|
+
|
|
85
|
+
## [0.1.1](https://github.com/adammatthewsteinberger/codexloop/compare/v0.1.0...v0.1.1) (2026-08-14)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Bug Fixes
|
|
89
|
+
|
|
90
|
+
* pin release-please to main ([4c974a2](https://github.com/adammatthewsteinberger/codexloop/commit/4c974a243f98d0790325929fd124c4aca72f04f7))
|
|
91
|
+
* pin release-please to main and Node 24 action ([cf19789](https://github.com/adammatthewsteinberger/codexloop/commit/cf19789c9ed4fc179f88ef6176f8b05859d05cb8))
|
|
92
|
+
* unstick version CI and keep TestPyPI on develop ([a4cf78e](https://github.com/adammatthewsteinberger/codexloop/commit/a4cf78eb32a622af03f707a5654c8da708a81f83))
|
|
93
|
+
* version CI + TestPyPI only from develop ([01d7695](https://github.com/adammatthewsteinberger/codexloop/commit/01d7695de87849b949ffd6e275b1f79126f9f2c6))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
### Documentation
|
|
97
|
+
|
|
98
|
+
* deploy MkDocs site to GitHub Pages ([bce3384](https://github.com/adammatthewsteinberger/codexloop/commit/bce33843a1eb7f2579fea6d895b9966abcf5f11e))
|
|
99
|
+
* GitHub Pages MkDocs site ([e1c286b](https://github.com/adammatthewsteinberger/codexloop/commit/e1c286bef14b63f5b337548eb99bad94b917f21a))
|
|
100
|
+
|
|
101
|
+
## 0.1.0 (2026-08-13)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
### Features
|
|
105
|
+
|
|
106
|
+
* add app-server rate-limit probe client ([a30ef93](https://github.com/adammatthewsteinberger/codexloop/commit/a30ef9377685ef9aea8f5096e1759b0f6293574e))
|
|
107
|
+
* add application ports and fakes ([33e721d](https://github.com/adammatthewsteinberger/codexloop/commit/33e721d0dab21b38c614ab71ea7c3e47a8126fb3))
|
|
108
|
+
* add autonomous runner and run/resume use cases ([bd36f45](https://github.com/adammatthewsteinberger/codexloop/commit/bd36f457548c5969f0fd37453c2d1ab5727d3302))
|
|
109
|
+
* add backoff and adaptive wait policy ([43c70c6](https://github.com/adammatthewsteinberger/codexloop/commit/43c70c68396255e10c61907497c53dd0d1c2ba63))
|
|
110
|
+
* add bootstrap and core CLI commands ([6b6aafc](https://github.com/adammatthewsteinberger/codexloop/commit/6b6aafc94f8d2513282389f154682b1b5a97bcee))
|
|
111
|
+
* add capacity value objects ([1aa3fed](https://github.com/adammatthewsteinberger/codexloop/commit/1aa3fede743d6c5db518f869d03826788c64da5b))
|
|
112
|
+
* add clock, logging, config, rundir, state, and lock adapters ([8f7e4ad](https://github.com/adammatthewsteinberger/codexloop/commit/8f7e4ad1aad0f9a754e7ff5777898bfe5a35c5cd))
|
|
113
|
+
* add codex argv builder ([42ab842](https://github.com/adammatthewsteinberger/codexloop/commit/42ab8426e676b0c6b59bb655bfc94e4a607338ba))
|
|
114
|
+
* add control plane, savepoints, and ops CLI ([512e03f](https://github.com/adammatthewsteinberger/codexloop/commit/512e03f24eddf226425326b992eacc4732f1bc7b))
|
|
115
|
+
* add ephemeral read-only exec capacity probe ([427620b](https://github.com/adammatthewsteinberger/codexloop/commit/427620bda645389caf571bcef010d269d3457093))
|
|
116
|
+
* add error hierarchy and OpenAI error-code taxonomy ([1bf5aa2](https://github.com/adammatthewsteinberger/codexloop/commit/1bf5aa2f2805c80aeba0f37fbe6da1dcb4a59585))
|
|
117
|
+
* add generated OpenAI REST CLI surface with drift gate ([53320f8](https://github.com/adammatthewsteinberger/codexloop/commit/53320f82512869b43075d6eeaf3f6fe73a06a3dd))
|
|
118
|
+
* add optional app-server gateway, stream UI, docs, and release scaffolding ([23bfddf](https://github.com/adammatthewsteinberger/codexloop/commit/23bfddfb169cfb37e8fe60a9a80bd7f9b644bba9))
|
|
119
|
+
* add plan, budget, session, profile, approval, and control types ([07a8188](https://github.com/adammatthewsteinberger/codexloop/commit/07a8188207fa6fbac5f85114d891b266b6be1bf9))
|
|
120
|
+
* add read-only CODEX_HOME rollout tail ([071d6ab](https://github.com/adammatthewsteinberger/codexloop/commit/071d6abe526935893d7d330909e96a308e5203b2))
|
|
121
|
+
* add run-loop state machine ([582144f](https://github.com/adammatthewsteinberger/codexloop/commit/582144fcd2b5d3c327f6af36c74307a9a8818966))
|
|
122
|
+
* add scripted system harness and test-agent gate ([68a7ebf](https://github.com/adammatthewsteinberger/codexloop/commit/68a7ebf9483013f5e7fae4ff98ff2b0f5da843f0))
|
|
123
|
+
* add three-layer completion evaluation ([eee2cc3](https://github.com/adammatthewsteinberger/codexloop/commit/eee2cc3a70562126c438e1a1ba842abca9aa0db6))
|
|
124
|
+
* classify turn signals into capacity states ([f7c4162](https://github.com/adammatthewsteinberger/codexloop/commit/f7c4162048b62f83a7b7ea3f99474605f18376ef))
|
|
125
|
+
* implement codexloop M1–M5 (onion runner + REST + docs) ([1dbef91](https://github.com/adammatthewsteinberger/codexloop/commit/1dbef9118097d8b8210f6a770df8c4c05956f6ce))
|
|
126
|
+
* parse codex exec JSONL events ([1cdc76c](https://github.com/adammatthewsteinberger/codexloop/commit/1cdc76c754f0e0f023f7dc94472be59f9776d3f5))
|
|
127
|
+
* supervise codex subprocess with concurrent pumps ([1c95f6e](https://github.com/adammatthewsteinberger/codexloop/commit/1c95f6e6fe628daefe0256e5ba5fb921bfd595a5))
|
|
128
|
+
* translate JSONL and drive codex exec gateway ([6a1842c](https://github.com/adammatthewsteinberger/codexloop/commit/6a1842c3bab3b9eb57d052b2bb8f1c45b919b69f))
|
|
129
|
+
* wire composite capacity probe and adaptive wait loop ([ab682b1](https://github.com/adammatthewsteinberger/codexloop/commit/ab682b16130829e3ae7a523597213c33509dec22))
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
### Bug Fixes
|
|
133
|
+
|
|
134
|
+
* jitter throttle waits above Retry-After ([666a4e6](https://github.com/adammatthewsteinberger/codexloop/commit/666a4e6c3d73f277946e866d33866091c225e1c8))
|
|
135
|
+
* only break session locks for known-dead pids ([712b0f4](https://github.com/adammatthewsteinberger/codexloop/commit/712b0f4a4b25d83ba27c0ca53d8278e6961efbd9))
|
|
136
|
+
* preserve remaining work across capacity-rejected turns ([d2d10c3](https://github.com/adammatthewsteinberger/codexloop/commit/d2d10c36a93084a36f48509433d9bb6865172fde))
|
|
137
|
+
* seal onion contracts and order drain before signals ([cecf827](https://github.com/adammatthewsteinberger/codexloop/commit/cecf827e841d11df0fb34c71724415970da3ab7d))
|
|
138
|
+
* stabilize CI help and process-group cancel tests ([3fe2c6d](https://github.com/adammatthewsteinberger/codexloop/commit/3fe2c6d09f94adb0de528a74364a0d9d177ee77b))
|
|
139
|
+
* terminate fatals, apply mid-run controls, harden ops edges ([9171835](https://github.com/adammatthewsteinberger/codexloop/commit/91718359a07f5e25ffd1366c7ea8bbfba51b0a01))
|
|
140
|
+
* treat ControlCommand as the inbox union and wrap parse errors ([0885204](https://github.com/adammatthewsteinberger/codexloop/commit/08852040d2a48a14eb5b7b750fa5d02bb9314e4b))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codexloop
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Onion-architected, autonomous OpenAI Codex session runner — never blocks on a human, distinguishes rate limits from exhausted credits, and resumes safely across usage windows.
|
|
5
5
|
Project-URL: Homepage, https://github.com/adammatthewsteinberger/codexloop
|
|
6
6
|
Project-URL: Repository, https://github.com/adammatthewsteinberger/codexloop
|
|
@@ -56,18 +56,26 @@ Autonomous OpenAI Codex / GPT session runner. Same job as
|
|
|
56
56
|
a human, and never treat `insufficient_quota` / billing as a waitable
|
|
57
57
|
`rate_limit_exceeded` window.
|
|
58
58
|
|
|
59
|
-
**
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
**Docs:** https://adammatthewsteinberger.github.io/codexloop/
|
|
60
|
+
|
|
61
|
+
**Status:** M1–M5 on PyPI (`0.1.0`) — onion core, exec gateway, capacity probes,
|
|
62
|
+
control plane, generated REST CLI, optional app-server transport with exec
|
|
63
|
+
fallback. MIT-licensed; author Adam Matthew Steinberger.
|
|
62
64
|
|
|
63
65
|
## Install
|
|
64
66
|
|
|
65
67
|
```bash
|
|
66
|
-
pip install
|
|
68
|
+
pip install codexloop
|
|
67
69
|
codexloop --version
|
|
68
70
|
codexloop doctor
|
|
69
71
|
```
|
|
70
72
|
|
|
73
|
+
For local development:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install -e ".[dev]"
|
|
77
|
+
```
|
|
78
|
+
|
|
71
79
|
## Quick start
|
|
72
80
|
|
|
73
81
|
```bash
|
|
@@ -5,18 +5,26 @@ Autonomous OpenAI Codex / GPT session runner. Same job as
|
|
|
5
5
|
a human, and never treat `insufficient_quota` / billing as a waitable
|
|
6
6
|
`rate_limit_exceeded` window.
|
|
7
7
|
|
|
8
|
-
**
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
**Docs:** https://adammatthewsteinberger.github.io/codexloop/
|
|
9
|
+
|
|
10
|
+
**Status:** M1–M5 on PyPI (`0.1.0`) — onion core, exec gateway, capacity probes,
|
|
11
|
+
control plane, generated REST CLI, optional app-server transport with exec
|
|
12
|
+
fallback. MIT-licensed; author Adam Matthew Steinberger.
|
|
11
13
|
|
|
12
14
|
## Install
|
|
13
15
|
|
|
14
16
|
```bash
|
|
15
|
-
pip install
|
|
17
|
+
pip install codexloop
|
|
16
18
|
codexloop --version
|
|
17
19
|
codexloop doctor
|
|
18
20
|
```
|
|
19
21
|
|
|
22
|
+
For local development:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install -e ".[dev]"
|
|
26
|
+
```
|
|
27
|
+
|
|
20
28
|
## Quick start
|
|
21
29
|
|
|
22
30
|
```bash
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Publishing
|
|
2
|
+
|
|
3
|
+
`codexloop` ships via [Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
|
|
4
|
+
(OIDC). No long-lived PyPI API tokens are stored in GitHub.
|
|
5
|
+
|
|
6
|
+
## Environments
|
|
7
|
+
|
|
8
|
+
| GitHub Environment | Index | Branch / workflow |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| `testpypi` | https://test.pypi.org | **`develop`** → `.github/workflows/publish-testpypi.yml` |
|
|
11
|
+
| `pypi` | https://pypi.org | **`main`** → `.github/workflows/release-please.yml` (`publish-pypi`) |
|
|
12
|
+
|
|
13
|
+
Create them once (repo **Settings → Environments**), or via API as in the
|
|
14
|
+
setup checklist below.
|
|
15
|
+
|
|
16
|
+
## One-time Trusted Publisher setup
|
|
17
|
+
|
|
18
|
+
Do this **before** the first upload (pending publisher), signed in as the PyPI
|
|
19
|
+
owner account.
|
|
20
|
+
|
|
21
|
+
### TestPyPI
|
|
22
|
+
|
|
23
|
+
1. Open https://test.pypi.org/manage/account/publishing/
|
|
24
|
+
2. Add a pending publisher:
|
|
25
|
+
- **PyPI Project Name:** `codexloop`
|
|
26
|
+
- **Owner:** `adammatthewsteinberger`
|
|
27
|
+
- **Repository name:** `codexloop`
|
|
28
|
+
- **Workflow name:** `publish-testpypi.yml`
|
|
29
|
+
- **Environment name:** `testpypi`
|
|
30
|
+
|
|
31
|
+
### PyPI
|
|
32
|
+
|
|
33
|
+
1. Open https://pypi.org/manage/account/publishing/
|
|
34
|
+
2. Add a pending publisher:
|
|
35
|
+
- **PyPI Project Name:** `codexloop`
|
|
36
|
+
- **Owner:** `adammatthewsteinberger`
|
|
37
|
+
- **Repository name:** `codexloop`
|
|
38
|
+
- **Workflow name:** `release-please.yml`
|
|
39
|
+
- **Environment name:** `pypi`
|
|
40
|
+
|
|
41
|
+
## Release flow
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
feat/* ──PR──► develop ──auto TestPyPI──► main ──release-please──► PyPI
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
1. Land work on `develop`. Every push to `develop` runs **Publish TestPyPI**
|
|
48
|
+
(`publish-testpypi.yml`). Do not publish TestPyPI from `main`.
|
|
49
|
+
2. Smoke-install from TestPyPI if needed:
|
|
50
|
+
`pip install -i https://test.pypi.org/simple/ --pre codexloop`.
|
|
51
|
+
3. Merge `develop` → `main` when ready.
|
|
52
|
+
4. `release-please` opens a release PR against **`main` only**
|
|
53
|
+
(`target-branch: main` in `.github/workflows/release-please.yml`).
|
|
54
|
+
5. Squash-merge the release PR → GitHub Release + tag → `publish-pypi`
|
|
55
|
+
uploads to **PyPI**. Do not open or merge `chore(develop): release …` PRs.
|
|
56
|
+
|
|
57
|
+
Manual PyPI retry (Trusted Publishing, `main` / tagged release only):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
gh workflow run release-please.yml -f publish_to_pypi=true
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Manual TestPyPI from `develop`:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
gh workflow run "Publish TestPyPI" --ref develop
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Local dry-run (no upload)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
python -m build
|
|
73
|
+
twine check --strict dist/*
|
|
74
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
site_name: codexloop
|
|
2
|
+
site_description: Autonomous OpenAI Codex session runner
|
|
3
|
+
site_url: https://adammatthewsteinberger.github.io/codexloop/
|
|
4
|
+
repo_url: https://github.com/adammatthewsteinberger/codexloop
|
|
5
|
+
repo_name: adammatthewsteinberger/codexloop
|
|
6
|
+
theme:
|
|
7
|
+
name: material
|
|
8
|
+
features:
|
|
9
|
+
- navigation.sections
|
|
10
|
+
- content.code.copy
|
|
11
|
+
markdown_extensions:
|
|
12
|
+
- admonition
|
|
13
|
+
- pymdownx.details
|
|
14
|
+
- pymdownx.superfences
|
|
15
|
+
- toc:
|
|
16
|
+
permalink: true
|
|
17
|
+
exclude_docs: |
|
|
18
|
+
plans/**
|
|
19
|
+
superpowers/**
|
|
20
|
+
nav:
|
|
21
|
+
- Home: index.md
|
|
22
|
+
- Getting started: getting-started.md
|
|
23
|
+
- Guides:
|
|
24
|
+
- REST API surface: guides/rest-api-surface.md
|
|
25
|
+
- Architecture:
|
|
26
|
+
- Overview: architecture/index.md
|
|
27
|
+
- ADRs:
|
|
28
|
+
- Index: architecture/adr/index.md
|
|
29
|
+
- "0001 Onion import-linter": architecture/adr/0001-onion-import-linter.md
|
|
30
|
+
- "0002 Subprocess codex exec": architecture/adr/0002-subprocess-codex-exec.md
|
|
31
|
+
- "0003 Credits exhausted": architecture/adr/0003-credits-exhausted.md
|
|
32
|
+
- "0004 Adaptive probe loop": architecture/adr/0004-adaptive-probe-loop.md
|
|
33
|
+
- "0005 Layered capacity probe": architecture/adr/0005-layered-capacity-probe.md
|
|
34
|
+
- "0006 Generated OpenAI REST": architecture/adr/0006-generated-openai-rest.md
|
|
35
|
+
- "0007 Default approval/sandbox": architecture/adr/0007-default-approval-sandbox.md
|
|
36
|
+
- "0008 Policy via -c flags": architecture/adr/0008-policy-via-c-flags.md
|
|
37
|
+
- "0009 Optional app-server": architecture/adr/0009-optional-app-server.md
|
|
38
|
+
- "0010 Rollout best-effort": architecture/adr/0010-rollout-best-effort.md
|
|
39
|
+
- "0011 Never consume resets": architecture/adr/0011-never-consume-resets.md
|
|
40
|
+
- "0012 Minimum Codex version": architecture/adr/0012-minimum-codex-version.md
|
|
41
|
+
- Reference: reference/cli.md
|
|
42
|
+
- Contributing: contributing.md
|
|
43
|
+
- Publishing: publishing.md
|
|
44
|
+
strict: true
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codexloop"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Onion-architected, autonomous OpenAI Codex session runner — never blocks on a human, distinguishes rate limits from exhausted credits, and resumes safely across usage windows."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -173,3 +173,16 @@ forbidden_modules = [
|
|
|
173
173
|
"docker",
|
|
174
174
|
"sqlalchemy",
|
|
175
175
|
]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
[[tool.importlinter.contracts]]
|
|
179
|
+
name = "Interfaces declare seams, never consume them"
|
|
180
|
+
type = "forbidden"
|
|
181
|
+
source_modules = ["codexloop.application.interfaces"]
|
|
182
|
+
forbidden_modules = [
|
|
183
|
+
"codexloop.application.runner",
|
|
184
|
+
"codexloop.application.usecases",
|
|
185
|
+
"codexloop.infrastructure",
|
|
186
|
+
"codexloop.cli",
|
|
187
|
+
"codexloop.bootstrap",
|
|
188
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Application interfaces -- every seam implemented by infrastructure/ and
|
|
2
|
+
never imported from it.
|
|
3
|
+
|
|
4
|
+
One module per collaborator family so a reader finds a seam by what it does
|
|
5
|
+
rather than by scrolling one long file. `application/ports.py` re-exports
|
|
6
|
+
this package unchanged, so existing imports keep working.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from codexloop.application.interfaces.agent import (
|
|
12
|
+
AgentGateway,
|
|
13
|
+
CapacityProbe,
|
|
14
|
+
RunResources,
|
|
15
|
+
ThreadCatalog,
|
|
16
|
+
)
|
|
17
|
+
from codexloop.application.interfaces.api import (
|
|
18
|
+
ApiGateway,
|
|
19
|
+
)
|
|
20
|
+
from codexloop.application.interfaces.control import (
|
|
21
|
+
ControlInbox,
|
|
22
|
+
RunControl,
|
|
23
|
+
)
|
|
24
|
+
from codexloop.application.interfaces.doctor import (
|
|
25
|
+
DoctorCheck,
|
|
26
|
+
DoctorEnvironment,
|
|
27
|
+
DoctorReport,
|
|
28
|
+
)
|
|
29
|
+
from codexloop.application.interfaces.observability import (
|
|
30
|
+
AuditLog,
|
|
31
|
+
Logger,
|
|
32
|
+
Notifier,
|
|
33
|
+
ProgressReporter,
|
|
34
|
+
RunEventSink,
|
|
35
|
+
StateBus,
|
|
36
|
+
)
|
|
37
|
+
from codexloop.application.interfaces.permissions import (
|
|
38
|
+
PermissionMode,
|
|
39
|
+
)
|
|
40
|
+
from codexloop.application.interfaces.storage import (
|
|
41
|
+
RunSnapshotSink,
|
|
42
|
+
RunStateStore,
|
|
43
|
+
SavePointStore,
|
|
44
|
+
SessionLock,
|
|
45
|
+
)
|
|
46
|
+
from codexloop.application.interfaces.system import (
|
|
47
|
+
Clock,
|
|
48
|
+
Sleeper,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
__all__ = [
|
|
52
|
+
"AgentGateway",
|
|
53
|
+
"ApiGateway",
|
|
54
|
+
"AuditLog",
|
|
55
|
+
"CapacityProbe",
|
|
56
|
+
"Clock",
|
|
57
|
+
"ControlInbox",
|
|
58
|
+
"DoctorCheck",
|
|
59
|
+
"DoctorEnvironment",
|
|
60
|
+
"DoctorReport",
|
|
61
|
+
"Logger",
|
|
62
|
+
"Notifier",
|
|
63
|
+
"PermissionMode",
|
|
64
|
+
"ProgressReporter",
|
|
65
|
+
"RunControl",
|
|
66
|
+
"RunEventSink",
|
|
67
|
+
"RunResources",
|
|
68
|
+
"RunSnapshotSink",
|
|
69
|
+
"RunStateStore",
|
|
70
|
+
"SavePointStore",
|
|
71
|
+
"SessionLock",
|
|
72
|
+
"Sleeper",
|
|
73
|
+
"StateBus",
|
|
74
|
+
"ThreadCatalog",
|
|
75
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""The vendor session seam: sending turns, probing capacity, enumerating
|
|
2
|
+
sessions, and the run-scoped resources attached to one."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from collections.abc import Mapping, Sequence
|
|
7
|
+
from typing import Protocol, runtime_checkable
|
|
8
|
+
|
|
9
|
+
from codexloop.application.dto import ProbeResult, TurnOutcome
|
|
10
|
+
from codexloop.application.interfaces.permissions import PermissionMode
|
|
11
|
+
from codexloop.domain.model_profile import ModelEffortProfile
|
|
12
|
+
from codexloop.domain.session import ThreadRef
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@runtime_checkable
|
|
16
|
+
class AgentGateway(Protocol):
|
|
17
|
+
"""Vendor-agnostic agent session (exec and app-server adapters implement this)."""
|
|
18
|
+
|
|
19
|
+
async def send_turn(self, prompt: str) -> TurnOutcome: ...
|
|
20
|
+
async def close(self) -> None: ...
|
|
21
|
+
async def set_profile(self, profile: ModelEffortProfile) -> None: ...
|
|
22
|
+
async def set_permission_mode(self, mode: PermissionMode) -> None: ...
|
|
23
|
+
async def set_cwd(self, path: str) -> None: ...
|
|
24
|
+
async def set_session_resources(self, resources: Mapping[str, object]) -> None: ...
|
|
25
|
+
def resolve_tool_approval(self, request_id: str, *, allow: bool, reason: str = "") -> bool: ...
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@runtime_checkable
|
|
29
|
+
class CapacityProbe(Protocol):
|
|
30
|
+
async def probe(self) -> ProbeResult: ...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@runtime_checkable
|
|
34
|
+
class ThreadCatalog(Protocol):
|
|
35
|
+
"""Our run registry keyed by ``thread_id``, not vendor session discovery."""
|
|
36
|
+
|
|
37
|
+
def list_threads(self) -> Sequence[ThreadRef]: ...
|
|
38
|
+
def get(self, thread_id: str) -> ThreadRef | None: ...
|
|
39
|
+
def record(self, ref: ThreadRef) -> None: ...
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@runtime_checkable
|
|
43
|
+
class RunResources(Protocol):
|
|
44
|
+
"""Placeholder for run-scoped attachments applied mid-run."""
|
|
45
|
+
|
|
46
|
+
def as_payload(self) -> Mapping[str, object]: ...
|