by-framework 0.2.2.dev12__tar.gz → 0.2.2.dev13__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 (321) hide show
  1. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/PKG-INFO +1 -1
  2. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/architecture/KEY_FILES.md +22 -4
  3. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/pyproject.toml +1 -1
  4. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/wait_sweeper.py +1 -1
  5. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/context.py +5 -0
  6. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/worker.py +9 -0
  7. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_wait_sweeper.py +11 -0
  8. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/test_nested_chain.py +57 -5
  9. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_context.py +31 -0
  10. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_gateway_worker.py +14 -0
  11. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/uv.lock +1 -1
  12. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.codex/hooks.json +0 -0
  13. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.dockerignore +0 -0
  14. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  15. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  16. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  17. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/RELEASING.md +0 -0
  18. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/workflows/ci.yml +0 -0
  19. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/workflows/deploy-smoke-test.yml +0 -0
  20. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/workflows/publish.yml +0 -0
  21. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/workflows/stale.yml +0 -0
  22. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.github/workflows/verify.yml +0 -0
  23. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.gitignore +0 -0
  24. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/.pre-commit-config.yaml +0 -0
  25. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/AGENTS.md +0 -0
  26. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/CHANGELOG.md +0 -0
  27. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/CLAUDE.md +0 -0
  28. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/CODE_OF_CONDUCT.md +0 -0
  29. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/CONTRIBUTING.md +0 -0
  30. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/LICENSE +0 -0
  31. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/Makefile +0 -0
  32. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/README.md +0 -0
  33. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/README_zh.md +0 -0
  34. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/SECURITY.md +0 -0
  35. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/assets/img/architecture_en.png +0 -0
  36. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/assets/img/architecture_zh.png +0 -0
  37. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/autoformat.sh +0 -0
  38. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/deploy/Dockerfile +0 -0
  39. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/deploy/docker-compose.yml +0 -0
  40. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/deploy/entrypoint.sh +0 -0
  41. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/deploy/kubernetes/worker-deployment.yaml +0 -0
  42. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/README.md +0 -0
  43. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/architecture/GUARD_AUTHORING.md +0 -0
  44. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/architecture/production-deployment.md +0 -0
  45. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/architecture/redis-cluster-mode.md +0 -0
  46. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/architecture/suspend-resume-liveness.md +0 -0
  47. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/architecture/worker-readiness-endpoint.md +0 -0
  48. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/by-framework-trace-change-usage.html +0 -0
  49. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/by-framework-trace-complete-guide.html +0 -0
  50. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/plans/2026-05-15-worker-task-state-stats.md +0 -0
  51. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/plans/2026-06-10-trace-metrics-correlation.md +0 -0
  52. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/docs/worker_management.html +0 -0
  53. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/examples/__init__.py +0 -0
  54. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/examples/echo_worker.py +0 -0
  55. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/examples/send_and_verify.py +0 -0
  56. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/README.md +0 -0
  57. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/pyproject.toml +0 -0
  58. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/src/by_framework_adk/__init__.py +0 -0
  59. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/src/by_framework_adk/_utils.py +0 -0
  60. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/src/by_framework_adk/adapter.py +0 -0
  61. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/src/by_framework_adk/worker.py +0 -0
  62. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/tests/test_adapter.py +0 -0
  63. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-adk/tests/test_worker.py +0 -0
  64. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/README.md +0 -0
  65. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/01_basic_chat.py +0 -0
  66. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/02_tools_and_ask_user.py +0 -0
  67. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/03_agent_delegation.py +0 -0
  68. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/04_task_group.py +0 -0
  69. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/05_real_model_react.py +0 -0
  70. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/README.md +0 -0
  71. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/examples/_infra.py +0 -0
  72. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/pyproject.toml +0 -0
  73. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/__init__.py +0 -0
  74. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/litellm_client.py +0 -0
  75. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/loop.py +0 -0
  76. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/model_client.py +0 -0
  77. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/testing.py +0 -0
  78. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/tool_spec.py +0 -0
  79. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/src/by_framework_agent/worker.py +0 -0
  80. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/conftest.py +0 -0
  81. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/test_agent_as_tool.py +0 -0
  82. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/test_ask_user_suspend_resume.py +0 -0
  83. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/test_cancel_cleanup.py +0 -0
  84. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/test_native_agent_worker.py +0 -0
  85. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/test_task_group_batching.py +0 -0
  86. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-agent/tests/test_tool_calling_loop.py +0 -0
  87. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/Dockerfile +0 -0
  88. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/README.md +0 -0
  89. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/frontend/index.html +0 -0
  90. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/frontend/package-lock.json +0 -0
  91. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/frontend/package.json +0 -0
  92. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/frontend/src/main.jsx +0 -0
  93. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/frontend/src/styles.css +0 -0
  94. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/frontend/vite.config.js +0 -0
  95. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/pyproject.toml +0 -0
  96. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/__init__.py +0 -0
  97. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/adapters.py +0 -0
  98. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/dashboard.py +0 -0
  99. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/static/__init__.py +0 -0
  100. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/static/app.js +0 -0
  101. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/static/index.html +0 -0
  102. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/src/by_framework_dashboard/static/styles.css +0 -0
  103. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-dashboard/tests/test_dashboard_server.py +0 -0
  104. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-byclaw/README.md +0 -0
  105. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-byclaw/pyproject.toml +0 -0
  106. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/__init__.py +0 -0
  107. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-byclaw/src/by_framework_history_byclaw/byclaw_history.py +0 -0
  108. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-byclaw/tests/test_byclaw_history.py +0 -0
  109. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-postgres/README.md +0 -0
  110. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-postgres/pyproject.toml +0 -0
  111. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-postgres/src/by_framework_history_postgres/__init__.py +0 -0
  112. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-postgres/src/by_framework_history_postgres/postgres.py +0 -0
  113. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-history-postgres/tests/test_postgres_history_storage.py +0 -0
  114. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/README.md +0 -0
  115. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/pyproject.toml +0 -0
  116. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/src/by_framework_langgraph/__init__.py +0 -0
  117. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/src/by_framework_langgraph/_utils.py +0 -0
  118. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/src/by_framework_langgraph/adapter.py +0 -0
  119. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/src/by_framework_langgraph/tools.py +0 -0
  120. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/src/by_framework_langgraph/worker.py +0 -0
  121. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/tests/test_adapter.py +0 -0
  122. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/tests/test_tools.py +0 -0
  123. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-langgraph/tests/test_utils.py +0 -0
  124. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-langfuse/README.md +0 -0
  125. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-langfuse/pyproject.toml +0 -0
  126. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/__init__.py +0 -0
  127. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-langfuse/src/by_framework_trace_langfuse/langfuse.py +0 -0
  128. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-langfuse/tests/test_langfuse_import.py +0 -0
  129. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-phoenix/README.md +0 -0
  130. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-phoenix/pyproject.toml +0 -0
  131. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/__init__.py +0 -0
  132. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-phoenix/src/by_framework_trace_phoenix/phoenix.py +0 -0
  133. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-phoenix/tests/test_phoenix_import.py +0 -0
  134. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-phoenix/tests/test_phoenix_plugin.py +0 -0
  135. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/pyproject.toml +0 -0
  136. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/src/by_framework_trace_query/__init__.py +0 -0
  137. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/src/by_framework_trace_query/client.py +0 -0
  138. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/src/by_framework_trace_query/merger.py +0 -0
  139. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/src/by_framework_trace_query/models.py +0 -0
  140. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/src/by_framework_trace_query/redis_source.py +0 -0
  141. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/libs/by-framework-trace-query/tests/test_trace_query_sdk.py +0 -0
  142. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/pylintrc +0 -0
  143. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/.map.conf +0 -0
  144. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/check-doc-discipline.sh +0 -0
  145. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/check-entry-freshness.sh +0 -0
  146. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/check-map-territory.sh +0 -0
  147. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/map-stop-hook.sh +0 -0
  148. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/python_quality.sh +0 -0
  149. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/test-growth-ladder.sh +0 -0
  150. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/scripts/verify.sh +0 -0
  151. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/__init__.py +0 -0
  152. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/__main__.py +0 -0
  153. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/admin/__init__.py +0 -0
  154. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/admin/cli.py +0 -0
  155. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/admin/worker_manager.py +0 -0
  156. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/client/__init__.py +0 -0
  157. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/client/byai_client.py +0 -0
  158. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/client/client.py +0 -0
  159. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/__init__.py +0 -0
  160. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/config.py +0 -0
  161. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/constants.py +0 -0
  162. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/emitter.py +0 -0
  163. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/exceptions.py +0 -0
  164. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/logger.py +0 -0
  165. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/common/redis_client.py +0 -0
  166. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/__init__.py +0 -0
  167. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/availability.py +0 -0
  168. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/delivery_gate.py +0 -0
  169. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/discovery.py +0 -0
  170. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/extensions/__init__.py +0 -0
  171. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/extensions/agent_config.py +0 -0
  172. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/extensions/agent_config_audit.py +0 -0
  173. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/extensions/plugin.py +0 -0
  174. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/extensions/registry.py +0 -0
  175. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/extensions/trace_provider.py +0 -0
  176. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/__init__.py +0 -0
  177. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/action_type.py +0 -0
  178. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/agent_state.py +0 -0
  179. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/byai_codec.py +0 -0
  180. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/byai_command.py +0 -0
  181. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/byai_types.py +0 -0
  182. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/commands.py +0 -0
  183. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/content_codec.py +0 -0
  184. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/content_type.py +0 -0
  185. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/data_message.py +0 -0
  186. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/data_shapes.py +0 -0
  187. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/event_type.py +0 -0
  188. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/events.py +0 -0
  189. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/message.py +0 -0
  190. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/message_header.py +0 -0
  191. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/responses.py +0 -0
  192. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/protocol/results.py +0 -0
  193. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/registry.py +0 -0
  194. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/__init__.py +0 -0
  195. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/agent_config_manager.py +0 -0
  196. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/agent_runtime_state.py +0 -0
  197. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/file_manager.py +0 -0
  198. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/file_paths.py +0 -0
  199. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/file_permissions.py +0 -0
  200. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/filestore/__init__.py +0 -0
  201. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/filestore/base.py +0 -0
  202. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/filestore/local.py +0 -0
  203. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/history/__init__.py +0 -0
  204. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/history/base.py +0 -0
  205. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/history/history_manager.py +0 -0
  206. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/history/in_memory.py +0 -0
  207. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/runtime/session_manager.py +0 -0
  208. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/wait_gate.py +0 -0
  209. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/wait_index.py +0 -0
  210. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/wait_reply.py +0 -0
  211. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/wakeup_controller.py +0 -0
  212. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/core/workspace.py +0 -0
  213. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/__init__.py +0 -0
  214. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/base.py +0 -0
  215. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/common.py +0 -0
  216. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/execution.py +0 -0
  217. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/http.py +0 -0
  218. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/protocol.py +0 -0
  219. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/errors/registry.py +0 -0
  220. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/metrics/__init__.py +0 -0
  221. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/metrics/catalog.py +0 -0
  222. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/metrics/collector.py +0 -0
  223. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/metrics/read_client.py +0 -0
  224. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/metrics/snapshot.py +0 -0
  225. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/trace/__init__.py +0 -0
  226. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/trace/external_trace.py +0 -0
  227. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/trace/span_recorder.py +0 -0
  228. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/trace/trace_schema.py +0 -0
  229. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/trace/trace_writer.py +0 -0
  230. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/util/__init__.py +0 -0
  231. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/util/discovery_http_client.py +0 -0
  232. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/util/generate_message_id.py +0 -0
  233. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/util/http_client.py +0 -0
  234. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/__init__.py +0 -0
  235. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/_control_handling.py +0 -0
  236. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/_execution_tracking.py +0 -0
  237. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/_message_processing.py +0 -0
  238. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/app.py +0 -0
  239. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/byai_context.py +0 -0
  240. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/byai_worker.py +0 -0
  241. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/health_server.py +0 -0
  242. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/heartbeat.py +0 -0
  243. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/processor.py +0 -0
  244. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/runner.py +0 -0
  245. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/sandbox/__init__.py +0 -0
  246. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/src/by_framework/worker/sandbox/hook_sandbox.py +0 -0
  247. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/admin/__init__.py +0 -0
  248. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/admin/test_cli.py +0 -0
  249. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/client/__init__.py +0 -0
  250. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/client/test_client.py +0 -0
  251. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/common/__init__.py +0 -0
  252. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/common/test_config.py +0 -0
  253. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/common/test_constants.py +0 -0
  254. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/common/test_exceptions.py +0 -0
  255. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/common/test_logger.py +0 -0
  256. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/common/test_redis_client.py +0 -0
  257. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/conftest.py +0 -0
  258. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/__init__.py +0 -0
  259. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/protocol/__init__.py +0 -0
  260. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/protocol/test_byai_codec.py +0 -0
  261. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/protocol/test_command_wire.py +0 -0
  262. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/protocol/test_protocol.py +0 -0
  263. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/protocol/test_results.py +0 -0
  264. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/history/__init__.py +0 -0
  265. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/history/test_history_persistence.py +0 -0
  266. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_file_access_context.py +0 -0
  267. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_file_manager_default_storage.py +0 -0
  268. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_file_paths.py +0 -0
  269. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_file_permissions.py +0 -0
  270. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_filestore_local_collection.py +0 -0
  271. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_filestore_local_mutation.py +0 -0
  272. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_filestore_local_read.py +0 -0
  273. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/runtime/test_filestore_local_search.py +0 -0
  274. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_agent_config_audit.py +0 -0
  275. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_availability.py +0 -0
  276. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_discovery.py +0 -0
  277. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_registry.py +0 -0
  278. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_wait_gate.py +0 -0
  279. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_wait_index.py +0 -0
  280. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/core/test_worker_manager.py +0 -0
  281. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/__init__.py +0 -0
  282. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/test_ask_user_flow.py +0 -0
  283. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/test_callback_flow.py +0 -0
  284. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/test_logger_integration.py +0 -0
  285. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/test_orphan_recovery.py +0 -0
  286. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/integration/test_scatter_gather.py +0 -0
  287. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/metrics/test_catalog.py +0 -0
  288. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/metrics/test_collector.py +0 -0
  289. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/metrics/test_metrics.py +0 -0
  290. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/metrics/test_read_client.py +0 -0
  291. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/metrics/test_snapshot.py +0 -0
  292. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/plugin/__init__.py +0 -0
  293. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/plugin/test_langfuse_plugin.py +0 -0
  294. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/plugin/test_plugin_discovery.py +0 -0
  295. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/plugin/test_plugin_improvements.py +0 -0
  296. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/plugin/test_plugin_registry.py +0 -0
  297. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/plugin/test_plugin_system.py +0 -0
  298. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/test_main.py +0 -0
  299. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/trace/test_external_trace.py +0 -0
  300. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/trace/test_logger_correlation.py +0 -0
  301. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/trace/test_otel_exporter.py +0 -0
  302. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/trace/test_span_recorder.py +0 -0
  303. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/trace/test_trace_writer.py +0 -0
  304. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/util/test_discovery_http_client.py +0 -0
  305. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/util/test_discovery_http_client_download.py +0 -0
  306. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/util/test_discovery_http_client_upload.py +0 -0
  307. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/util/test_http_client.py +0 -0
  308. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/__init__.py +0 -0
  309. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_admin_control_handling.py +0 -0
  310. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_app.py +0 -0
  311. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_byai_worker.py +0 -0
  312. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_control_handling.py +0 -0
  313. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_emitter.py +0 -0
  314. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_fetch_messages.py +0 -0
  315. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_health_server.py +0 -0
  316. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_heartbeat.py +0 -0
  317. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_message_processing.py +0 -0
  318. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_processor.py +0 -0
  319. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_runner.py +0 -0
  320. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_sandbox.py +0 -0
  321. {by_framework-0.2.2.dev12 → by_framework-0.2.2.dev13}/tests/worker/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: by-framework
