by-framework 0.2.2.dev14__tar.gz → 0.2.2.dev15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/CLAUDE.md +17 -0
  2. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/Makefile +28 -5
  3. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/PKG-INFO +1 -1
  4. by_framework-0.2.2.dev15/docs/architecture/langfuse-tracing-memory.md +130 -0
  5. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/langfuse.py +387 -80
  6. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/pyproject.toml +1 -1
  7. by_framework-0.2.2.dev15/scripts/check-metric-catalog.sh +65 -0
  8. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/verify.sh +1 -0
  9. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/metrics/catalog.py +54 -0
  10. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/metrics/test_catalog.py +14 -2
  11. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/plugin/test_langfuse_plugin.py +358 -0
  12. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/uv.lock +1 -1
  13. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.codex/hooks.json +0 -0
  14. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.dockerignore +0 -0
  15. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  16. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  17. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  18. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/RELEASING.md +0 -0
  19. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/workflows/ci.yml +0 -0
  20. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/workflows/deploy-smoke-test.yml +0 -0
  21. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/workflows/publish.yml +0 -0
  22. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/workflows/stale.yml +0 -0
  23. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.github/workflows/verify.yml +0 -0
  24. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.gitignore +0 -0
  25. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/.pre-commit-config.yaml +0 -0
  26. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/AGENTS.md +0 -0
  27. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/CHANGELOG.md +0 -0
  28. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/CODE_OF_CONDUCT.md +0 -0
  29. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/CONTRIBUTING.md +0 -0
  30. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/LICENSE +0 -0
  31. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/README.md +0 -0
  32. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/README_zh.md +0 -0
  33. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/SECURITY.md +0 -0
  34. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/assets/img/architecture_en.png +0 -0
  35. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/assets/img/architecture_zh.png +0 -0
  36. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/autoformat.sh +0 -0
  37. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/deploy/Dockerfile +0 -0
  38. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/deploy/docker-compose.yml +0 -0
  39. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/deploy/entrypoint.sh +0 -0
  40. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/deploy/kubernetes/worker-deployment.yaml +0 -0
  41. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/README.md +0 -0
  42. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/architecture/GUARD_AUTHORING.md +0 -0
  43. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/architecture/KEY_FILES.md +0 -0
  44. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/architecture/production-deployment.md +0 -0
  45. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/architecture/redis-cluster-mode.md +0 -0
  46. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/architecture/suspend-resume-liveness.md +0 -0
  47. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/architecture/worker-readiness-endpoint.md +0 -0
  48. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/by-framework-trace-change-usage.html +0 -0
  49. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/by-framework-trace-complete-guide.html +0 -0
  50. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/plans/2026-05-15-worker-task-state-stats.md +0 -0
  51. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/plans/2026-06-10-trace-metrics-correlation.md +0 -0
  52. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/docs/worker_management.html +0 -0
  53. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/examples/__init__.py +0 -0
  54. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/examples/echo_worker.py +0 -0
  55. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/examples/send_and_verify.py +0 -0
  56. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/README.md +0 -0
  57. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/pyproject.toml +0 -0
  58. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/src/by_framework_adk/__init__.py +0 -0
  59. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/src/by_framework_adk/_utils.py +0 -0
  60. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/src/by_framework_adk/adapter.py +0 -0
  61. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/src/by_framework_adk/worker.py +0 -0
  62. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/tests/test_adapter.py +0 -0
  63. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-adk/tests/test_worker.py +0 -0
  64. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/README.md +0 -0
  65. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/01_basic_chat.py +0 -0
  66. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/02_tools_and_ask_user.py +0 -0
  67. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/03_agent_delegation.py +0 -0
  68. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/04_task_group.py +0 -0
  69. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/05_real_model_react.py +0 -0
  70. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/README.md +0 -0
  71. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/examples/_infra.py +0 -0
  72. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/pyproject.toml +0 -0
  73. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/__init__.py +0 -0
  74. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/litellm_client.py +0 -0
  75. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/loop.py +0 -0
  76. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/model_client.py +0 -0
  77. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/testing.py +0 -0
  78. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/tool_spec.py +0 -0
  79. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/src/by_framework_agent/worker.py +0 -0
  80. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/conftest.py +0 -0
  81. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/test_agent_as_tool.py +0 -0
  82. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/test_ask_user_suspend_resume.py +0 -0
  83. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/test_cancel_cleanup.py +0 -0
  84. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/test_native_agent_worker.py +0 -0
  85. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/test_task_group_batching.py +0 -0
  86. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-agent/tests/test_tool_calling_loop.py +0 -0
  87. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/Dockerfile +0 -0
  88. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/README.md +0 -0
  89. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/frontend/index.html +0 -0
  90. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/frontend/package-lock.json +0 -0
  91. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/frontend/package.json +0 -0
  92. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/frontend/src/main.jsx +0 -0
  93. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/frontend/src/styles.css +0 -0
  94. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/frontend/vite.config.js +0 -0
  95. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/pyproject.toml +0 -0
  96. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/__init__.py +0 -0
  97. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/adapters.py +0 -0
  98. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/dashboard.py +0 -0
  99. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/static/__init__.py +0 -0
  100. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/static/app.js +0 -0
  101. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/static/index.html +0 -0
  102. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/src/by_framework_dashboard/static/styles.css +0 -0
  103. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-dashboard/tests/test_dashboard_server.py +0 -0
  104. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-byclaw/README.md +0 -0
  105. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-byclaw/pyproject.toml +0 -0
  106. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/__init__.py +0 -0
  107. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/byclaw_history.py +0 -0
  108. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-byclaw/tests/test_byclaw_history.py +0 -0
  109. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-postgres/README.md +0 -0
  110. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-postgres/pyproject.toml +0 -0
  111. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-postgres/src/by_framework_history_postgres/__init__.py +0 -0
  112. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-postgres/src/by_framework_history_postgres/postgres.py +0 -0
  113. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-history-postgres/tests/test_postgres_history_storage.py +0 -0
  114. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/README.md +0 -0
  115. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/pyproject.toml +0 -0
  116. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/src/by_framework_langgraph/__init__.py +0 -0
  117. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/src/by_framework_langgraph/_utils.py +0 -0
  118. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/src/by_framework_langgraph/adapter.py +0 -0
  119. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/src/by_framework_langgraph/tools.py +0 -0
  120. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/src/by_framework_langgraph/worker.py +0 -0
  121. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/tests/test_adapter.py +0 -0
  122. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/tests/test_tools.py +0 -0
  123. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-langgraph/tests/test_utils.py +0 -0
  124. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-langfuse/README.md +0 -0
  125. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-langfuse/pyproject.toml +0 -0
  126. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/__init__.py +0 -0
  127. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-langfuse/tests/test_langfuse_import.py +0 -0
  128. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-phoenix/README.md +0 -0
  129. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-phoenix/pyproject.toml +0 -0
  130. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/__init__.py +0 -0
  131. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/phoenix.py +0 -0
  132. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-phoenix/tests/test_phoenix_import.py +0 -0
  133. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-phoenix/tests/test_phoenix_plugin.py +0 -0
  134. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/pyproject.toml +0 -0
  135. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/src/by_framework_trace_query/__init__.py +0 -0
  136. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/src/by_framework_trace_query/client.py +0 -0
  137. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/src/by_framework_trace_query/merger.py +0 -0
  138. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/src/by_framework_trace_query/models.py +0 -0
  139. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/src/by_framework_trace_query/redis_source.py +0 -0
  140. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/libs/by-framework-trace-query/tests/test_trace_query_sdk.py +0 -0
  141. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/pylintrc +0 -0
  142. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/.map.conf +0 -0
  143. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/check-doc-discipline.sh +0 -0
  144. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/check-entry-freshness.sh +0 -0
  145. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/check-map-territory.sh +0 -0
  146. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/map-stop-hook.sh +0 -0
  147. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/python_quality.sh +0 -0
  148. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/scripts/test-growth-ladder.sh +0 -0
  149. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/__init__.py +0 -0
  150. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/__main__.py +0 -0
  151. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/admin/__init__.py +0 -0
  152. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/admin/cli.py +0 -0
  153. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/admin/worker_manager.py +0 -0
  154. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/client/__init__.py +0 -0
  155. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/client/byai_client.py +0 -0
  156. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/client/client.py +0 -0
  157. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/__init__.py +0 -0
  158. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/config.py +0 -0
  159. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/constants.py +0 -0
  160. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/emitter.py +0 -0
  161. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/exceptions.py +0 -0
  162. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/logger.py +0 -0
  163. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/common/redis_client.py +0 -0
  164. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/__init__.py +0 -0
  165. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/availability.py +0 -0
  166. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/delivery_gate.py +0 -0
  167. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/discovery.py +0 -0
  168. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/extensions/__init__.py +0 -0
  169. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/extensions/agent_config.py +0 -0
  170. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/extensions/agent_config_audit.py +0 -0
  171. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/extensions/plugin.py +0 -0
  172. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/extensions/registry.py +0 -0
  173. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/extensions/trace_provider.py +0 -0
  174. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/__init__.py +0 -0
  175. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/action_type.py +0 -0
  176. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/agent_state.py +0 -0
  177. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/byai_codec.py +0 -0
  178. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/byai_command.py +0 -0
  179. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/byai_types.py +0 -0
  180. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/commands.py +0 -0
  181. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/content_codec.py +0 -0
  182. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/content_type.py +0 -0
  183. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/data_message.py +0 -0
  184. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/data_shapes.py +0 -0
  185. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/event_type.py +0 -0
  186. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/events.py +0 -0
  187. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/message.py +0 -0
  188. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/message_header.py +0 -0
  189. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/responses.py +0 -0
  190. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/protocol/results.py +0 -0
  191. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/registry.py +0 -0
  192. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/__init__.py +0 -0
  193. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/agent_config_manager.py +0 -0
  194. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/agent_runtime_state.py +0 -0
  195. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/file_manager.py +0 -0
  196. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/file_paths.py +0 -0
  197. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/file_permissions.py +0 -0
  198. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/filestore/__init__.py +0 -0
  199. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/filestore/base.py +0 -0
  200. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/filestore/local.py +0 -0
  201. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/history/__init__.py +0 -0
  202. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/history/base.py +0 -0
  203. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/history/history_manager.py +0 -0
  204. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/history/in_memory.py +0 -0
  205. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/runtime/session_manager.py +0 -0
  206. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/wait_gate.py +0 -0
  207. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/wait_index.py +0 -0
  208. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/wait_reply.py +0 -0
  209. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/wait_sweeper.py +0 -0
  210. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/wakeup_controller.py +0 -0
  211. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/core/workspace.py +0 -0
  212. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/__init__.py +0 -0
  213. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/base.py +0 -0
  214. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/common.py +0 -0
  215. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/execution.py +0 -0
  216. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/http.py +0 -0
  217. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/protocol.py +0 -0
  218. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/errors/registry.py +0 -0
  219. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/metrics/__init__.py +0 -0
  220. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/metrics/collector.py +0 -0
  221. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/metrics/read_client.py +0 -0
  222. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/metrics/snapshot.py +0 -0
  223. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/trace/__init__.py +0 -0
  224. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/trace/external_trace.py +0 -0
  225. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/trace/span_recorder.py +0 -0
  226. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/trace/trace_schema.py +0 -0
  227. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/trace/trace_writer.py +0 -0
  228. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/util/__init__.py +0 -0
  229. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/util/discovery_http_client.py +0 -0
  230. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/util/generate_message_id.py +0 -0
  231. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/util/http_client.py +0 -0
  232. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/__init__.py +0 -0
  233. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/_control_handling.py +0 -0
  234. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/_execution_tracking.py +0 -0
  235. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/_message_processing.py +0 -0
  236. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/_resume_metadata.py +0 -0
  237. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/app.py +0 -0
  238. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/byai_context.py +0 -0
  239. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/byai_worker.py +0 -0
  240. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/context.py +0 -0
  241. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/health_server.py +0 -0
  242. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/heartbeat.py +0 -0
  243. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/processor.py +0 -0
  244. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/runner.py +0 -0
  245. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/sandbox/__init__.py +0 -0
  246. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/sandbox/hook_sandbox.py +0 -0
  247. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/src/by_framework/worker/worker.py +0 -0
  248. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/admin/__init__.py +0 -0
  249. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/admin/test_cli.py +0 -0
  250. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/client/__init__.py +0 -0
  251. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/client/test_client.py +0 -0
  252. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/common/__init__.py +0 -0
  253. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/common/test_config.py +0 -0
  254. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/common/test_constants.py +0 -0
  255. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/common/test_exceptions.py +0 -0
  256. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/common/test_logger.py +0 -0
  257. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/common/test_redis_client.py +0 -0
  258. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/conftest.py +0 -0
  259. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/__init__.py +0 -0
  260. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/protocol/__init__.py +0 -0
  261. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/protocol/test_byai_codec.py +0 -0
  262. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/protocol/test_command_wire.py +0 -0
  263. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/protocol/test_protocol.py +0 -0
  264. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/protocol/test_results.py +0 -0
  265. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/history/__init__.py +0 -0
  266. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/history/test_history_persistence.py +0 -0
  267. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_file_access_context.py +0 -0
  268. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_file_manager_default_storage.py +0 -0
  269. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_file_paths.py +0 -0
  270. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_file_permissions.py +0 -0
  271. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_filestore_local_collection.py +0 -0
  272. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_filestore_local_mutation.py +0 -0
  273. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_filestore_local_read.py +0 -0
  274. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/runtime/test_filestore_local_search.py +0 -0
  275. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_agent_config_audit.py +0 -0
  276. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_availability.py +0 -0
  277. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_discovery.py +0 -0
  278. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_registry.py +0 -0
  279. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_wait_gate.py +0 -0
  280. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_wait_index.py +0 -0
  281. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_wait_sweeper.py +0 -0
  282. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/core/test_worker_manager.py +0 -0
  283. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/__init__.py +0 -0
  284. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/test_ask_user_flow.py +0 -0
  285. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/test_callback_flow.py +0 -0
  286. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/test_logger_integration.py +0 -0
  287. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/test_nested_chain.py +0 -0
  288. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/test_orphan_recovery.py +0 -0
  289. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/integration/test_scatter_gather.py +0 -0
  290. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/metrics/test_collector.py +0 -0
  291. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/metrics/test_metrics.py +0 -0
  292. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/metrics/test_read_client.py +0 -0
  293. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/metrics/test_snapshot.py +0 -0
  294. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/plugin/__init__.py +0 -0
  295. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/plugin/test_plugin_discovery.py +0 -0
  296. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/plugin/test_plugin_improvements.py +0 -0
  297. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/plugin/test_plugin_registry.py +0 -0
  298. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/plugin/test_plugin_system.py +0 -0
  299. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/test_main.py +0 -0
  300. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/trace/test_external_trace.py +0 -0
  301. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/trace/test_logger_correlation.py +0 -0
  302. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/trace/test_otel_exporter.py +0 -0
  303. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/trace/test_span_recorder.py +0 -0
  304. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/trace/test_trace_writer.py +0 -0
  305. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/util/test_discovery_http_client.py +0 -0
  306. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/util/test_discovery_http_client_download.py +0 -0
  307. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/util/test_discovery_http_client_upload.py +0 -0
  308. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/util/test_http_client.py +0 -0
  309. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/__init__.py +0 -0
  310. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_admin_control_handling.py +0 -0
  311. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_app.py +0 -0
  312. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_byai_worker.py +0 -0
  313. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_context.py +0 -0
  314. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_control_handling.py +0 -0
  315. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_emitter.py +0 -0
  316. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_fetch_messages.py +0 -0
  317. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_gateway_worker.py +0 -0
  318. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_health_server.py +0 -0
  319. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_heartbeat.py +0 -0
  320. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_message_processing.py +0 -0
  321. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_processor.py +0 -0
  322. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_resume_metadata.py +0 -0
  323. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_runner.py +0 -0
  324. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/tests/worker/test_sandbox.py +0 -0
  325. {by_framework-0.2.2.dev14 → by_framework-0.2.2.dev15}/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
- @for project in $(PROJECTS); do \
42
- echo "==> Syncing $$project"; \
43
- (cd $$project && uv sync --all-extras); \
44
- done
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 --extra dev pytest); \
113
+ (cd $$project && uv run --all-extras pytest); \
91
114
  done
92
115
 
93
116
  clean:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: by-framework
3
- Version: 0.2.2.dev14
3
+ Version: 0.2.2.dev15
4
4
  Summary: 分布式 Agent 调度框架
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -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.