by-framework 0.2.2.dev14__tar.gz → 0.2.2.dev16__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.
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/CLAUDE.md +17 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/Makefile +28 -5
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/PKG-INFO +1 -1
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/KEY_FILES.md +16 -0
- by_framework-0.2.2.dev16/docs/architecture/langfuse-tracing-memory.md +130 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/worker-readiness-endpoint.md +9 -1
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/pyproject.toml +1 -1
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-langfuse/pyproject.toml +1 -1
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/langfuse.py +387 -80
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/pyproject.toml +1 -1
- by_framework-0.2.2.dev16/scripts/check-metric-catalog.sh +65 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/verify.sh +1 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/metrics/catalog.py +54 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/runner.py +25 -2
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/metrics/test_catalog.py +14 -2
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/plugin/test_langfuse_plugin.py +358 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_runner.py +208 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/uv.lock +3 -3
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.codex/hooks.json +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.dockerignore +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/RELEASING.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/workflows/ci.yml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/workflows/deploy-smoke-test.yml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/workflows/publish.yml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/workflows/stale.yml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.github/workflows/verify.yml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.gitignore +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/.pre-commit-config.yaml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/AGENTS.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/CHANGELOG.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/CODE_OF_CONDUCT.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/CONTRIBUTING.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/LICENSE +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/README_zh.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/SECURITY.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/assets/img/architecture_en.png +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/assets/img/architecture_zh.png +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/autoformat.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/deploy/Dockerfile +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/deploy/docker-compose.yml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/deploy/entrypoint.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/deploy/kubernetes/worker-deployment.yaml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/GUARD_AUTHORING.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/production-deployment.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/redis-cluster-mode.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/suspend-resume-liveness.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/by-framework-trace-change-usage.html +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/by-framework-trace-complete-guide.html +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/plans/2026-05-15-worker-task-state-stats.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/plans/2026-06-10-trace-metrics-correlation.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/worker_management.html +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/examples/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/examples/echo_worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/examples/send_and_verify.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/src/by_framework_adk/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/src/by_framework_adk/_utils.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/src/by_framework_adk/adapter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/src/by_framework_adk/worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/tests/test_adapter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-adk/tests/test_worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/01_basic_chat.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/02_tools_and_ask_user.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/03_agent_delegation.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/04_task_group.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/05_real_model_react.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/examples/_infra.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/litellm_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/loop.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/model_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/testing.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/tool_spec.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/src/by_framework_agent/worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/conftest.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/test_agent_as_tool.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/test_ask_user_suspend_resume.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/test_cancel_cleanup.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/test_native_agent_worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/test_task_group_batching.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-agent/tests/test_tool_calling_loop.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/Dockerfile +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/frontend/index.html +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/frontend/package-lock.json +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/frontend/package.json +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/frontend/src/main.jsx +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/frontend/src/styles.css +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/frontend/vite.config.js +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/adapters.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/dashboard.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/static/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/static/app.js +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/static/index.html +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/src/by_framework_dashboard/static/styles.css +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-dashboard/tests/test_dashboard_server.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-byclaw/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-byclaw/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/byclaw_history.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-byclaw/tests/test_byclaw_history.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-postgres/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-postgres/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-postgres/src/by_framework_history_postgres/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-postgres/src/by_framework_history_postgres/postgres.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-history-postgres/tests/test_postgres_history_storage.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/src/by_framework_langgraph/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/src/by_framework_langgraph/_utils.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/src/by_framework_langgraph/adapter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/src/by_framework_langgraph/tools.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/src/by_framework_langgraph/worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/tests/test_adapter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/tests/test_tools.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-langgraph/tests/test_utils.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-langfuse/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-langfuse/tests/test_langfuse_import.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-phoenix/README.md +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-phoenix/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/phoenix.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-phoenix/tests/test_phoenix_import.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-phoenix/tests/test_phoenix_plugin.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/pyproject.toml +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/src/by_framework_trace_query/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/src/by_framework_trace_query/client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/src/by_framework_trace_query/merger.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/src/by_framework_trace_query/models.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/src/by_framework_trace_query/redis_source.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/libs/by-framework-trace-query/tests/test_trace_query_sdk.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/pylintrc +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/.map.conf +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/check-doc-discipline.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/check-entry-freshness.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/check-map-territory.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/map-stop-hook.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/python_quality.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/scripts/test-growth-ladder.sh +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/__main__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/admin/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/admin/cli.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/admin/worker_manager.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/client/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/client/byai_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/client/client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/config.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/constants.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/emitter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/exceptions.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/logger.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/common/redis_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/availability.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/delivery_gate.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/discovery.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/extensions/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/extensions/agent_config.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/extensions/agent_config_audit.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/extensions/plugin.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/extensions/registry.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/extensions/trace_provider.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/action_type.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/agent_state.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/byai_codec.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/byai_command.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/byai_types.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/commands.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/content_codec.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/content_type.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/data_message.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/data_shapes.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/event_type.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/events.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/message.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/message_header.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/responses.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/protocol/results.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/registry.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/agent_config_manager.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/agent_runtime_state.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/file_manager.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/file_paths.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/file_permissions.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/filestore/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/filestore/base.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/filestore/local.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/history/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/history/base.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/history/history_manager.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/history/in_memory.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/runtime/session_manager.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/wait_gate.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/wait_index.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/wait_reply.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/wait_sweeper.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/wakeup_controller.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/core/workspace.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/base.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/common.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/execution.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/http.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/protocol.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/errors/registry.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/metrics/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/metrics/collector.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/metrics/read_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/metrics/snapshot.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/trace/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/trace/external_trace.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/trace/span_recorder.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/trace/trace_schema.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/trace/trace_writer.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/util/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/util/discovery_http_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/util/generate_message_id.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/util/http_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/_control_handling.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/_execution_tracking.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/_message_processing.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/_resume_metadata.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/app.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/byai_context.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/byai_worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/context.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/health_server.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/heartbeat.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/processor.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/sandbox/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/sandbox/hook_sandbox.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/src/by_framework/worker/worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/admin/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/admin/test_cli.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/client/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/client/test_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/common/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/common/test_config.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/common/test_constants.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/common/test_exceptions.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/common/test_logger.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/common/test_redis_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/conftest.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/protocol/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/protocol/test_byai_codec.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/protocol/test_command_wire.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/protocol/test_protocol.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/protocol/test_results.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/history/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/history/test_history_persistence.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_file_access_context.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_file_manager_default_storage.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_file_paths.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_file_permissions.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_filestore_local_collection.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_filestore_local_mutation.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_filestore_local_read.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/runtime/test_filestore_local_search.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_agent_config_audit.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_availability.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_discovery.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_registry.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_wait_gate.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_wait_index.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_wait_sweeper.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/core/test_worker_manager.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/test_ask_user_flow.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/test_callback_flow.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/test_logger_integration.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/test_nested_chain.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/test_orphan_recovery.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/integration/test_scatter_gather.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/metrics/test_collector.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/metrics/test_metrics.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/metrics/test_read_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/metrics/test_snapshot.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/plugin/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/plugin/test_plugin_discovery.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/plugin/test_plugin_improvements.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/plugin/test_plugin_registry.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/plugin/test_plugin_system.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/test_main.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/trace/test_external_trace.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/trace/test_logger_correlation.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/trace/test_otel_exporter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/trace/test_span_recorder.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/trace/test_trace_writer.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/util/test_discovery_http_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/util/test_discovery_http_client_download.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/util/test_discovery_http_client_upload.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/util/test_http_client.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/__init__.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_admin_control_handling.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_app.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_byai_worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_context.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_control_handling.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_emitter.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_fetch_messages.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_gateway_worker.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_health_server.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_heartbeat.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_message_processing.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_processor.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_resume_metadata.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_sandbox.py +0 -0
- {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/tests/worker/test_workspace.py +0 -0
|
@@ -151,6 +151,22 @@ Pre-commit hooks are configured in `.pre-commit-config.yaml` and run isort, ruff
|
|
|
151
151
|
plugin/trace integration point must degrade to a no-op (logged) rather
|
|
152
152
|
than raising.
|
|
153
153
|
|
|
154
|
+
- **A rule enforced only behind an optional dependency is not enforced.** If
|
|
155
|
+
the check short-circuits when a package is missing, then whatever controls
|
|
156
|
+
the environment controls the rule — and a green run stops meaning anything.
|
|
157
|
+
Incident: `tests/metrics/test_catalog.py` asserts every exported metric has a
|
|
158
|
+
`metrics/catalog.py` entry, but returned early when `prometheus-client` was
|
|
159
|
+
absent, while `make test` synced with `--extra dev` and dropped the root
|
|
160
|
+
`observability` extra. The assertion ran against an empty registry and
|
|
161
|
+
reported success for months; four uncatalogued metrics landed on main with CI
|
|
162
|
+
green (#142, then the CI fix). Correct form: enforce the rule where the
|
|
163
|
+
optional dependency cannot reach it — here `scripts/check-metric-catalog.sh`
|
|
164
|
+
reads the source, so **every new Prometheus `Counter`/`Gauge`/`Histogram` in
|
|
165
|
+
`src/` needs a `catalog.py` entry** regardless of what is installed — and
|
|
166
|
+
make the dependent test `pytest.skip()` rather than `return`, so degrading is
|
|
167
|
+
at least visible. Test commands must sync the extras the tests exercise
|
|
168
|
+
(`make test` uses `--all-extras`); narrowing them silently deletes coverage.
|
|
169
|
+
|
|
154
170
|
## Iron rules
|
|
155
171
|
|
|
156
172
|
<!-- No process rules (test invocation, release steps) have caused an
|
|
@@ -166,6 +182,7 @@ Pre-commit hooks are configured in `.pre-commit-config.yaml` and run isort, ruff
|
|
|
166
182
|
| Worker deployment/production-readiness — README's 部署 section, `__main__.py` CLI flags, `run_worker()`'s signature, or shutdown/signal handling | `docs/architecture/production-deployment.md` |
|
|
167
183
|
| Worker readiness/health-check endpoint (`WorkerHealthServer`, `/readyz`, `--health-port`) — building it, or touching anything that changes what "ready" means | `docs/architecture/worker-readiness-endpoint.md` |
|
|
168
184
|
| suspend/resume liveness — the wait index, its idempotency gate, or the sweep that resolves callers whose reply never arrives | `docs/architecture/suspend-resume-liveness.md` |
|
|
185
|
+
| Langfuse tracing state held in worker memory — `_active_workflows`, trace-output uploads, or anything that queues/retains per-task telemetry | `docs/architecture/langfuse-tracing-memory.md` |
|
|
169
186
|
|
|
170
187
|
## Maintaining this map
|
|
171
188
|
|
|
@@ -37,11 +37,22 @@ list-projects:
|
|
|
37
37
|
echo $$project; \
|
|
38
38
|
done
|
|
39
39
|
|
|
40
|
+
# All ten projects share the workspace venv, so syncing them in a loop makes
|
|
41
|
+
# each one PRUNE the previous one's dependencies — the loop used to end with a
|
|
42
|
+
# venv holding only the last project's deps (and it uninstalled prometheus-client
|
|
43
|
+
# on the second iteration). --all-packages resolves the whole workspace once
|
|
44
|
+
# instead. The loop survives only for an explicit PROJECTS override, where
|
|
45
|
+
# narrowing the venv is what the caller asked for.
|
|
40
46
|
install:
|
|
41
|
-
@
|
|
42
|
-
echo "==> Syncing
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
@if [ "$(strip $(PROJECTS))" = "$(strip $(PYTHON_PROJECTS))" ]; then \
|
|
48
|
+
echo "==> Syncing workspace (all packages, all extras)"; \
|
|
49
|
+
uv sync --all-extras --all-packages; \
|
|
50
|
+
else \
|
|
51
|
+
for project in $(PROJECTS); do \
|
|
52
|
+
echo "==> Syncing $$project (narrowed: PROJECTS override)"; \
|
|
53
|
+
(cd $$project && uv sync --all-extras); \
|
|
54
|
+
done; \
|
|
55
|
+
fi
|
|
45
56
|
|
|
46
57
|
format:
|
|
47
58
|
@PROJECTS="$(PROJECTS)" ./scripts/python_quality.sh format $(FILES)
|
|
@@ -80,6 +91,18 @@ lint-changed:
|
|
|
80
91
|
$(MAKE) lint PROJECTS="$(PROJECTS)" FILES="$$changed_files"; \
|
|
81
92
|
fi
|
|
82
93
|
|
|
94
|
+
# --all-extras, not --extra dev: `uv run` only ever adds what it is asked for,
|
|
95
|
+
# it never restores an extra it was not told about. So once `install`'s old
|
|
96
|
+
# per-project loop had uninstalled prometheus-client, `--extra dev` left it
|
|
97
|
+
# uninstalled and the root project's whole `observability` extra stayed missing
|
|
98
|
+
# for the entire test run. tests/metrics then ran against a build with no
|
|
99
|
+
# Prometheus registry, where the metric catalog check short-circuits and reports
|
|
100
|
+
# success without inspecting anything. State what the tests need, rather than
|
|
101
|
+
# inheriting whatever `install` happened to leave behind.
|
|
102
|
+
#
|
|
103
|
+
# Deliberately per-project rather than --all-packages: each project must be
|
|
104
|
+
# testable with only its own declared dependencies, or a package that quietly
|
|
105
|
+
# leans on a sibling's deps would still pass here and break on install.
|
|
83
106
|
test:
|
|
84
107
|
@set -e; for project in $(PROJECTS); do \
|
|
85
108
|
if ! find "$$project/tests" -type f \( -name 'test_*.py' -o -name '*_test.py' \) -print -quit 2>/dev/null | grep -q .; then \
|
|
@@ -87,7 +110,7 @@ test:
|
|
|
87
110
|
continue; \
|
|
88
111
|
fi; \
|
|
89
112
|
echo "==> Testing $$project"; \
|
|
90
|
-
(cd $$project && uv run --
|
|
113
|
+
(cd $$project && uv run --all-extras pytest); \
|
|
91
114
|
done
|
|
92
115
|
|
|
93
116
|
clean:
|
|
@@ -314,6 +314,22 @@ Entry anatomy:
|
|
|
314
314
|
best-effort — a background component that fails to construct must never
|
|
315
315
|
prevent the worker from consuming — and every one of them must be
|
|
316
316
|
cancelled and awaited in `_shutdown()`, or shutdown hangs on it.
|
|
317
|
+
`_run_once()` acquires a concurrency slot via `_acquire_slot()`, never a
|
|
318
|
+
bare `await self.semaphore.acquire()` — a saturated pool (all
|
|
319
|
+
`max_concurrency` slots held by legitimately long-running tasks) must not
|
|
320
|
+
be indistinguishable from a genuinely stuck consume loop. `_acquire_slot()`
|
|
321
|
+
polls `len(self._running_tasks) >= self.max_concurrency` and calls
|
|
322
|
+
`_mark_consumer_tick()` on every poll while waiting, so `_is_consumer_healthy()`
|
|
323
|
+
(whose own comparison logic is untouched) keeps seeing fresh ticks for as
|
|
324
|
+
long as the loop is merely busy, not stalled. `self._slot_wait_poll_seconds`
|
|
325
|
+
is derived from `_consumer_health_timeout_seconds` (not hardcoded) so the
|
|
326
|
+
two stay proportional under any lease-TTL/stream-block-ms configuration.
|
|
327
|
+
Trade-off this does *not* solve, by design: it cannot distinguish a
|
|
328
|
+
legitimately long task from a deadlocked one that will never return — both
|
|
329
|
+
present as `_running_tasks` stuck at `max_concurrency`; task-level SLA
|
|
330
|
+
enforcement (detecting and cancelling an individual stuck task) is a
|
|
331
|
+
separate concern from consumer-loop liveness and is not implemented here —
|
|
332
|
+
see `CancelTaskCommand` for the existing per-task cancel path.
|
|
317
333
|
|
|
318
334
|
- `src/by_framework/worker/health_server.py` — `WorkerHealthServer`: the
|
|
319
335
|
`/readyz` readiness HTTP endpoint, on its own daemon thread (mirrors
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Langfuse tracing: what the worker holds, and for how long
|
|
2
|
+
|
|
3
|
+
## What this covers
|
|
4
|
+
|
|
5
|
+
`libs/by-framework-trace-langfuse` is the only plugin that keeps **live
|
|
6
|
+
per-task state in worker memory across hook calls**. Everything else in the
|
|
7
|
+
trace layer is either fire-and-forget (`RedisSpanExporter`) or bounded by the
|
|
8
|
+
SDK (`LangfuseSpanProcessor` wraps OTel's `BatchSpanProcessor`, whose queue
|
|
9
|
+
tops out at 2048 spans and drops the overflow).
|
|
10
|
+
|
|
11
|
+
This doc exists because three separate unbounded-growth bugs shipped in that
|
|
12
|
+
plugin and none of them were visible from reading a single function. They
|
|
13
|
+
shared one root cause, stated below, and the fixes are only correct as long
|
|
14
|
+
as that framing holds.
|
|
15
|
+
|
|
16
|
+
## The rule everything follows from
|
|
17
|
+
|
|
18
|
+
**Langfuse reporting is best-effort telemetry, not business data.** A slow or
|
|
19
|
+
unreachable Langfuse must cost trace fidelity — never worker memory, never
|
|
20
|
+
worker shutdown, never a shared executor.
|
|
21
|
+
|
|
22
|
+
Every degraded path therefore **sheds load**: drop the work, count it, log it
|
|
23
|
+
sparsely. The failure mode to avoid is the intuitive one — "queue it, we'll
|
|
24
|
+
send it when Langfuse recovers" — because a worker completing tasks faster
|
|
25
|
+
than Langfuse accepts them turns that queue into an OOM with the whole
|
|
26
|
+
serialized task output pinned in each entry.
|
|
27
|
+
|
|
28
|
+
This is a stricter rule than the repo-wide fail-soft invariant in `CLAUDE.md`.
|
|
29
|
+
Fail-soft says *don't raise into the task path*. This says *don't accumulate
|
|
30
|
+
in the task path either* — a plugin that swallows every exception can still
|
|
31
|
+
kill the worker by growing.
|
|
32
|
+
|
|
33
|
+
## The three things the plugin holds
|
|
34
|
+
|
|
35
|
+
### 1. `_active_workflows` — durable workflow spans
|
|
36
|
+
|
|
37
|
+
An `agent.workflow` observation spans the **logical** task, which outlives any
|
|
38
|
+
single worker execution: `ask_user` and `call_agent` suspend the execution and
|
|
39
|
+
a later `RESUME` reattaches to it (see `suspend-resume-liveness.md`). So the
|
|
40
|
+
handle cannot be closed when the first execution returns — it lives in an
|
|
41
|
+
`OrderedDict` keyed by `(session_id, message_id)` until the task reaches a
|
|
42
|
+
terminal status.
|
|
43
|
+
|
|
44
|
+
Three things can end an entry, and all three must exist:
|
|
45
|
+
|
|
46
|
+
| Exit | Trigger |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Normal | terminal `on_task_complete` / `on_task_error` / `on_task_cancel` |
|
|
49
|
+
| TTL | `_expire_active_workflows()`, for a suspend whose resume never came |
|
|
50
|
+
| LRU | `_evict_active_workflows_if_needed()`, at `max_active_workflows` |
|
|
51
|
+
|
|
52
|
+
**Invariant — LRU order equals expiry order.** `_expire_active_workflows()`
|
|
53
|
+
scans from the head and stops at the first live entry, which is only valid
|
|
54
|
+
because every write goes through `_track_active_workflow()`, which refreshes
|
|
55
|
+
`expires_at` *and* moves the entry to the tail. A future write that bypasses
|
|
56
|
+
that helper silently turns expiry into a no-op for everything behind it.
|
|
57
|
+
|
|
58
|
+
**Ownership is claimed at registration, not at the end of the hook.**
|
|
59
|
+
`on_task_start` registers the workflow and immediately sets
|
|
60
|
+
`LANGFUSE_WORKFLOW_OBSERVATION_ATTR` on the context, because the tracer calls
|
|
61
|
+
that follow it can raise — and `PluginRegistry._execute_hook()` swallows that.
|
|
62
|
+
`_end_workflow_observation()` additionally falls back to the
|
|
63
|
+
`(session_id, message_id)` key when the context attribute is missing. Both
|
|
64
|
+
halves are load-bearing: without the fallback, a mid-hook SDK error orphaned
|
|
65
|
+
100% of entries until LRU eviction, each one a live span that would never
|
|
66
|
+
export.
|
|
67
|
+
|
|
68
|
+
For the same reason `on_task_error` / `on_task_cancel` must **not** return
|
|
69
|
+
early when the context has no agent/worker observations. The workflow entry
|
|
70
|
+
can outlive them, and bailing is what stranded it.
|
|
71
|
+
|
|
72
|
+
### 2. `_pending_trace_output_updates` — in-flight trace-output uploads
|
|
73
|
+
|
|
74
|
+
`update_trace_output` is a *synchronous* HTTP POST — it patches the trace-list
|
|
75
|
+
`output` field, which the OTel span pipeline does not carry. It runs on the
|
|
76
|
+
plugin's **own** `ThreadPoolExecutor`, never the asyncio default executor:
|
|
77
|
+
that pool is shared with the rest of the framework's blocking calls, and a
|
|
78
|
+
stalled Langfuse would starve unrelated work.
|
|
79
|
+
|
|
80
|
+
The bound is enforced **before submitting**, not by trimming the tracking set.
|
|
81
|
+
Dropping only the future leaves the work item — and the payload it closes
|
|
82
|
+
over — sitting in the executor queue, which is exactly the growth being
|
|
83
|
+
guarded. At the limit the upload is discarded and counted.
|
|
84
|
+
|
|
85
|
+
`on_worker_shutdown` waits on the remainder with a deadline and abandons
|
|
86
|
+
whatever misses it. The discard callback catches `BaseException`, not
|
|
87
|
+
`Exception`: shutdown cancels the stragglers, and `CancelledError` is a
|
|
88
|
+
`BaseException`, so a narrower catch dumps one traceback per abandoned upload.
|
|
89
|
+
|
|
90
|
+
### 3. Serialized output
|
|
91
|
+
|
|
92
|
+
`_serialize_value` deep-copies the whole task result. The end-of-task path
|
|
93
|
+
serializes **once**, at the top of `on_task_complete`; `_end_observation`,
|
|
94
|
+
`_end_workflow_observation` and `_update_trace_output` all take an
|
|
95
|
+
already-serialized value and must not re-serialize it. Their docstrings state
|
|
96
|
+
this precondition — it is a contract, not an optimization, because copy #3 is
|
|
97
|
+
what an in-flight upload pins.
|
|
98
|
+
|
|
99
|
+
## Tunables
|
|
100
|
+
|
|
101
|
+
All have safe defaults; unset behaves no worse than the built-in values.
|
|
102
|
+
Explicit constructor kwargs always win over the environment, per `CLAUDE.md`'s
|
|
103
|
+
"explicitly-passed kwarg" invariant.
|
|
104
|
+
|
|
105
|
+
| Env | Default | What it bounds |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `BYAI_LANGFUSE_MAX_ACTIVE_WORKFLOWS` | 10000 | live workflow spans |
|
|
108
|
+
| `BYAI_LANGFUSE_WORKFLOW_TTL_SECONDS` | 3600 | how long a suspended workflow is held |
|
|
109
|
+
| `BYAI_LANGFUSE_MAX_PENDING_TRACE_OUTPUTS` | 128 | in-flight trace-output uploads |
|
|
110
|
+
| `BYAI_LANGFUSE_SHUTDOWN_FLUSH_TIMEOUT_SECONDS` | 5 | shutdown flush deadline |
|
|
111
|
+
|
|
112
|
+
## Accepted trade-off
|
|
113
|
+
|
|
114
|
+
A workflow reclaimed by TTL or LRU whose resume arrives later gets a *new*
|
|
115
|
+
observation built from the same deterministic span id
|
|
116
|
+
(`str_to_uint64(f"{execution_anchor}:agent.workflow")`), so Langfuse sees a
|
|
117
|
+
duplicate span id. This is pre-existing LRU behaviour, not new; the 1-hour
|
|
118
|
+
default TTL keeps it rare. Trace-output drops under load are likewise
|
|
119
|
+
deliberate — the trace and its observations still ship via the SDK's own
|
|
120
|
+
batch pipeline, so only the trace-list `output` preview is lost.
|
|
121
|
+
|
|
122
|
+
## One more thing that is not a leak
|
|
123
|
+
|
|
124
|
+
`build_langchain_callback` subclasses the Langfuse `CallbackHandler` to stop
|
|
125
|
+
LangChain runs being promoted to trace roots. That subclass is cached per base
|
|
126
|
+
class in a `WeakKeyDictionary`. Minting one per call was *not* a hard leak —
|
|
127
|
+
the classes are reclaimable — but it ran once per task, and type objects are
|
|
128
|
+
only collected by the generational GC while every creation invalidates
|
|
129
|
+
CPython's type method cache. Per-callback state lives on the instance
|
|
130
|
+
(`_by_framework_metadata`), so one shared subclass is safe.
|
{by_framework-0.2.2.dev14 → by_framework-0.2.2.dev16}/docs/architecture/worker-readiness-endpoint.md
RENAMED
|
@@ -216,7 +216,15 @@ regardless.
|
|
|
216
216
|
2. `draining` — `SIGTERM`/`SIGINT` received, shutdown in progress
|
|
217
217
|
3. `evicted` — `admin_lifecycle == "evicted"`
|
|
218
218
|
4. `suspended` — `admin_lifecycle == "suspended"`
|
|
219
|
-
5. `consumer_stalled` — consume loop stale past `_consumer_health_timeout_seconds
|
|
219
|
+
5. `consumer_stalled` — consume loop stale past `_consumer_health_timeout_seconds`.
|
|
220
|
+
"Stale" means the loop itself has stopped making progress (crashed task,
|
|
221
|
+
or an unexpected hang outside slot-waiting) — it deliberately excludes a
|
|
222
|
+
consume loop that is merely waiting for every `max_concurrency` slot to
|
|
223
|
+
free up while legitimately long-running tasks are in flight. A saturated-
|
|
224
|
+
but-alive loop keeps refreshing its liveness signal while it waits (see
|
|
225
|
+
`runner.py`'s `_acquire_slot()` in `docs/architecture/KEY_FILES.md`), so
|
|
226
|
+
it never surfaces here; only a loop that has actually stopped responding
|
|
227
|
+
does.
|
|
220
228
|
6. `serving` — none of the above; `ready=true`
|
|
221
229
|
|
|
222
230
|
`ready` is `true` if and only if `reason == "serving"`.
|