3
- Version: 0.2.2.dev12
3
+ Version: 0.2.2.dev13
4
4
  Summary: 分布式 Agent 调度框架
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -194,9 +194,14 @@ Entry anatomy:
194
194
  and *no* reply — registration happens before the dispatch `xadd`, so a
195
195
  failed `xadd` leaves exactly that. Synthesized failures must stay shaped
196
196
  like a sub-agent's own failure (`error`/`error_code` in `reply_data`,
197
- same stream, same header id reversal). Two switches, and they must stay
198
- separate: *compensation* (the triage, replies, renewals, cancellation) is
199
- off unless `BY_FRAMEWORK_WAIT_SWEEPER_ENABLED` is set and is the rollback
197
+ same stream, same header id reversal). `_synthesize_failure()` seeds its
198
+ reply's metadata from `child.get("metadata")` the callee's execution
199
+ snapshot, where `context.py`'s `initialize_execution()` persists the
200
+ caller's original dispatch metadata — instead of an empty dict, so a
201
+ caller that never gets a real reply at all still gets its own metadata
202
+ back, consistent with every other reply shape to it. Two switches, and
203
+ they must stay separate: *compensation* (the triage, replies, renewals,
204
+ cancellation) is off unless `BY_FRAMEWORK_WAIT_SWEEPER_ENABLED` is set and is the rollback
200
205
  switch for the whole liveness feature, while *pruning* is on by default
