petfishframework 0.5.2__tar.gz → 1.0.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.
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.github/workflows/ci.yml +28 -2
- petfishframework-1.0.0/.sisyphus/plans/v1.0.0-plan.md +211 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/CHANGELOG.md +69 -0
- petfishframework-1.0.0/Dockerfile +25 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/PKG-INFO +10 -10
- {petfishframework-0.5.2 → petfishframework-1.0.0}/README.md +3 -3
- {petfishframework-0.5.2 → petfishframework-1.0.0}/SECURITY.md +3 -3
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/api-stability.md +18 -13
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/api.md +1 -1
- {petfishframework-0.5.2 → petfishframework-1.0.0}/pyproject.toml +18 -6
- petfishframework-1.0.0/src/petfishframework/__init__.py +80 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/config.py +8 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/__init__.py +15 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/agent.py +2 -2
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/environment.py +282 -240
- petfishframework-1.0.0/src/petfishframework/core/errors.py +35 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/events.py +36 -8
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/credentials/broker.py +23 -2
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/credentials/token.py +19 -3
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/client.py +10 -3
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/server.py +5 -2
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/wrapper.py +5 -2
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/retry.py +4 -4
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/base.py +5 -2
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/idempotency.py +35 -14
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/rate_limiter.py +24 -17
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/sandbox.py +9 -5
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/schema_validator.py +29 -1
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_api_edge_cases.py +2 -1
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_api_public_surface.py +93 -24
- petfishframework-1.0.0/tests/test_ci_markers.py +67 -0
- petfishframework-1.0.0/tests/test_config_validation.py +50 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_credential_broker.py +50 -0
- petfishframework-1.0.0/tests/test_dockerfile.py +42 -0
- petfishframework-1.0.0/tests/test_environment_refactor.py +167 -0
- petfishframework-1.0.0/tests/test_event_emitter.py +167 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_main_entry.py +1 -1
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_mcp.py +3 -2
- petfishframework-1.0.0/tests/test_mypy_clean.py +19 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_rate_limiter.py +26 -0
- petfishframework-1.0.0/tests/test_tool_execution_errors.py +174 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_tool_idempotency.py +34 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/uv.lock +142 -13
- petfishframework-0.5.2/Dockerfile +0 -7
- petfishframework-0.5.2/src/petfishframework/__init__.py +0 -36
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.env.example +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.gitattributes +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.github/workflows/publish.yml +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.gitignore +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.sisyphus/plans/v0.1.6-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.sisyphus/plans/v0.2.0-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.sisyphus/plans/v0.3.0-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.sisyphus/plans/v0.4.0-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/.sisyphus/plans/v0.5.0-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/AGENTS.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/AGENTS.md.new +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/CONTRIBUTING.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/LICENSE +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/conftest.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docker-compose.yml +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/architecture.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/benchmark-results.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/deployment.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/development-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/development.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/enterprise-expense-demo.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_0_1_4_playground_recommendations.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_playground_report.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_production_readiness_roadmap.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_recommendations.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_1_6_playground_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_1_7_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_1_8_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_2_1_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_2_2_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_3_0_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_4_0_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/archives/petfishframework_v0_4_1_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/feedbacks/petfishframework_v0_5_1_review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/release-checklist.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/release-protocol.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/competitor-analysis/README.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/competitor-analysis/competitor-matrix.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/competitor-analysis/market-brief.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/competitor-analysis/positioning-map.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/competitor-analysis/swot-analysis.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/literature-review/inclusion-exclusion-criteria.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/literature-review/literature-matrix.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/literature-review/literature-review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/literature-review/search-strategy.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/research/reference-repos-absorption.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/skeleton-completeness-checklist.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/test-results-report.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/threat-model.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/usage-guide.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/docs/validation-roadmap.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/initialization-report.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/mcp/README.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/mcp/connection-checklist.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/mcp/mcp-config.example.json +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/opencode.json +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/qa/code-review-checklist.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/qa/qa-review.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/qa/qc-gate-decision.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/qa/test-plan.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/__main__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/compiled.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/contracts.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/conversation.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/session.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/structured.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/core/types.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/credentials/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/credentials/vault_adapter.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/allowlist.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/exceptions.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/risk_mapper.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/schema_pin.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/mcp/stdio_transport.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/models/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/models/anthropic.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/models/fake.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/models/openai.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/observability/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/observability/otel_sink.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/observability/siem_sink.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/observability/sinks.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/permissions/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/permissions/model.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/permissions/risk_policy.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/conditions.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/engine.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/hot_reload.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/rule.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/test_runner.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/policies/validator.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reasoning/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reasoning/lats.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reasoning/llm_plus_p.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reasoning/react.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reasoning/reflexion.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/audit_report.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/circuit_breaker.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/cost.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/cost_report.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/pass_at_k.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/replay.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/reliability/timeout.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/retrieval/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/retrieval/adaptive.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/retrieval/crag.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/retrieval/memory_store.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/agent_tool.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/calculator.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/governance.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/metadata_policy.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/path_planner.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/registry.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/src/petfishframework/tools/word_sorter.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tasks/backlog.md +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/integration/__init__.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/integration/test_anthropic_integration.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/integration/test_openai_integration.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/policies/enterprise-expense.tests.yaml +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_agent_tool.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_anthropic_adapter.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_api_agent_lifecycle.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_api_integration.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_api_type_safety.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_async.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_audit_report_v2.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_circuit_breaker.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_conversation.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_credential_integration.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_degrade.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_degrade_failclosed.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_enterprise_demo.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_lats_mcts.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_llm_plus_p_general.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_m2_m3_m4.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_mcp_allowlist.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_mcp_lifecycle.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_mcp_risk_mapping.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_mcp_schema_pin.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_mcp_server.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_openai_adapter.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_otel_sink.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_pass_at_k.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_permission_semantics.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_policy_hot_reload.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_quickstart_smoke.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_reflexion.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_replay.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_replay_rerun.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_replay_resume.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_retrieval.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_retry.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_risk_classification.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_sandbox.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_siem_export.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_skeleton.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_stdio_transport.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_streaming.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_structured.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_tool_metadata.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_tool_registry.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_tool_retry.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_tool_schema.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_tool_timeout.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_v016_semantics.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_v018.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_v019.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_v2_interface_compatibility.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_v2_lats.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_v2_llm_plus_p.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_vault_adapter.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_yaml_policy.py +0 -0
- {petfishframework-0.5.2 → petfishframework-1.0.0}/tests/test_yaml_policy_suite.py +0 -0
|
@@ -5,6 +5,9 @@ on:
|
|
|
5
5
|
branches: [master, main]
|
|
6
6
|
pull_request:
|
|
7
7
|
branches: [master, main]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "0 6 * * *"
|
|
10
|
+
workflow_dispatch:
|
|
8
11
|
|
|
9
12
|
jobs:
|
|
10
13
|
test:
|
|
@@ -28,9 +31,32 @@ jobs:
|
|
|
28
31
|
- name: Lint with ruff
|
|
29
32
|
run: uv run ruff check src/ tests/
|
|
30
33
|
|
|
34
|
+
- name: Type check
|
|
35
|
+
run: uv run mypy src/petfishframework
|
|
36
|
+
|
|
31
37
|
- name: Run tests
|
|
32
|
-
run: uv run pytest tests/ -q --tb=short
|
|
33
|
-
|
|
38
|
+
run: uv run pytest tests/ -q --tb=short -m "not integration"
|
|
39
|
+
|
|
40
|
+
integration:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
needs: test
|
|
43
|
+
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
uses: actions/setup-python@v5
|
|
49
|
+
with:
|
|
50
|
+
python-version: '3.12'
|
|
51
|
+
|
|
52
|
+
- name: Install dependencies
|
|
53
|
+
run: pip install uv && uv sync --all-extras
|
|
54
|
+
|
|
55
|
+
- name: Run integration tests
|
|
56
|
+
run: uv run pytest tests/ -m integration -v --tb=short
|
|
57
|
+
env:
|
|
58
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
59
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
34
60
|
|
|
35
61
|
docker-smoke:
|
|
36
62
|
runs-on: ubuntu-latest
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# petfishFramework v1.0.0 Production-Readiness Plan
|
|
2
|
+
|
|
3
|
+
> Target: ship v1.0.0 with all 14 audit gaps closed.
|
|
4
|
+
> Baseline: v0.5.2, 382 tests, ruff clean, Python ≥3.10.
|
|
5
|
+
> Approach: TDD先行,pre_release.py门禁,每gap一个atomic commit。
|
|
6
|
+
|
|
7
|
+
## 设计决策(已确认)
|
|
8
|
+
|
|
9
|
+
| ID | 决策 | 选择 |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| D1 | 公开API surface | 导出全部Stable API到`__init__.__all__`;promote FrameworkConfig到Stable |
|
|
12
|
+
| D2 | 线程安全范围 | EventEmitter/RateLimiter/IdempotencyStore + RuntimeEnvironment计数器加锁;Session保持单线程设计 |
|
|
13
|
+
| D3 | 异常层级 | ToolExecutionError → ToolSchemaError/ToolTimeoutError/ToolRateLimitError/ToolRetryExhaustedError/ToolInternalError;sanitized messages |
|
|
14
|
+
| D4 | RuntimeEnvironment重构 | 提取`_build_execution_plan`共享执行计划,消除sync/async重复,修复gate ordering bug |
|
|
15
|
+
| Q1 | FrameworkConfig tier | Promote to Stable(config surface小,B1验证后可冻结) |
|
|
16
|
+
| Q2 | mypy backlog | Fix便宜的错误,>15个非trivial error记为P2 follow-up,不阻塞v1.0 |
|
|
17
|
+
| Q3 | Coverage gate | v1.0 informational only,v1.1起hard gate(fail_under=80%) |
|
|
18
|
+
| Q4 | Temperature range | 0 ≤ temp ≤ 2 |
|
|
19
|
+
|
|
20
|
+
## 14个Gap验证状态
|
|
21
|
+
|
|
22
|
+
全部14项已通过源码阅读确认。附发现:
|
|
23
|
+
|
|
24
|
+
- **B1 — 隐性正确性bug(Gap 14的一部分)**:`call()` sync路径gate顺序 schema→idempotency→rate_limit;`call_async()` 是 schema→rate_limit→idempotency。Async路径让idempotency cache hit消耗rate-limit quota。D4重构修复。
|
|
25
|
+
- **B2 — badge drift**:pytest收集385,README badge写382。
|
|
26
|
+
|
|
27
|
+
| # | Gap | Severity | 主要文件 | 验证位置 |
|
|
28
|
+
|---|---|---|---|---|
|
|
29
|
+
| 1 | 公开API导出不匹配 | P0 | `__init__.py`, `api-stability.md` | 15 exports vs 30+ Stable |
|
|
30
|
+
| 2 | 线程安全 | P0 | `events.py`, `rate_limiter.py`, `idempotency.py`, `environment.py` | 无`threading.Lock` |
|
|
31
|
+
| 3 | 异常泄漏 | P0 | `environment.py:296,478`, `base.py:73`, `wrapper.py:41`, `sandbox.py:50`, `server.py:102` | `str(exc)`→ToolResult |
|
|
32
|
+
| 4 | FrameworkConfig无校验 | P0 | `config.py` | 无`__post_init__` |
|
|
33
|
+
| 5 | 无覆盖率工具 | P0 | `pyproject.toml` | 无`pytest-cov` |
|
|
34
|
+
| 6 | SECURITY.md过期 | P0 | `SECURITY.md` | 0.5.x missing |
|
|
35
|
+
| 7 | Dockerfile非生产级 | P0 | `Dockerfile` | root, no HEALTHCHECK |
|
|
36
|
+
| 8 | CredentialBroker安全 | P1 | `token.py:19`, `broker.py:64-69` | `_secret`可读, max_uses未强制 |
|
|
37
|
+
| 9 | 可选依赖无上限 | P1 | `pyproject.toml:49-53` | `>=` only |
|
|
38
|
+
| 10 | 集成测试CI跳过 | P1 | `ci.yml`, `tests/integration/*` | 无API key |
|
|
39
|
+
| 11 | mypy未强制 | P1 | `ci.yml` | 无mypy step |
|
|
40
|
+
| 12 | EventEmitter吞sink异常 | P1 | `events.py:57-61` | `except Exception: pass` |
|
|
41
|
+
| 13 | api-stability.md过时 | P1 | `api-stability.md` | serve_as_mcp/FrameworkConfig mismatch |
|
|
42
|
+
| 14 | RuntimeEnvironment 711行 | P1 | `environment.py:127-497` | call=190, call_async=180, gate-order bug |
|
|
43
|
+
|
|
44
|
+
## 依赖图
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Gap 5 (coverage) ──────────────────────────────► (enables measurement)
|
|
48
|
+
Gap 1 (API surface) ──► Gap 13 (api-stability doc)
|
|
49
|
+
Gap 6 (SECURITY) ─┐
|
|
50
|
+
Gap 9 (dep bounds) ├─ independent
|
|
51
|
+
Gap 4 (config valid.) ┘
|
|
52
|
+
Gap 8 (credentials) ──────────────────────────► independent
|
|
53
|
+
Gap 12 (sink swallow) ─► pairs with Gap 2 (events.py)
|
|
54
|
+
Gap 2 (thread safety):
|
|
55
|
+
standalone (events/rate_limiter/idempotency) ─► independent
|
|
56
|
+
environment.py portion ─► merge into Gap 14
|
|
57
|
+
Gap 3 (exception hierarchy) ──► Gap 14 (refactor consumes new errors)
|
|
58
|
+
Gap 7 (Dockerfile), Gap 10 (CI), Gap 11 (mypy) ─► infra, fully independent
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Phase分解(6个Wave)
|
|
62
|
+
|
|
63
|
+
### Wave A — Foundation(2项,并行)
|
|
64
|
+
- **A1 = Gap 5** — 覆盖率工具
|
|
65
|
+
- **A2 = Gap 1** — 公开API surface冻结
|
|
66
|
+
|
|
67
|
+
### Wave B — Quick/config修复(5项,并行;B5在A2后)
|
|
68
|
+
- **B1 = Gap 4** — FrameworkConfig验证器
|
|
69
|
+
- **B2 = Gap 9** — 依赖上限
|
|
70
|
+
- **B3 = Gap 6** — SECURITY.md
|
|
71
|
+
- **B4 = Gap 8** — CredentialBroker加固
|
|
72
|
+
- **B5 = Gap 13** — api-stability.md(A2后)
|
|
73
|
+
|
|
74
|
+
### Wave C — 错误处理(2项,并行不同文件)
|
|
75
|
+
- **C1 = Gap 3** — ToolExecutionError层级(新`errors.py` + 更新5个call site)
|
|
76
|
+
- **C2 = Gap 12 + Gap 2(events/rate_limiter/idempotency)** — sink-failure上报 + 独立锁
|
|
77
|
+
|
|
78
|
+
### Wave D — Environment整合(1项,C1后串行)
|
|
79
|
+
- **D1 = Gap 2(env) + Gap 14** — RuntimeEnvironment锁 + `_build_execution_plan`重构 + gate order修复
|
|
80
|
+
|
|
81
|
+
### Wave E — 基础设施(3项,并行)
|
|
82
|
+
- **E1 = Gap 7** — Dockerfile加固
|
|
83
|
+
- **E2 = Gap 10** — 集成测试CI
|
|
84
|
+
- **E3 = Gap 11** — mypy强制
|
|
85
|
+
|
|
86
|
+
### Wave F — 发布
|
|
87
|
+
- 版本号、CHANGELOG、badge、pre_release.py加固、tag
|
|
88
|
+
|
|
89
|
+
## Per-Gap TDD测试规范
|
|
90
|
+
|
|
91
|
+
### A1 / Gap 5 — 覆盖率工具
|
|
92
|
+
- `tests/test_coverage_config.py`:pytest-cov可导入;`[tool.coverage.run]` source=pkg;覆盖率>0%。
|
|
93
|
+
- v1.0 informational,不hard fail。
|
|
94
|
+
|
|
95
|
+
### A2 / Gap 1 — API surface冻结
|
|
96
|
+
- 硬化`tests/test_api_public_surface.py`:skip→assert;扩展TIER1_NAMES到完整frozen set。
|
|
97
|
+
- 新增`test_all_exports_in___all__`:`__all__`与实际importable一致。
|
|
98
|
+
- 新增`test_no_unstable_symbols_in_top_level`:top-level不含Experimental/Internal。
|
|
99
|
+
- **D1 frozen set(`__all__`)**:当前15个 + Session, RuntimeEnvironment, EventEmitter, Event, Step, Trajectory, Usage, PermissionPolicy, DefaultAllowPolicy, DenyByDefaultPolicy, Subject, Action, Resource, AccessContext, Decision, CredentialBroker, ScopedToken, pass_at_k, audit_report_from_session, AuditReport, Calculator, WordSorter, FakeModel, tool(decorator)。promote FrameworkConfig到Stable。
|
|
100
|
+
|
|
101
|
+
### B1 / Gap 4 — FrameworkConfig验证
|
|
102
|
+
- `tests/test_config_validation.py`:
|
|
103
|
+
- `timeout_s <= 0` → ValueError
|
|
104
|
+
- `default_temperature < 0 or > 2` → ValueError
|
|
105
|
+
- `default_max_tokens < 0` → ValueError;None OK
|
|
106
|
+
- `from_dict` invalid → raises
|
|
107
|
+
- valid defaults → 不回归
|
|
108
|
+
|
|
109
|
+
### B2 / Gap 9 — 依赖上限
|
|
110
|
+
- `tests/test_dependency_bounds.py`:解析pyproject.toml,每个optional dep有`>=X,<Y`格式。
|
|
111
|
+
- upper bound pin到当前known-good major:openai<2, anthropic<1, mcp<2。
|
|
112
|
+
|
|
113
|
+
### B3 / Gap 6 — SECURITY.md
|
|
114
|
+
- `tests/test_security_doc.py`:当前版本在Supported Versions表中标Active;至少一行security-only。
|
|
115
|
+
|
|
116
|
+
### B4 / Gap 8 — CredentialBroker
|
|
117
|
+
- `_secret`改为`__secret`(name-mangled),`get_secret()`为唯一读取入口。
|
|
118
|
+
- `validate_token`调用`token.use()`强制max_uses。
|
|
119
|
+
- 测试:`token._secret`→AttributeError;max_uses=1的token第二次validate→False;repr不含secret。
|
|
120
|
+
|
|
121
|
+
### B5 / Gap 13 — api-stability.md
|
|
122
|
+
- `tests/test_api_stability_doc.py`:top-level `__all__`与api-stability.md分类一致;serve_as_mcp非Internal;effective version=v1.0。
|
|
123
|
+
|
|
124
|
+
### C1 / Gap 3 — 异常层级
|
|
125
|
+
- `tests/test_tool_execution_errors.py`:
|
|
126
|
+
- 5个ToolExecutionError子类正确继承
|
|
127
|
+
- tool抛ValueError→ToolResult.is_error=True,message=sanitized(不含原始exception文本)
|
|
128
|
+
- schema violation→safe descriptive message
|
|
129
|
+
- timeout→ToolTimeoutError message含tool name+timeout值
|
|
130
|
+
- KeyboardInterrupt/SystemExit/AssertionError→propagate(不被catch)
|
|
131
|
+
|
|
132
|
+
### C2 / Gap 12 + Gap 2(non-env)
|
|
133
|
+
- `tests/test_event_emitter.py`:
|
|
134
|
+
- failing sink→emit `sink.error`事件(不静默pass)
|
|
135
|
+
- 其他sink仍收到event
|
|
136
|
+
- 2线程并发emit+subscribe→无RuntimeError/丢失
|
|
137
|
+
- `tests/test_rate_limiter.py`/`test_tool_idempotency.py`:并发访问测试
|
|
138
|
+
|
|
139
|
+
### D1 / Gap 2(env) + Gap 14
|
|
140
|
+
- `tests/test_environment_refactor.py`:
|
|
141
|
+
- **Gate order parity test**:sync和async路径idempotency cache hit不消耗rate-limit quota
|
|
142
|
+
- `_build_execution_plan`返回callable,所有effect正确执行
|
|
143
|
+
- 并发`query_model`计数一致
|
|
144
|
+
- 全部现有env测试不回归
|
|
145
|
+
- 重构:提取`_build_execution_plan(tool, args, decision)→Callable`,统一gate顺序 schema→idempotency→rate_limit→mask→execute→cache→mask_out。
|
|
146
|
+
|
|
147
|
+
### E1 / Gap 7 — Dockerfile
|
|
148
|
+
- `tests/test_dockerfile.py`(static parse):USER non-root, HEALTHCHECK, STOPSIGNAL SIGTERM, base pinned。
|
|
149
|
+
|
|
150
|
+
### E2 / Gap 10 — 集成测试CI
|
|
151
|
+
- `ci.yml`:default job显式`-m "not integration"`;新增scheduled `workflow_dispatch` integration job。
|
|
152
|
+
- `tests/test_ci_markers.py`:所有integration test有`@pytest.mark.integration`。
|
|
153
|
+
|
|
154
|
+
### E3 / Gap 11 — mypy
|
|
155
|
+
- `tests/test_mypy_clean.py`:subprocess运行mypy,exit 0。
|
|
156
|
+
- 修复现有mypy错误(>15个非trivial→记为P2 follow-up)。
|
|
157
|
+
- 不允许新增`# type: ignore`。
|
|
158
|
+
|
|
159
|
+
## 风险评估
|
|
160
|
+
|
|
161
|
+
| 风险 | 概率 | 影响 | 缓解 |
|
|
162
|
+
|---|---|---|---|
|
|
163
|
+
| D1重构破坏env测试 | 高 | 高 | Gate-order parity test先行;每步跑全suite |
|
|
164
|
+
| C1 sanitized message破坏现有测试 | 高 | 中 | 预先grep `str(exc)`/`error=.*exc`,同commit更新 |
|
|
165
|
+
| A2 export扩展导致import cycle | 中 | 中 | 增量添加;test_all_exports捕获ImportError |
|
|
166
|
+
| B4 `_secret`锁定破坏issue_token | 中 | 中 | classmethod构造;测试construction path |
|
|
167
|
+
| E3 mypy暴露大量错误 | 中 | 低 | 时间盒;>15个记为P2 |
|
|
168
|
+
| 锁竞争/deadlock | 低 | 中 | 非重入Lock;不在tool.execute()期间持有 |
|
|
169
|
+
|
|
170
|
+
## Scope边界(明确不做)
|
|
171
|
+
|
|
172
|
+
- ❌ 多线程Session(Session保持单线程设计)
|
|
173
|
+
- ❌ 提升Experimental API到Stable(除FrameworkConfig)
|
|
174
|
+
- ❌ 性能优化(仅correctness)
|
|
175
|
+
- ❌ 改变Tool/ToolResult协议
|
|
176
|
+
- ❌ 移除现有公开符号(纯增量)
|
|
177
|
+
- ❌ strict mypy(仅enforce现有config到0错误)
|
|
178
|
+
- ❌ 新功能(新策略/sink/RAG backend)
|
|
179
|
+
- ❌ 重写api.md(仅version line + api-stability.md修正)
|
|
180
|
+
|
|
181
|
+
## Commit策略
|
|
182
|
+
|
|
183
|
+
每gap一个green commit(tests+impl一起),branch off master at 5e264ca。
|
|
184
|
+
|
|
185
|
+
| Commit | Wave | Gap(s) |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| `test+feat: add coverage tooling` | A | 5 |
|
|
188
|
+
| `test+feat: freeze public API surface` | A | 1 |
|
|
189
|
+
| `test+feat: validate FrameworkConfig` | B | 4 |
|
|
190
|
+
| `chore: pin optional dependency upper bounds` | B | 9 |
|
|
191
|
+
| `docs: refresh SECURITY.md supported versions` | B | 6 |
|
|
192
|
+
| `test+feat: harden CredentialBroker/ScopedToken` | B | 8 |
|
|
193
|
+
| `docs: align api-stability.md with frozen surface` | B | 13 |
|
|
194
|
+
| `test+feat: ToolExecutionError hierarchy` | C | 3 |
|
|
195
|
+
| `test+feat: lock EventEmitter/RateLimiter/Idempotency; report sink errors` | C | 2,12 |
|
|
196
|
+
| `test+refactor: RuntimeEnvironment execution plan + locks + gate-order fix` | D | 2(env),14 |
|
|
197
|
+
| `build: production-harden Dockerfile` | E | 7 |
|
|
198
|
+
| `ci: explicit integration-test gating + scheduled job` | E | 10 |
|
|
199
|
+
| `test+chore: enforce mypy in CI` | E | 11 |
|
|
200
|
+
| `release: v1.0.0` | F | — |
|
|
201
|
+
|
|
202
|
+
## 发布门禁
|
|
203
|
+
|
|
204
|
+
1. `uv run pytest` → all green
|
|
205
|
+
2. `uv run ruff check src/ tests/ examples/` → clean
|
|
206
|
+
3. `uv run mypy src/petfishframework` → exit 0
|
|
207
|
+
4. `uv run pytest --cov=petfishframework` → report produced(informational)
|
|
208
|
+
5. `python scripts/pre_release.py 1.0.0` → exit 0
|
|
209
|
+
6. Docker build + smoke(SIGTERM graceful exit)
|
|
210
|
+
7. api-stability.md ↔ __init__.py cross-check green
|
|
211
|
+
8. `from petfishframework import Session, RuntimeEnvironment, EventEmitter, CredentialBroker` → 成功
|
|
@@ -2,6 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to petfishFramework will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.0] — 2026-07-09
|
|
6
|
+
|
|
7
|
+
### Production Release — API Stability Freeze
|
|
8
|
+
|
|
9
|
+
#### API Surface Frozen (Gap 1)
|
|
10
|
+
- Top-level `petfishframework.__all__` expanded from 15 to 40+ Stable exports
|
|
11
|
+
- `Session`, `RuntimeEnvironment`, `EventEmitter`, `CredentialBroker`, `ScopedToken`, `Calculator`, `WordSorter`, `FakeModel`, `pass_at_k`, `audit_report_from_session`, and all SARC types now importable from top level
|
|
12
|
+
- `test_api_public_surface.py` hardened: strict assert (no skip), `__all__` consistency check
|
|
13
|
+
|
|
14
|
+
#### Thread Safety (Gap 2)
|
|
15
|
+
- `threading.Lock` added to `EventEmitter`, `RateLimiter`, `IdempotencyStore`
|
|
16
|
+
- `RuntimeEnvironment` internal counters (`_model_calls`, `_accountant`) locked
|
|
17
|
+
- Session documented as single-threaded by design
|
|
18
|
+
- Concurrent stress tests verify no lost events/corruption
|
|
19
|
+
|
|
20
|
+
#### Exception Sanitization (Gap 3)
|
|
21
|
+
- New `ToolExecutionError` hierarchy: `ToolSchemaError`, `ToolTimeoutError`, `ToolRateLimitError`, `ToolRetryExhaustedError`, `ToolInternalError`
|
|
22
|
+
- All `except Exception` blocks sanitized — no `str(exc)` leakage to callers
|
|
23
|
+
- `KeyboardInterrupt`, `SystemExit`, `AssertionError` propagate (not caught)
|
|
24
|
+
- Schema validator sanitizes jsonschema errors (no input value echo)
|
|
25
|
+
|
|
26
|
+
#### Configuration Validation (Gap 4)
|
|
27
|
+
- `FrameworkConfig.__post_init__` validates: timeout > 0, temperature 0-2, max_tokens ≥ 0
|
|
28
|
+
- Invalid configs fail fast with `ValueError`
|
|
29
|
+
|
|
30
|
+
#### Test Coverage Tooling (Gap 5)
|
|
31
|
+
- `pytest-cov` added to dev dependencies
|
|
32
|
+
- `[tool.coverage.run]` configured with branch coverage
|
|
33
|
+
|
|
34
|
+
#### Security (Gap 6, 8)
|
|
35
|
+
- `SECURITY.md` updated: 1.0.x active, 0.5.x security-only
|
|
36
|
+
- `ScopedToken._secret` → name-mangled `__secret` (not trivially accessible)
|
|
37
|
+
- `CredentialBroker.validate_token` now enforces `max_uses`
|
|
38
|
+
|
|
39
|
+
#### Dockerfile Hardening (Gap 7)
|
|
40
|
+
- Non-root user (`pf`, uid 1000)
|
|
41
|
+
- `HEALTHCHECK` with 30s interval
|
|
42
|
+
- `STOPSIGNAL SIGTERM` for graceful shutdown
|
|
43
|
+
|
|
44
|
+
#### Dependency Bounds (Gap 9)
|
|
45
|
+
- All optional deps pinned with upper bounds: `openai<2`, `anthropic<1`, `mcp<2`, `otel<2`, `vault<2`
|
|
46
|
+
|
|
47
|
+
#### CI Hardening (Gap 10, 11)
|
|
48
|
+
- Integration tests explicitly gated: `-m "not integration"` default
|
|
49
|
+
- Scheduled `workflow_dispatch` integration job for real-API tests
|
|
50
|
+
- mypy enforced in CI: `mypy src/petfishframework` must exit 0
|
|
51
|
+
- `test_mypy_clean.py` and `test_ci_markers.py` as regression guards
|
|
52
|
+
|
|
53
|
+
#### EventEmitter Sink Error Visibility (Gap 12)
|
|
54
|
+
- `sink_error_count` property — failing sinks increment counter instead of silent `pass`
|
|
55
|
+
- Sinks called outside lock (deadlock prevention)
|
|
56
|
+
|
|
57
|
+
#### API Stability Policy (Gap 13)
|
|
58
|
+
- `api-stability.md` synced with actual exports
|
|
59
|
+
- `serve_as_mcp` reclassified Internal → Experimental
|
|
60
|
+
- `FrameworkConfig` promoted Experimental → Stable
|
|
61
|
+
- v1.0 freeze criteria documented as met
|
|
62
|
+
|
|
63
|
+
#### RuntimeEnvironment Refactor (Gap 14)
|
|
64
|
+
- Extracted `_prepare_execution` shared by `call()` and `call_async()`
|
|
65
|
+
- **Fixed gate ordering bug**: async path now matches sync (idempotency before rate_limit)
|
|
66
|
+
- call()/call_async() duplication eliminated via shared execution plan
|
|
67
|
+
- Thread-safety lock on model call counter and cost accountant
|
|
68
|
+
|
|
69
|
+
#### Test Growth
|
|
70
|
+
- v0.5.2: 382 tests → v1.0.0: 448 tests (+66)
|
|
71
|
+
- mypy: 0 errors across 76 source files
|
|
72
|
+
- ruff: clean
|
|
73
|
+
|
|
5
74
|
## [0.5.2] — 2026-07-09
|
|
6
75
|
|
|
7
76
|
### Review Fix Patch
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
|
|
3
|
+
# Non-root user
|
|
4
|
+
RUN useradd --create-home --uid 1000 pf
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
# Install dependencies first (layer caching)
|
|
8
|
+
COPY pyproject.toml uv.lock README.md ./
|
|
9
|
+
RUN pip install uv && uv sync --no-dev --all-extras
|
|
10
|
+
|
|
11
|
+
# Copy source
|
|
12
|
+
COPY src/ src/
|
|
13
|
+
RUN uv pip install --system .
|
|
14
|
+
|
|
15
|
+
# Switch to non-root
|
|
16
|
+
USER pf
|
|
17
|
+
|
|
18
|
+
# Healthcheck
|
|
19
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
20
|
+
CMD python -c "import petfishframework; print('ok')" || exit 1
|
|
21
|
+
|
|
22
|
+
# Graceful shutdown
|
|
23
|
+
STOPSIGNAL SIGTERM
|
|
24
|
+
|
|
25
|
+
ENTRYPOINT ["python", "-m", "petfishframework"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: petfishframework
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: A lightweight runtime framework for reliable, auditable, budget-aware, and permission-aware AI agents.
|
|
5
5
|
Project-URL: Homepage, https://github.com/kylecui/petfishFramework
|
|
6
6
|
Project-URL: Documentation, https://github.com/kylecui/petfishFramework/tree/master/docs
|
|
@@ -21,16 +21,16 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
|
21
21
|
Requires-Python: >=3.10
|
|
22
22
|
Requires-Dist: pyyaml>=6.0.3
|
|
23
23
|
Provides-Extra: anthropic
|
|
24
|
-
Requires-Dist: anthropic
|
|
24
|
+
Requires-Dist: anthropic<1,>=0.40; extra == 'anthropic'
|
|
25
25
|
Provides-Extra: mcp
|
|
26
|
-
Requires-Dist: mcp
|
|
26
|
+
Requires-Dist: mcp<2,>=1.0; extra == 'mcp'
|
|
27
27
|
Provides-Extra: openai
|
|
28
|
-
Requires-Dist: openai
|
|
28
|
+
Requires-Dist: openai<2,>=1.0; extra == 'openai'
|
|
29
29
|
Provides-Extra: otel
|
|
30
|
-
Requires-Dist: opentelemetry-api
|
|
31
|
-
Requires-Dist: opentelemetry-sdk
|
|
30
|
+
Requires-Dist: opentelemetry-api<2,>=1.20; extra == 'otel'
|
|
31
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.20; extra == 'otel'
|
|
32
32
|
Provides-Extra: vault
|
|
33
|
-
Requires-Dist: hvac
|
|
33
|
+
Requires-Dist: hvac<2,>=1.0; extra == 'vault'
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
35
|
|
|
36
36
|
# petfishFramework
|
|
@@ -39,7 +39,7 @@ Description-Content-Type: text/markdown
|
|
|
39
39
|
|
|
40
40
|
[](https://www.python.org/downloads/)
|
|
41
41
|
[](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
|
|
42
|
-
[](https://github.com/kylecui/petfishFramework/tree/master/tests/)
|
|
43
43
|
|
|
44
44
|
**Status: Alpha** — API may change. Core runtime works; see [Roadmap](#roadmap).
|
|
45
45
|
|
|
@@ -289,7 +289,7 @@ agent = Agent(model=model, reasoning=ReAct(), tools=tools, tool_governance=gover
|
|
|
289
289
|
|
|
290
290
|
- **v0.2.x**: Core runtime, permission semantics, enterprise PoC, Trusted Publishing ✅
|
|
291
291
|
- **v0.3.x**: YAML Policy Engine, CredentialBroker ✅
|
|
292
|
-
- **
|
|
292
|
+
- **v1.0.x** (current): Production release — API stability freeze, thread safety, exception sanitization, Dockerfile hardening, mypy enforcementdes, Vault adapter, Docker, threat model ✅
|
|
293
293
|
|
|
294
294
|
## Current Limitations
|
|
295
295
|
|
|
@@ -320,7 +320,7 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
320
320
|
git clone https://github.com/kylecui/petfishFramework.git
|
|
321
321
|
cd petfishFramework
|
|
322
322
|
uv sync --all-extras
|
|
323
|
-
uv run pytest #
|
|
323
|
+
uv run pytest # 448 tests
|
|
324
324
|
uv run ruff check src/ tests/
|
|
325
325
|
```
|
|
326
326
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.python.org/downloads/)
|
|
6
6
|
[](https://github.com/kylecui/petfishFramework/blob/master/LICENSE)
|
|
7
|
-
[](https://github.com/kylecui/petfishFramework/tree/master/tests/)
|
|
8
8
|
|
|
9
9
|
**Status: Alpha** — API may change. Core runtime works; see [Roadmap](#roadmap).
|
|
10
10
|
|
|
@@ -254,7 +254,7 @@ agent = Agent(model=model, reasoning=ReAct(), tools=tools, tool_governance=gover
|
|
|
254
254
|
|
|
255
255
|
- **v0.2.x**: Core runtime, permission semantics, enterprise PoC, Trusted Publishing ✅
|
|
256
256
|
- **v0.3.x**: YAML Policy Engine, CredentialBroker ✅
|
|
257
|
-
- **
|
|
257
|
+
- **v1.0.x** (current): Production release — API stability freeze, thread safety, exception sanitization, Dockerfile hardening, mypy enforcementdes, Vault adapter, Docker, threat model ✅
|
|
258
258
|
|
|
259
259
|
## Current Limitations
|
|
260
260
|
|
|
@@ -285,7 +285,7 @@ petfishFramework is **Alpha**. API may change before v1.0.
|
|
|
285
285
|
git clone https://github.com/kylecui/petfishFramework.git
|
|
286
286
|
cd petfishFramework
|
|
287
287
|
uv sync --all-extras
|
|
288
|
-
uv run pytest #
|
|
288
|
+
uv run pytest # 448 tests
|
|
289
289
|
uv run ruff check src/ tests/
|
|
290
290
|
```
|
|
291
291
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
|---------|------------------------|
|
|
7
|
-
| 0.
|
|
8
|
-
| 0.
|
|
9
|
-
| < 0.
|
|
7
|
+
| 1.0.x | ✅ Active development |
|
|
8
|
+
| 0.5.x | ⚠️ Security fixes only |
|
|
9
|
+
| < 0.5 | ❌ Not supported |
|
|
10
10
|
|
|
11
11
|
## Reporting a Vulnerability
|
|
12
12
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# API Stability Policy
|
|
2
2
|
|
|
3
|
-
> Effective:
|
|
4
|
-
> Goal: Help users understand which APIs are safe to depend on
|
|
3
|
+
> Effective: v1.0.0
|
|
4
|
+
> Goal: Help users understand which APIs are safe to depend on.
|
|
5
5
|
|
|
6
6
|
## Stability Tiers
|
|
7
7
|
|
|
8
8
|
| Tier | Meaning | Breaking changes | Versioning |
|
|
9
9
|
|---|---|---|---|
|
|
10
|
-
| **Stable** | API signature and semantics will not change
|
|
11
|
-
| **Experimental** | API exists and works, but may change signature or semantics in the next minor version. | Allowed with CHANGELOG note. | Minor (
|
|
10
|
+
| **Stable** | API signature and semantics will not change without a deprecation cycle (min 1 minor version). | Only for security fixes. | Patch (1.0.x) |
|
|
11
|
+
| **Experimental** | API exists and works, but may change signature or semantics in the next minor version. | Allowed with CHANGELOG note. | Minor (1.x.0) |
|
|
12
12
|
| **Internal** | Used by the framework internally. May change or be removed without notice. | No guarantees. | Any |
|
|
13
13
|
|
|
14
14
|
## Classification
|
|
15
15
|
|
|
16
16
|
### Stable
|
|
17
17
|
|
|
18
|
-
These APIs have been validated by
|
|
18
|
+
These APIs have been validated by 439+ tests and are exported from the top-level package:
|
|
19
19
|
|
|
20
20
|
- `Agent`, `Session` — core execution abstractions
|
|
21
21
|
- `Budget`, `BudgetExceeded` — budget enforcement
|
|
@@ -51,7 +51,7 @@ These APIs work and are tested, but their signatures or semantics may change:
|
|
|
51
51
|
- `AgentAsTool` — multi-agent delegation
|
|
52
52
|
- `ConversationStore`, `InMemoryConversationStore` — conversation memory
|
|
53
53
|
- `StructuredResult`, `parse_json`, `parse_structured` — structured output
|
|
54
|
-
- `FrameworkConfig` — configuration system
|
|
54
|
+
- `FrameworkConfig` — configuration system (validated, stable surface)
|
|
55
55
|
- `CostReport` — cost reporting format
|
|
56
56
|
- `connect_stdio`, `MCPClient` — MCP client
|
|
57
57
|
- Policy condition matchers — YAML matcher set may expand/change
|
|
@@ -66,7 +66,7 @@ These are implementation details that should not be directly imported:
|
|
|
66
66
|
- `CapabilityGrant` — audit artifact type (not yet emitted)
|
|
67
67
|
- `CompiledContext`, `TaskSpec`, `MemorySlice`, `EvidenceBundle`, `OutputContract` — compiled context types
|
|
68
68
|
- `MemoryView` — memory protocol (empty stub)
|
|
69
|
-
- `serve_as_mcp` — MCP server
|
|
69
|
+
- `serve_as_mcp` — MCP server mode (functional minimal stdio JSON-RPC, moved from Internal)
|
|
70
70
|
- `pass_at_k` perturbation functions (`canonical`, `order_shuffled`, etc.) — stable interface but internal implementations
|
|
71
71
|
|
|
72
72
|
## Deprecation Process
|
|
@@ -78,11 +78,16 @@ When an API moves from Stable to deprecated:
|
|
|
78
78
|
3. Keep the API functional for at least 1 minor version
|
|
79
79
|
4. Remove in the following minor version (or v1.0 if major)
|
|
80
80
|
|
|
81
|
-
## v1.0 Freeze Criteria
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- All Stable APIs have
|
|
86
|
-
-
|
|
81
|
+
## v1.0 Freeze Criteria (Met)
|
|
82
|
+
|
|
83
|
+
v1.0.0 freeze criteria:
|
|
84
|
+
- ✅ All Stable APIs are exported from top-level `petfishframework` package
|
|
85
|
+
- ✅ All Stable APIs have test coverage
|
|
86
|
+
- ✅ `pre_release.py` validates version consistency across all files
|
|
87
|
+
- ✅ mypy enforced in CI
|
|
88
|
+
- ✅ Thread-safety primitives locked (EventEmitter, RateLimiter, IdempotencyStore)
|
|
89
|
+
- ✅ Exception handling sanitized (no internal leakage)
|
|
90
|
+
- ✅ FrameworkConfig input validated
|
|
91
|
+
- ✅ Dockerfile production-hardened (non-root, HEALTHCHECK, SIGTERM)
|
|
87
92
|
- Breaking changes require semver-major version bump
|
|
88
93
|
- Migration guide published for any dropped APIs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# petfishFramework API Reference
|
|
2
2
|
|
|
3
|
-
This document is the authoritative reference for the public API of petfishFramework
|
|
3
|
+
This document is the authoritative reference for the public API of petfishFramework v1.0.0. Every signature, field, and example below is derived from the source code and from the tests that exercise it.
|
|
4
4
|
|
|
5
5
|
## 1. Overview
|
|
6
6
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "petfishframework"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "1.0.0"
|
|
8
8
|
description = "A lightweight runtime framework for reliable, auditable, budget-aware, and permission-aware AI agents."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -46,11 +46,11 @@ exclude = [
|
|
|
46
46
|
]
|
|
47
47
|
|
|
48
48
|
[project.optional-dependencies]
|
|
49
|
-
openai = ["openai>=1.0"]
|
|
50
|
-
anthropic = ["anthropic>=0.40"]
|
|
51
|
-
mcp = ["mcp>=1.0"]
|
|
52
|
-
otel = ["opentelemetry-api>=1.20", "opentelemetry-sdk>=1.20"]
|
|
53
|
-
vault = ["hvac>=1.0"]
|
|
49
|
+
openai = ["openai>=1.0,<2"]
|
|
50
|
+
anthropic = ["anthropic>=0.40,<1"]
|
|
51
|
+
mcp = ["mcp>=1.0,<2"]
|
|
52
|
+
otel = ["opentelemetry-api>=1.20,<2", "opentelemetry-sdk>=1.20,<2"]
|
|
53
|
+
vault = ["hvac>=1.0,<2"]
|
|
54
54
|
|
|
55
55
|
[tool.pytest.ini_options]
|
|
56
56
|
testpaths = ["tests"]
|
|
@@ -70,12 +70,24 @@ select = ["E", "F", "I", "B"]
|
|
|
70
70
|
python_version = "3.10"
|
|
71
71
|
warn_unused_configs = true
|
|
72
72
|
|
|
73
|
+
[[tool.mypy.overrides]]
|
|
74
|
+
module = ["jsonschema.*", "yaml.*"]
|
|
75
|
+
ignore_missing_imports = true
|
|
76
|
+
|
|
73
77
|
[dependency-groups]
|
|
74
78
|
dev = [
|
|
75
79
|
"mypy>=2.1.0",
|
|
76
80
|
"pytest>=9.1.1",
|
|
77
81
|
"pytest-asyncio>=1.4.0",
|
|
82
|
+
"pytest-cov>=5.0",
|
|
78
83
|
"python-dotenv>=1.2.2",
|
|
79
84
|
"ruff>=0.15.20",
|
|
80
85
|
"twine>=6.2.0",
|
|
81
86
|
]
|
|
87
|
+
|
|
88
|
+
[tool.coverage.run]
|
|
89
|
+
source = ["petfishframework"]
|
|
90
|
+
branch = true
|
|
91
|
+
|
|
92
|
+
[tool.coverage.report]
|
|
93
|
+
show_missing = true
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""petfishFramework — a general AI Agent framework.
|
|
2
|
+
|
|
3
|
+
Model-agnostic agent framework with pluggable reasoning strategies,
|
|
4
|
+
MCP-first tool contracts, and structural reliability.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from .config import FrameworkConfig
|
|
9
|
+
from .core.agent import Agent
|
|
10
|
+
from .core.contracts import Tool
|
|
11
|
+
from .core.environment import RuntimeEnvironment
|
|
12
|
+
from .core.events import Event, EventEmitter
|
|
13
|
+
from .core.session import Session
|
|
14
|
+
from .core.types import Budget, BudgetExceeded, Result, Step, Task, Trajectory, Usage
|
|
15
|
+
from .credentials.broker import CredentialBroker
|
|
16
|
+
from .credentials.token import ScopedToken
|
|
17
|
+
from .models.fake import FakeModel
|
|
18
|
+
from .permissions.model import (
|
|
19
|
+
AccessContext,
|
|
20
|
+
Action,
|
|
21
|
+
Decision,
|
|
22
|
+
DecisionEffect,
|
|
23
|
+
DefaultAllowPolicy,
|
|
24
|
+
DenyByDefaultPolicy,
|
|
25
|
+
PermissionPolicy,
|
|
26
|
+
Resource,
|
|
27
|
+
Subject,
|
|
28
|
+
)
|
|
29
|
+
from .policies import PolicyRule, YamlPolicy
|
|
30
|
+
from .reasoning import LATS, LLMPlusP, ReAct
|
|
31
|
+
from .reliability.audit_report import AuditReport, audit_report_from_session
|
|
32
|
+
from .reliability.pass_at_k import pass_at_k
|
|
33
|
+
from .reliability.replay import ReplayMode
|
|
34
|
+
from .tools.base import BaseTool, tool
|
|
35
|
+
from .tools.calculator import Calculator
|
|
36
|
+
from .tools.word_sorter import WordSorter
|
|
37
|
+
|
|
38
|
+
__version__ = "1.0.0"
|
|
39
|
+
|
|
40
|
+
__all__ = [
|
|
41
|
+
"AccessContext",
|
|
42
|
+
"Action",
|
|
43
|
+
"Agent",
|
|
44
|
+
"AuditReport",
|
|
45
|
+
"BaseTool",
|
|
46
|
+
"Budget",
|
|
47
|
+
"BudgetExceeded",
|
|
48
|
+
"Calculator",
|
|
49
|
+
"CredentialBroker",
|
|
50
|
+
"Decision",
|
|
51
|
+
"DecisionEffect",
|
|
52
|
+
"DefaultAllowPolicy",
|
|
53
|
+
"DenyByDefaultPolicy",
|
|
54
|
+
"Event",
|
|
55
|
+
"EventEmitter",
|
|
56
|
+
"FakeModel",
|
|
57
|
+
"FrameworkConfig",
|
|
58
|
+
"LATS",
|
|
59
|
+
"LLMPlusP",
|
|
60
|
+
"PermissionPolicy",
|
|
61
|
+
"PolicyRule",
|
|
62
|
+
"ReAct",
|
|
63
|
+
"ReplayMode",
|
|
64
|
+
"Resource",
|
|
65
|
+
"Result",
|
|
66
|
+
"RuntimeEnvironment",
|
|
67
|
+
"ScopedToken",
|
|
68
|
+
"Session",
|
|
69
|
+
"Step",
|
|
70
|
+
"Subject",
|
|
71
|
+
"Task",
|
|
72
|
+
"Tool",
|
|
73
|
+
"Trajectory",
|
|
74
|
+
"Usage",
|
|
75
|
+
"WordSorter",
|
|
76
|
+
"YamlPolicy",
|
|
77
|
+
"audit_report_from_session",
|
|
78
|
+
"pass_at_k",
|
|
79
|
+
"tool",
|
|
80
|
+
]
|