201
206
  (`BY_FRAMEWORK_WAIT_PRUNE_ENABLED`) because nothing else ever removes a
202
207
  wait-index entry — with compensation off, every call whose reply never
@@ -340,6 +345,14 @@ Entry anatomy:
340
345
  `ask_user` round is the common one) posts its result to a control stream
341
346
  nobody consumes and, worse, stops emitting the end-of-stream event the user
342
347
  is waiting on, because it now believes it owes an agent a reply.
348
+ `_resolve_reply_command()` restores `header.metadata` from the same
349
+ execution snapshot (`existing_data["metadata"]`) as a full *replacement*,
350
+ never merged with the resuming command's own metadata: that metadata
351
+ belongs to whatever woke this execution up (an `ask_user` answer, or a
352
+ sub-call's reply), not to the original caller, and leaking it would let a
353
+ transient hop overwrite the caller's own data instead of being layered
354
+ under `task_result.metadata` like `_enqueue_agent_return()`'s merge
355
+ already does correctly.
343
356
  The success path must NOT reply while `context._is_suspended` — a suspended
344
357
  execution has no result, and forwarding the value the handler returned in
345
358
  order to unwind both wakes the caller early and consumes the single reply it
@@ -397,7 +410,12 @@ Entry anatomy:
397
410
  so: it is bookkeeping, not the dispatch.
398
411
  `initialize_execution()`'s payload carries `source_agent_type` and
399
412
  `task_group_id` because they are the only durable record of who a
400
- suspended callee owes its reply to (see `worker.py`).
413
+ suspended callee owes its reply to (see `worker.py`). It also carries
414
+ `metadata` (a copy of the dispatched `command.header.metadata`) for the
415
+ same reason: it is the only durable record of what the caller's metadata
416
+ *was*, and `worker.py`'s `_resolve_reply_command()` reads it back
417
+ verbatim so a caller's metadata survives however many times the callee
418
+ suspends and resumes before it finally replies.
401
419
  `_suspended_state` records *which* state the execution is waiting in and is
402
420
  what the framework persists; keep it set/rolled-back in lockstep with
403
421
  `_is_suspended`.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "by-framework"
3
- version = "0.2.2.dev12"
3
+ version = "0.2.2.dev13"
4
4
  description = "分布式 Agent 调度框架"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -999,7 +999,7 @@ class WaitIndexSweeper:
999
999
  ),
1000
1000
  extra_payload={},
1001
1001
  error_code=error_code,
1002
- metadata={},
1002
+ metadata=dict(child.get("metadata") or {}),
1003
1003
  )
1004
1004
  return outcome if emitted else OUTCOME_UNROUTABLE
1005
1005
 
@@ -875,6 +875,11 @@ class AgentContext:
875
875
  # the reply belongs to — the resume message itself
876
876
  # describes the hop that woke it, not this dispatch.
877
877
  "task_group_id": task_group_id,
878
+ # A's original dispatch metadata, so a resumed reply
879
+ # can restore it as the base layer instead of
880
+ # inheriting whatever message last woke this
881
+ # execution up (see _resolve_reply_command).
882
+ "metadata": dict(command.header.metadata),
878
883
  "stream_name": delivery_stream,
879
884
  "status": "QUEUED",
880
885
  "route_policy": route_policy,
@@ -343,6 +343,14 @@ class GatewayWorker(ABC):
343
343
  Treating "is a resume" as "has no caller" is what used to make an
344
344
  A -> B -> C chain silently drop B's result on the floor.
345
345
 
346
+ ``header.metadata`` is restored the same way, as a full replacement
347
+ rather than a merge with the waking message's own metadata: the
348
+ waking message (an ``ask_user`` answer, or a sub-call's reply) is
349
+ transient plumbing for that hop, not something A ever sent or asked
350
+ for. If A's original metadata is missing from the snapshot (an
351
+ execution recorded before this field existed), this degrades to an
352
+ empty dict rather than leaking the waking message's metadata to A.
353
+
346
354
  A root execution's record names ``CLIENT_SOURCE_AGENT_TYPE`` as its
347
355
  source, which is a marker rather than an agent type — it has to be
348
356
  excluded explicitly, or every client-dispatched execution that ever
@@ -365,6 +373,7 @@ class GatewayWorker(ABC):
365
373
  source_agent_type=caller_agent_type,
366
374
  parent_message_id=str(snapshot.get("parent_message_id", "") or ""),
367
375
  task_group_id=str(snapshot.get("task_group_id", "") or ""),
376
+ metadata=dict(snapshot.get("metadata") or {}),
368
377
  ),
369
378
  )
370
379
 
@@ -456,6 +456,10 @@ class TestOddEntries(unittest.IsolatedAsyncioTestCase):
456
456
  target_agent_type="agent-b",
457
457
  status=AgentState.COMPLETED.value,
458
458
  worker_id="worker-b",
459
+ # A's original dispatch metadata, persisted at
460
+ # initialize_execution() time: the synthesized failure must
461
+ # restore it instead of emitting an empty dict.
462
+ metadata={"caller": "original", "request_id": "req-1"},
459
463
  )
460
464
  _due_member(
461
465
  self.redis,
@@ -475,6 +479,13 @@ class TestOddEntries(unittest.IsolatedAsyncioTestCase):
475
479
  reply["body"]["reply_data"]["error_code"],
476
480
  LivenessErrorCode.REPLY_LOST_RECOVERED,
477
481
  )
482
+ # A's original metadata rides along the synthesized failure, same as
483
+ # every other reply shape to A — not discarded as `{}`.
484
+ reply_metadata = reply["header"]["metadata"]
485
+ self.assertEqual(reply_metadata["caller"], "original")
486
+ self.assertEqual(reply_metadata["request_id"], "req-1")
487
+ # The sweeper's own provenance keys still ride on top.
488
+ self.assertEqual(reply_metadata["synthesized_by"], "wait_sweeper")
478
489
 
479
490
  async def test_dead_worker_reply_mirrors_a_real_agent_return(self):
480
491
  self._add_suspended_caller()
@@ -219,10 +219,13 @@ class WorkspaceManagerStub:
219
219
  class ChainAgent(GatewayWorker):
220
220
  """Calls `next_agent_type` on first contact, answers on resume."""
221
221
 
222
- def __init__(self, agent_type, next_agent_type, *args, **kwargs):
222
+ def __init__(
223
+ self, agent_type, next_agent_type, *args, dispatch_metadata=None, **kwargs
224
+ ):
223
225
  super().__init__(*args, **kwargs)
224
226
  self.agent_type = agent_type
225
227
  self.next_agent_type = next_agent_type
228
+ self.dispatch_metadata = dispatch_metadata
226
229
  self.dispatch_calls = 0
227
230
  self.resume_payloads: list[Any] = []
228
231
 
@@ -235,12 +238,20 @@ class ChainAgent(GatewayWorker):
235
238
  return {
236
239
  "status": AgentState.COMPLETED.value,
237
240
  "reply_data": {"from": self.agent_type, "sub": command.reply_data},
241
+ # Own metadata this link contributes: must override
242
+ # same-named keys from whatever it was dispatched with, while
243
+ # leaving other inherited keys untouched.
244
+ "metadata": {
245
+ "agent": self.agent_type,
246
+ "tag": f"from-{self.agent_type}",
247
+ },
238
248
  }
239
249
  self.dispatch_calls += 1
240
250
  await context.call_agent(
241
251
  target_agent_type=self.next_agent_type,
242
252
  content="delegate",
243
253
  wait_for_reply=True,
254
+ metadata=self.dispatch_metadata,
244
255
  )
245
256
  return {"status": AgentState.QUEUED.value}
246
257
 
@@ -261,6 +272,9 @@ class AskingMiddleAgent(GatewayWorker):
261
272
  return {
262
273
  "status": AgentState.COMPLETED.value,
263
274
  "reply_data": {"from": "agent-b", "user_said": command.content},
275
+ # Own metadata this link contributes: must override
276
+ # same-named keys from A's original dispatch metadata.
277
+ "metadata": {"agent": "agent-b", "tag": "from-agent-b"},
264
278
  }
265
279
  return await context.ask_user("which colour?")
266
280
 
@@ -318,7 +332,17 @@ class TestNestedChain(unittest.IsolatedAsyncioTestCase):
318
332
  workspace = WorkspaceManagerStub()
319
333
 
320
334
  self.agent_a = ChainAgent(
321
- "agent-a", "agent-b", "worker-a", self.redis, self.registry, workspace
335
+ "agent-a",
336
+ "agent-b",
337
+ "worker-a",
338
+ self.redis,
339
+ self.registry,
340
+ workspace,
341
+ # A's own dispatch metadata to B: the "A's original metadata"
342
+ # this task is about. Must reach A's own reply intact even
343
+ # though B suspends (via a nested call_agent to C) before B
344
+ # finally replies.
345
+ dispatch_metadata={"caller": "agent-a", "tag": "keep"},
322
346
  )
323
347
  self.agent_b = ChainAgent(
324
348
  "agent-b", "agent-c", "worker-b", self.redis, self.registry, workspace
@@ -373,6 +397,12 @@ class TestNestedChain(unittest.IsolatedAsyncioTestCase):
373
397
  # Addressed to A's suspended execution, and identifying B's sub-task.
374
398
  self.assertEqual(reply.header.message_id, "msg-root")
375
399
  self.assertEqual(reply.header.source_agent_type, "agent-b")
400
+ # A's own dispatch metadata to B survives B suspending on a nested
401
+ # call_agent to C, and B's own returned metadata overrides same-named
402
+ # keys instead of being discarded or replacing the whole dict.
403
+ self.assertEqual(reply.header.metadata["caller"], "agent-a")
404
+ self.assertEqual(reply.header.metadata["tag"], "from-agent-b")
405
+ self.assertEqual(reply.header.metadata["agent"], "agent-b")
376
406
 
377
407
  await self._step("agent-a") # A resumes with B's answer
378
408
 
@@ -437,7 +467,15 @@ class TestSubAgentAsksTheUser(unittest.IsolatedAsyncioTestCase):
437
467
  workspace = WorkspaceManagerStub()
438
468
 
439
469
  self.agent_a = ChainAgent(
440
- "agent-a", "agent-b", "worker-a", self.redis, self.registry, workspace
470
+ "agent-a",
471
+ "agent-b",
472
+ "worker-a",
473
+ self.redis,
474
+ self.registry,
475
+ workspace,
476
+ # A's own dispatch metadata to B: must reach A's reply intact
477
+ # even though B suspends on ask_user before it replies.
478
+ dispatch_metadata={"caller": "agent-a", "tag": "keep"},
441
479
  )
442
480
  self.agent_b = AskingMiddleAgent(
443
481
  "worker-b", self.redis, self.registry, workspace
@@ -472,7 +510,7 @@ class TestSubAgentAsksTheUser(unittest.IsolatedAsyncioTestCase):
472
510
  await runner._run_once()
473
511
  await runner.wait_for_tasks()
474
512
 
475
- async def _answer_the_user_prompt(self, message_id, answer="Pink"):
513
+ async def _answer_the_user_prompt(self, message_id, answer="Pink", metadata=None):
476
514
  """What a client sends when the person replies.
477
515
 
478
516
  `GatewayClient.send_message(action_type=RESUME)` reuses the suspended
@@ -487,6 +525,7 @@ class TestSubAgentAsksTheUser(unittest.IsolatedAsyncioTestCase):
487
525
  session_id=self.session_id,
488
526
  trace_id="trace-ask",
489
527
  target_agent_type="agent-b",
528
+ metadata=metadata or {},
490
529
  ),
491
530
  content=answer,
492
531
  ).to_redis_payload(),
@@ -512,7 +551,12 @@ class TestSubAgentAsksTheUser(unittest.IsolatedAsyncioTestCase):
512
551
  await self._step("agent-b")
513
552
  b_dispatch = _dispatched_message_id(self.redis, "agent-b")
514
553
 
515
- await self._answer_the_user_prompt(b_dispatch)
554
+ await self._answer_the_user_prompt(
555
+ b_dispatch,
556
+ # The answering client's own metadata for this hop: transient
557
+ # plumbing that must not leak through to A.
558
+ metadata={"caller": "should-not-leak", "client_tag": "should-not-leak"},
559
+ )
516
560
  await self._step("agent-b")
517
561
 
518
562
  self.assertEqual(self.agent_b.user_answers, ["Pink"])
@@ -522,6 +566,14 @@ class TestSubAgentAsksTheUser(unittest.IsolatedAsyncioTestCase):
522
566
  # record its own dispatch wrote, which is the whole point.
523
567
  self.assertEqual(replies_to_a[0].header.message_id, "msg-root")
524
568
  self.assertEqual(replies_to_a[0].header.source_agent_type, "agent-b")
569
+ # A's own dispatch metadata to B survives the ask_user round-trip —
570
+ # it is NOT replaced by the answering client's own resume metadata —
571
+ # and B's own returned metadata overrides same-named keys.
572
+ reply_metadata = replies_to_a[0].header.metadata
573
+ self.assertEqual(reply_metadata["caller"], "agent-a")
574
+ self.assertEqual(reply_metadata["tag"], "from-agent-b")
575
+ self.assertEqual(reply_metadata["agent"], "agent-b")
576
+ self.assertNotIn("client_tag", reply_metadata)
525
577
 
526
578
  await self._step("agent-a")
527
579
 
@@ -1508,3 +1508,34 @@ async def test_dispatch_records_task_group_id_on_the_execution():
1508
1508
  payload = init_execution.await_args.args[0]
1509
1509
  assert payload["task_group_id"] == group["task_group_id"]
1510
1510
  assert payload["source_agent_type"] == "agent-a"
1511
+
1512
+
1513
+ @pytest.mark.asyncio
1514
+ async def test_dispatch_records_caller_metadata_on_the_execution():
1515
+ """A resumed sub-task rebuilds its reply header's metadata from this
1516
+ snapshot, not from whatever message wakes it — so the caller's original
1517
+ metadata has to be persisted here, same as the routing fields above."""
1518
+ from unittest.mock import patch
1519
+
1520
+ mock_redis = _online_redis()
1521
+ ctx = AgentContext(
1522
+ session_id="s1",
1523
+ trace_id="t1",
1524
+ redis_client=mock_redis,
1525
+ current_agent_id="agent-a",
1526
+ message_id="parent-msg",
1527
+ )
1528
+
1529
+ with patch(
1530
+ "by_framework.core.registry.WorkerRegistry.initialize_execution",
1531
+ new_callable=AsyncMock,
1532
+ ) as init_execution:
1533
+ await ctx.call_agent(
1534
+ target_agent_type="agent-b",
1535
+ content="one",
1536
+ metadata={"caller": "agent-a", "request_id": "req-1"},
1537
+ )
1538
+
1539
+ payload = init_execution.await_args.args[0]
1540
+ assert payload["metadata"]["caller"] == "agent-a"
1541
+ assert payload["metadata"]["request_id"] == "req-1"
@@ -1017,6 +1017,10 @@ async def test_resumed_execution_replies_to_its_own_caller_not_the_sub_agent(tmp
1017
1017
  target_agent_type="structured_agent",
1018
1018
  parent_message_id="msg-c", # B's sub-task
1019
1019
  task_group_id="tg-of-c", # B's OWN group, not the one B belongs to
1020
+ # C's own metadata for this hop: transient plumbing that must not
1021
+ # leak through to A — A's original metadata below is the base
1022
+ # instead.
1023
+ metadata={"caller": "should-not-leak", "from_c": "should-not-leak"},
1020
1024
  ),
1021
1025
  status=AgentState.COMPLETED.value,
1022
1026
  reply_data={"from": "c"},
@@ -1038,6 +1042,9 @@ async def test_resumed_execution_replies_to_its_own_caller_not_the_sub_agent(tmp
1038
1042
  "source_agent_type": "agent-a",
1039
1043
  "parent_message_id": "msg-a",
1040
1044
  "task_group_id": "tg-of-a",
1045
+ # A's original dispatch metadata, persisted at
1046
+ # initialize_execution() time.
1047
+ "metadata": {"caller": "original", "request_id": "req-1"},
1041
1048
  **snapshot_fields,
1042
1049
  },
1043
1050
  )
@@ -1055,6 +1062,13 @@ async def test_resumed_execution_replies_to_its_own_caller_not_the_sub_agent(tmp
1055
1062
  assert reply.header.task_group_id == "tg-of-a"
1056
1063
  assert reply.header.source_agent_type == "structured_agent"
1057
1064
  assert reply.reply_data == {"answer": 42}
1065
+ # A's original metadata is the base, B's own task_result.metadata
1066
+ # (StructuredResultWorker returns {"tokens": 123, "caller": "overridden"})
1067
+ # overrides same-named keys; C's waking metadata does not leak through.
1068
+ assert reply.header.metadata["caller"] == "overridden"
1069
+ assert reply.header.metadata["request_id"] == "req-1"
1070
+ assert reply.header.metadata["tokens"] == 123
1071
+ assert "from_c" not in reply.header.metadata
1058
1072
 
1059
1073
 
1060
1074
  @pytest.mark.asyncio
@@ -315,7 +315,7 @@ wheels = [
315
315
 
316
316
  [[package]]
317
317
  name = "by-framework"
318
- version = "0.2.2.dev12"
318
+ version = "0.2.2.dev13"
319
319
  source = { editable = "." }
320
320
  dependencies = [
321
321
  { name = "dill" },