bazaar-compute-node 0.2.0rc1__tar.gz → 0.2.0rc2__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 (201) hide show
  1. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/PKG-INFO +5 -2
  2. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/README.md +4 -1
  3. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/pyproject.toml +1 -1
  4. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/pyproject.toml.orig +1 -1
  5. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent.py +9 -1
  6. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/approval.py +8 -2
  7. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/channel.py +36 -1
  8. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/outbound.py +2 -1
  9. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/telegram/plugin.py +43 -0
  10. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/audit.py +154 -0
  11. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/channel.py +2 -0
  12. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/command.py +2 -2
  13. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/error_feedback.py +1 -2
  14. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/orchestrator.py +4 -9
  15. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/orchestration/services.py +30 -0
  16. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/turn.py +1 -2
  17. bazaar_compute_node-0.2.0rc1/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -23
  18. bazaar_compute_node-0.2.0rc1/src/bazaar_compute_node/core/audit.py +0 -70
  19. bazaar_compute_node-0.2.0rc1/src/bazaar_compute_node/core/orchestration/services.py +0 -118
  20. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/LICENSE +0 -0
  21. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/__init__.py +0 -0
  22. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/__init__.py +0 -0
  23. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent_management.py +0 -0
  24. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/application.py +0 -0
  25. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/attachments.py +0 -0
  26. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/command.py +0 -0
  27. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/config.py +0 -0
  28. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/registry.py +0 -0
  29. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/resource_dispatch.py +0 -0
  30. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/system_service.py +0 -0
  31. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/transport.py +0 -0
  32. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/upgrade.py +0 -0
  33. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/usage.py +0 -0
  34. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/version_check.py +0 -0
  35. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/windows_pipe.py +0 -0
  36. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/wrapper.py +0 -0
  37. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/bcc.py +0 -0
  38. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cli.py +0 -0
  39. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/__init__.py +0 -0
  40. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/__init__.py +0 -0
  41. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/_client.py +0 -0
  42. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/_format.py +0 -0
  43. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/inbox.py +0 -0
  44. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/message.py +0 -0
  45. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/node.py +0 -0
  46. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/reminder.py +0 -0
  47. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/thread.py +0 -0
  48. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/__init__.py +0 -0
  49. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/_options.py +0 -0
  50. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/_runner.py +0 -0
  51. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/agent.py +0 -0
  52. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/node.py +0 -0
  53. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/service.py +0 -0
  54. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/__init__.py +0 -0
  55. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/__init__.py +0 -0
  56. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/approval.py +0 -0
  57. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/client.py +0 -0
  58. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/events.py +0 -0
  59. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/plugin.py +0 -0
  60. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/process.py +0 -0
  61. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/protocol.py +0 -0
  62. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/runtime.py +0 -0
  63. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
  64. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/approval.py +0 -0
  65. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
  66. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/events.py +0 -0
  67. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
  68. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/process.py +0 -0
  69. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
  70. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/runtime.py +0 -0
  71. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/__init__.py +0 -0
  72. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/api.py +0 -0
  73. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/approval.py +0 -0
  74. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/attachments.py +0 -0
  75. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/channel.py +0 -0
  76. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/frame.py +0 -0
  77. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/identity.py +0 -0
  78. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/outbound.py +0 -0
  79. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/plugin.py +0 -0
  80. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/transport.py +0 -0
  81. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
  82. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/audit.py +0 -0
  83. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
  84. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
  85. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/codec.py +0 -0
  86. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/database.py +0 -0
  87. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/executor.py +0 -0
  88. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/__init__.py +0 -0
  89. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/model.py +0 -0
  90. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/registry.py +0 -0
  91. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v01_initial_node_schema.py +0 -0
  92. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v02_session_mapping_indexes.py +0 -0
  93. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v03_message_log_indexes.py +0 -0
  94. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v04_runtime_attempt_facts.py +0 -0
  95. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v05_inbound_message_references.py +0 -0
  96. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v06_inbound_message_reference_integrity.py +0 -0
  97. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v07_inbound_provider_identity.py +0 -0
  98. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v08_transient_stream_events.py +0 -0
  99. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v09_remove_runtime_events.py +0 -0
  100. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v10_add_outbound_attachments.py +0 -0
  101. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v11_remove_runtime_session_mapping.py +0 -0
  102. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v12_add_reminders.py +0 -0
  103. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v13_add_agent_ownership.py +0 -0
  104. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v14_add_inbox_discovery_indexes.py +0 -0
  105. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v15_add_handoffs.py +0 -0
  106. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v16_remove_outbound_drafts.py +0 -0
  107. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v17_remove_agent_identity_triggers.py +0 -0
  108. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v18_unify_messages.py +0 -0
  109. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v19_reminder_system_messages.py +0 -0
  110. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v20_remove_freshness_persistence.py +0 -0
  111. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v21_remove_handoffs.py +0 -0
  112. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v22_readable_targets.py +0 -0
  113. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v23_persist_sender_identity.py +0 -0
  114. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v24_persist_sender_display_name.py +0 -0
  115. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v25_rename_sessions_to_threads.py +0 -0
  116. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v26_remove_handoff_messages.py +0 -0
  117. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
  118. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +0 -0
  119. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/__init__.py +0 -0
  120. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/base.py +0 -0
  121. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/facade.py +0 -0
  122. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/messages.py +0 -0
  123. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/reminders.py +0 -0
  124. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/sessions.py +0 -0
  125. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/storage.py +0 -0
  126. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
  127. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/api.py +0 -0
  128. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/attachments.py +0 -0
  129. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
  130. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/markdown.py +0 -0
  131. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
  132. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/channel.py +0 -0
  133. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
  134. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
  135. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/__init__.py +0 -0
  136. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/actor.py +0 -0
  137. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/agent.py +0 -0
  138. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/approval.py +0 -0
  139. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/client.py +0 -0
  140. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/command.py +0 -0
  141. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/concurrency.py +0 -0
  142. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/correlation.py +0 -0
  143. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/inbox.py +0 -0
  144. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/instruction.py +0 -0
  145. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/lifecycle.py +0 -0
  146. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/__init__.py +0 -0
  147. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/entities.py +0 -0
  148. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/events.py +0 -0
  149. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/reminder.py +0 -0
  150. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/reminder_owner.py +0 -0
  151. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/states.py +0 -0
  152. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/observability.py +0 -0
  153. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/__init__.py +0 -0
  154. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
  155. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/reminder.py +0 -0
  156. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/reminder_command.py +0 -0
  157. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/upgrade_notice.py +0 -0
  158. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/outcomes.py +0 -0
  159. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/paths.py +0 -0
  160. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/reminder.py +0 -0
  161. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
  162. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/restart.py +0 -0
  163. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/runtime.py +0 -0
  164. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/storage.py +0 -0
  165. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/timerwheel.py +0 -0
  166. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/__init__.py +0 -0
  167. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/clock.py +0 -0
  168. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/line_reader.py +0 -0
  169. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/markdown.py +0 -0
  170. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/sanitization.py +0 -0
  171. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/text.py +0 -0
  172. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/i18n/__init__.py +0 -0
  173. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/i18n/catalog.py +0 -0
  174. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/rendering.py +0 -0
  175. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/approval_no_person.tpl +0 -0
  176. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/check.tpl +0 -0
  177. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/error.tpl +0 -0
  178. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/inbox_check.tpl +0 -0
  179. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/read.tpl +0 -0
  180. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_list.tpl +0 -0
  181. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_mutation.tpl +0 -0
  182. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_schedule.tpl +0 -0
  183. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/unfollow.tpl +0 -0
  184. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/upgrade.tpl +0 -0
  185. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/version.tpl +0 -0
  186. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/attachment_suffix.tpl +0 -0
  187. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/check_message.tpl +0 -0
  188. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/freshness_hold.tpl +0 -0
  189. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/read_message.tpl +0 -0
  190. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/send_result.tpl +0 -0
  191. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/sender.tpl +0 -0
  192. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/developer_instructions.md +0 -0
  193. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/inbox_notice.tpl +0 -0
  194. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/locales/en.toml +0 -0
  195. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/locales/zh-CN.toml +0 -0
  196. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/launchd.plist +0 -0
  197. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/launchd.sh +0 -0
  198. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/systemd.service +0 -0
  199. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.ps1 +0 -0
  200. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.vbs +0 -0
  201. {bazaar_compute_node-0.2.0rc1 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.xml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bazaar-compute-node
3
- Version: 0.2.0rc1
3
+ Version: 0.2.0rc2
4
4
  Summary: Runtime-agnostic computer node daemon for agents and channels.
5
5
  License-Expression: AGPL-3.0-only
6
6
  License-File: LICENSE
@@ -51,11 +51,14 @@ bcn --version
51
51
  uv tool upgrade bazaar-compute-node
52
52
 
53
53
  # Add an Agent / 添加 Agent
54
+ # allowed_sender_ids holds the Telegram user ids allowed to open a private chat
55
+ # allowed_sender_ids 是允许与其私聊的 Telegram 用户 id
54
56
  bcn agent add \
55
57
  --name Tifa \
56
58
  --channel telegram \
57
59
  --runtime codex \
58
- --set channel.token_env=BCN_TELEGRAM_TIFA_TOKEN
60
+ --set channel.token_env=BCN_TELEGRAM_TIFA_TOKEN \
61
+ --set channel.allowed_sender_ids=[123456789]
59
62
 
60
63
  # Configure the runtime environment / 配置运行时环境
61
64
  # Example file content / 示例文件内容:
@@ -32,11 +32,14 @@ bcn --version
32
32
  uv tool upgrade bazaar-compute-node
33
33
 
34
34
  # Add an Agent / 添加 Agent
35
+ # allowed_sender_ids holds the Telegram user ids allowed to open a private chat
36
+ # allowed_sender_ids 是允许与其私聊的 Telegram 用户 id
35
37
  bcn agent add \
36
38
  --name Tifa \
37
39
  --channel telegram \
38
40
  --runtime codex \
39
- --set channel.token_env=BCN_TELEGRAM_TIFA_TOKEN
41
+ --set channel.token_env=BCN_TELEGRAM_TIFA_TOKEN \
42
+ --set channel.allowed_sender_ids=[123456789]
40
43
 
41
44
  # Configure the runtime environment / 配置运行时环境
42
45
  # Example file content / 示例文件内容:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bazaar-compute-node"
3
- version = "0.2.0rc1"
3
+ version = "0.2.0rc2"
4
4
  description = "Runtime-agnostic computer node daemon for agents and channels."
5
5
  readme = "README.md"
6
6
  license = "AGPL-3.0-only"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bazaar-compute-node"
3
- version = "0.2.0rc1"
3
+ version = "0.2.0rc2"
4
4
  description = "Runtime-agnostic computer node daemon for agents and channels."
5
5
  readme = "README.md"
6
6
  license = "AGPL-3.0-only"
@@ -13,6 +13,7 @@ from functools import partial
13
13
  from pathlib import Path
14
14
 
15
15
  from ..core.actor import Actor, Actors, Agent, Thread
16
+ from ..core.audit import AuditRecorder
16
17
  from ..core.channel import Channel, ChannelContext, IChannel
17
18
  from ..core.concurrency import IThreadConcurrency, ThreadLockRegistry
18
19
  from ..core.lifecycle import TimeoutBudget
@@ -28,6 +29,7 @@ from ..core.paths import resolve_workspace_dir
28
29
  from ..core.runtime import IRuntime, RuntimeCommandContext
29
30
  from ..core.storage import IStorageScope
30
31
  from ..core.timerwheel import TimerWheel
32
+ from ..core.utils.clock import now_ms
31
33
  from ..i18n import Translator
32
34
  from .attachments import AttachmentMaterializer
33
35
  from .command import CommandDispatchError
@@ -104,6 +106,11 @@ class AgentApplication:
104
106
  self.workspace_path,
105
107
  self._referenced_attachment_paths,
106
108
  )
109
+ self._audit_recorder = AuditRecorder(
110
+ sink=audit,
111
+ timeout_budget=timeout_budget,
112
+ clock=now_ms,
113
+ )
107
114
  provider_channel = factories.channel.build(
108
115
  ChannelContext(
109
116
  agent_id=self.agent_id,
@@ -112,6 +119,7 @@ class AgentApplication:
112
119
  workspace=self.workspace_path,
113
120
  translator=self.translator,
114
121
  timer_wheel=self.timer_wheel,
122
+ audit=self._audit_recorder,
115
123
  )
116
124
  )
117
125
  self.channel: IChannel = Channel(self.agent_id, provider_channel)
@@ -163,7 +171,7 @@ class AgentApplication:
163
171
  channel=self.channel,
164
172
  runtimes=self.runtimes,
165
173
  storage=self.storage,
166
- audit=self.audit,
174
+ audit=self._audit_recorder,
167
175
  timeout_budget=self.timeout_budget,
168
176
  timer_wheel=self.timer_wheel,
169
177
  runtime_idle_timeout_ms=(
@@ -36,8 +36,14 @@ class _PendingApproval:
36
36
 
37
37
 
38
38
  class TelegramApprovalChannel(TelegramChannel):
39
- def __init__(self, context: ChannelContext, *, token: str) -> None:
40
- super().__init__(context, token=token)
39
+ def __init__(
40
+ self,
41
+ context: ChannelContext,
42
+ *,
43
+ token: str,
44
+ allowed_sender_ids: frozenset[int],
45
+ ) -> None:
46
+ super().__init__(context, token=token, allowed_sender_ids=allowed_sender_ids)
41
47
  self._translator: Translator = context.translator or create_translator(ENGLISH)
42
48
  self._pending_approvals: dict[str, _PendingApproval] = {}
43
49
  self._approval_tokens_by_request: dict[str, str] = {}
@@ -17,6 +17,7 @@ from ...core.channel import (
17
17
  ChannelSendRequest,
18
18
  IChannel,
19
19
  )
20
+ from ...core.correlation import CorrelationContext
20
21
  from ...core.models import (
21
22
  ApprovalDecision,
22
23
  ApprovalResult,
@@ -28,6 +29,7 @@ from ...core.models import (
28
29
  InboundAttachment,
29
30
  Message,
30
31
  MessageDirection,
32
+ RuntimeEventState,
31
33
  RuntimeOutputEvent,
32
34
  SenderIdentity,
33
35
  SenderKind,
@@ -44,6 +46,7 @@ from ...core.models import (
44
46
  TurnUnknown,
45
47
  UsageUpdated,
46
48
  )
49
+ from ...core.observability import LogLevel
47
50
  from ...core.outcomes import ProviderCallResult, ProviderCallStatus
48
51
  from ...core.timerwheel import TimerWheel
49
52
  from .api import TelegramApiError, TelegramBotApi, TelegramTransportError
@@ -95,9 +98,16 @@ class _InboundUpdate:
95
98
 
96
99
 
97
100
  class TelegramChannel(IChannel):
98
- def __init__(self, context: ChannelContext, *, token: str) -> None:
101
+ def __init__(
102
+ self,
103
+ context: ChannelContext,
104
+ *,
105
+ token: str,
106
+ allowed_sender_ids: frozenset[int],
107
+ ) -> None:
99
108
  self._context = context
100
109
  self._token = token
110
+ self._allowed_sender_ids = allowed_sender_ids
101
111
  self._timer_wheel: TimerWheel | None = context.timer_wheel
102
112
  self._started_at_s = time_ns() // 1_000_000_000
103
113
  self._inbound: asyncio.Queue[Message | object] = asyncio.Queue()
@@ -653,6 +663,31 @@ class TelegramChannel(IChannel):
653
663
  chat_type = chat.get("type")
654
664
  if chat_type not in {"private", "group", "supergroup"}:
655
665
  return "unsupported_chat_type"
666
+ # Anyone on Telegram can open a private chat with a bot. A group has to
667
+ # be joined, so only the private case is closed here.
668
+ if chat_type == "private" and not (
669
+ isinstance(provider_sender, Mapping)
670
+ and provider_sender.get("id") in self._allowed_sender_ids
671
+ ):
672
+ audit = self._context.audit
673
+ if audit is not None:
674
+ await audit.append(
675
+ event_name="channel.inbound.rejected",
676
+ state=RuntimeEventState.COMPLETED,
677
+ correlation=CorrelationContext(
678
+ node_id=self._context.agent_id,
679
+ channel=self.name,
680
+ ),
681
+ level=LogLevel.WARNING,
682
+ metadata={
683
+ "reason": "unauthorized_sender",
684
+ "telegram_sender_id": provider_sender.get("id")
685
+ if isinstance(provider_sender, Mapping)
686
+ else None,
687
+ "telegram_chat_id": chat.get("id"),
688
+ },
689
+ )
690
+ return "unauthorized_sender"
656
691
  chat_id = chat.get("id")
657
692
  provider_message_id = message.get("message_id")
658
693
  provider_time_s = message.get("date")
@@ -64,8 +64,9 @@ class TelegramOutboundChannel(TelegramApprovalChannel):
64
64
  context: ChannelContext,
65
65
  *,
66
66
  token: str,
67
+ allowed_sender_ids: frozenset[int],
67
68
  ) -> None:
68
- super().__init__(context, token=token)
69
+ super().__init__(context, token=token, allowed_sender_ids=allowed_sender_ids)
69
70
  self._outbound_requests = 0
70
71
  self._outbound_confirmed_requests = 0
71
72
  self._outbound_partial_requests = 0
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import cast
5
+
6
+ from ...core.channel import ChannelContext, IChannel, IChannelBuilder
7
+ from .outbound import TelegramOutboundChannel
8
+
9
+
10
+ class TelegramBuilder(IChannelBuilder):
11
+ def build(self, context: ChannelContext) -> IChannel:
12
+ token_env = context.options.get("token_env")
13
+ if not isinstance(token_env, str) or not token_env:
14
+ raise ValueError("agent.channel.token_env is required for telegram")
15
+ token = os.environ.get(token_env)
16
+ if token is None or not token.strip():
17
+ raise ValueError(f"telegram credential environment is missing: {token_env}")
18
+ raw_allowed = context.options.get("allowed_sender_ids")
19
+ if not isinstance(raw_allowed, list) or not raw_allowed:
20
+ raise ValueError(
21
+ "agent.channel.allowed_sender_ids is required for telegram "
22
+ "and must be a non-empty list"
23
+ )
24
+ # A username can be changed at will, so it cannot carry authority;
25
+ # only the numeric id can.
26
+ if any(
27
+ not isinstance(sender_id, int) or isinstance(sender_id, bool)
28
+ for sender_id in cast(list[object], raw_allowed)
29
+ ):
30
+ raise ValueError(
31
+ "agent.channel.allowed_sender_ids must hold Telegram user ids"
32
+ )
33
+ return TelegramOutboundChannel(
34
+ context,
35
+ token=token,
36
+ allowed_sender_ids=frozenset(cast(list[int], raw_allowed)),
37
+ )
38
+
39
+
40
+ builder = TelegramBuilder()
41
+
42
+
43
+ __all__ = ["TelegramBuilder", "builder"]
@@ -0,0 +1,154 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from collections.abc import Callable, Mapping
6
+ from dataclasses import dataclass, field
7
+ from enum import StrEnum
8
+ from typing import cast
9
+
10
+ from .correlation import CorrelationContext
11
+ from .lifecycle import TimeoutBudget
12
+ from .models import RuntimeEventState
13
+ from .observability import IAudit, LogLevel
14
+ from .utils.sanitization import is_sensitive_field, omit_sensitive_fields
15
+
16
+
17
+ class ErrorKind(StrEnum):
18
+ CANCELLED = "cancelled"
19
+ TIMEOUT = "timeout"
20
+ VALIDATION = "validation"
21
+ SESSION_NOT_FOUND = "session_not_found"
22
+ TARGET_NOT_REPLYABLE = "target_not_replyable"
23
+ EMPTY_BODY = "empty_body"
24
+ FRESH_CHECK_REQUIRED = "fresh_check_required"
25
+ FRESH_CHECK_FAILED = "fresh_check_failed"
26
+ PROVIDER_FAILED = "provider_failed"
27
+ PROVIDER_PARTIAL = "provider_partial"
28
+ PROVIDER_UNKNOWN = "provider_unknown"
29
+ PROTOCOL = "protocol"
30
+ STORAGE = "storage"
31
+ SHUTDOWN_TIMEOUT = "shutdown_timeout"
32
+ INTERNAL = "internal"
33
+
34
+
35
+ @dataclass(frozen=True, slots=True)
36
+ class AuditEvent:
37
+ """Sanitized append-only event contract shared by all adapters."""
38
+
39
+ event_name: str
40
+ state: RuntimeEventState
41
+ created_at_ms: int
42
+ correlation: CorrelationContext
43
+ level: LogLevel = LogLevel.INFO
44
+ duration_ms: int | None = None
45
+ error_kind: ErrorKind | None = None
46
+ error_type: str | None = None
47
+ error_message: str | None = None
48
+ traceback_ref: str | None = None
49
+ metadata: Mapping[str, object] = field(default_factory=dict)
50
+
51
+ def __post_init__(self) -> None:
52
+ if self.error_kind is None and any(
53
+ value is not None
54
+ for value in (
55
+ self.error_type,
56
+ self.error_message,
57
+ self.traceback_ref,
58
+ )
59
+ ):
60
+ raise ValueError("error details require an error_kind")
61
+ pending: list[object] = [self.metadata]
62
+ while pending:
63
+ value = pending.pop()
64
+ if isinstance(value, Mapping):
65
+ for key, item in value.items():
66
+ if not isinstance(key, str):
67
+ raise TypeError("audit metadata keys must be strings")
68
+ if is_sensitive_field(key):
69
+ raise ValueError(
70
+ f"audit metadata cannot contain sensitive field: {key}"
71
+ )
72
+ pending.append(item)
73
+ elif isinstance(value, list | tuple):
74
+ pending.extend(value)
75
+
76
+
77
+ class AuditRecorder:
78
+ """Write sanitized session audit events with one shared policy."""
79
+
80
+ def __init__(
81
+ self,
82
+ *,
83
+ sink: IAudit,
84
+ timeout_budget: TimeoutBudget,
85
+ clock: Callable[[], int],
86
+ ) -> None:
87
+ self._sink = sink
88
+ self._timeout_budget = timeout_budget
89
+ self._clock = clock
90
+ self._logger = logging.getLogger("bazaar_compute_node.audit.fallback")
91
+
92
+ async def append(
93
+ self,
94
+ *,
95
+ event_name: str,
96
+ state: RuntimeEventState,
97
+ correlation: CorrelationContext,
98
+ level: LogLevel | None = None,
99
+ error_kind: ErrorKind | None = None,
100
+ error_message: str | None = None,
101
+ metadata: Mapping[str, object] | None = None,
102
+ ) -> None:
103
+ # how severe an event is belongs to whoever raises it; the fallback is
104
+ # for the callers that have no opinion
105
+ if level is None:
106
+ level = LogLevel.ERROR if error_kind else LogLevel.INFO
107
+ event = AuditEvent(
108
+ event_name=event_name,
109
+ state=state,
110
+ created_at_ms=self._clock(),
111
+ correlation=correlation,
112
+ level=level,
113
+ error_kind=error_kind,
114
+ error_message=error_message,
115
+ metadata=cast(Mapping[str, object], omit_sensitive_fields(metadata or {})),
116
+ )
117
+ try:
118
+ await self._sink.append(
119
+ event,
120
+ timeout=self._timeout_budget.command_seconds,
121
+ )
122
+ except asyncio.CancelledError:
123
+ raise
124
+ except Exception:
125
+ self._logger.exception(
126
+ "audit append failed",
127
+ extra={"event_name": event_name},
128
+ )
129
+
130
+ async def append_tool(
131
+ self,
132
+ *,
133
+ operation: str,
134
+ status: str,
135
+ state: RuntimeEventState,
136
+ correlation: CorrelationContext,
137
+ arguments: Mapping[str, object],
138
+ error_kind: ErrorKind | None = None,
139
+ error_message: str | None = None,
140
+ ) -> None:
141
+ safe_arguments = cast(Mapping[str, object], omit_sensitive_fields(arguments))
142
+ await self.append(
143
+ event_name=f"tool.{operation}.{status}",
144
+ state=state,
145
+ correlation=correlation,
146
+ error_kind=error_kind,
147
+ error_message=error_message,
148
+ metadata={
149
+ "kind": "tool_call",
150
+ "operation": operation,
151
+ "status": status,
152
+ "arguments": safe_arguments,
153
+ },
154
+ )
@@ -7,6 +7,7 @@ from typing import Protocol
7
7
  from uuid import NAMESPACE_URL, uuid5
8
8
 
9
9
  from ..i18n import Translator
10
+ from .audit import AuditRecorder
10
11
  from .lifecycle import IAsyncLifecycle
11
12
  from .models import (
12
13
  ApprovalRequest,
@@ -107,6 +108,7 @@ class ChannelContext:
107
108
  workspace: Callable[[], Path]
108
109
  translator: Translator | None = None
109
110
  timer_wheel: TimerWheel | None = None
111
+ audit: AuditRecorder | None = None
110
112
 
111
113
 
112
114
  class IApproval(Protocol):
@@ -11,7 +11,7 @@ from dataclasses import replace
11
11
  from pathlib import Path, PurePosixPath
12
12
 
13
13
  from ..actor import Actor, Actors, Agent, Thread
14
- from ..audit import ErrorKind
14
+ from ..audit import AuditRecorder, ErrorKind
15
15
  from ..channel import ChannelSendRequest
16
16
  from ..command import (
17
17
  ICommandService,
@@ -42,7 +42,7 @@ from ..storage import (
42
42
  ResolvedInboxTarget,
43
43
  )
44
44
  from .delivery import OutboundDeliveryService
45
- from .services import AuditRecorder, threads_in_reach
45
+ from .services import threads_in_reach
46
46
 
47
47
 
48
48
  class OutboundAttachmentResolver:
@@ -6,7 +6,7 @@ from collections.abc import Callable, Mapping
6
6
  from types import MappingProxyType
7
7
 
8
8
  from ...i18n import Translator
9
- from ..audit import ErrorKind
9
+ from ..audit import AuditRecorder, ErrorKind
10
10
  from ..channel import ChannelSendRequest
11
11
  from ..correlation import CorrelationContext
12
12
  from ..models import (
@@ -19,7 +19,6 @@ from ..models import (
19
19
  from ..storage import IStorageScope
20
20
  from .delivery import OutboundDeliveryService
21
21
  from .reminder import resolve_reminder_anchor
22
- from .services import AuditRecorder
23
22
 
24
23
  MESSAGE_KEYS: Mapping[RuntimeTurnState, str] = MappingProxyType(
25
24
  {
@@ -12,7 +12,7 @@ from ...i18n import Translator
12
12
  from ..actor import Actor, Actors
13
13
  from ..agent import Agent, State
14
14
  from ..approval import IApprovalHandler
15
- from ..audit import ErrorKind
15
+ from ..audit import AuditRecorder, ErrorKind
16
16
  from ..channel import IChannel
17
17
  from ..concurrency import IThreadConcurrency, ThreadLockRegistry
18
18
  from ..correlation import CorrelationContext
@@ -27,7 +27,6 @@ from ..models import (
27
27
  RuntimeTurnState,
28
28
  Thread,
29
29
  )
30
- from ..observability import IAudit
31
30
  from ..outcomes import ProviderCallResult, ProviderCallStatus
32
31
  from ..runtime import (
33
32
  IRuntime,
@@ -50,7 +49,7 @@ from ..utils.text import format_exception
50
49
  from .command import CommandService
51
50
  from .delivery import OutboundDeliveryService
52
51
  from .error_feedback import MESSAGE_KEYS, RuntimeErrorReporter
53
- from .services import AuditRecorder, unread_in_reach
52
+ from .services import unread_in_reach
54
53
  from .turn import (
55
54
  TurnContext,
56
55
  TurnCoordinator,
@@ -155,7 +154,7 @@ class AgentOrchestrator(IAsyncLifecycle):
155
154
  channel: IChannel,
156
155
  runtimes: Sequence[IRuntime],
157
156
  storage: IStorageScope,
158
- audit: IAudit,
157
+ audit: AuditRecorder,
159
158
  timeout_budget: TimeoutBudget,
160
159
  timer_wheel: TimerWheel,
161
160
  runtime_idle_timeout_ms: int = 0,
@@ -195,11 +194,7 @@ class AgentOrchestrator(IAsyncLifecycle):
195
194
  self._logger.addHandler(logging.StreamHandler())
196
195
  self._logger.setLevel(logging.INFO)
197
196
  self._logger.propagate = False
198
- self._audit = AuditRecorder(
199
- sink=audit,
200
- timeout_budget=timeout_budget,
201
- clock=self._clock,
202
- )
197
+ self._audit = audit
203
198
  self._agent = Agent(self._session_runtime_states)
204
199
  self._delivery = OutboundDeliveryService(
205
200
  channel,
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ from ..actor import Actor, Agent, Thread
4
+ from ..command import UnreadSummary
5
+ from ..storage import IStorage
6
+
7
+
8
+ async def threads_in_reach(storage: IStorage, actor: Actor) -> tuple[str, ...]:
9
+ """Return the conversations one actor answers for."""
10
+
11
+ match actor:
12
+ case Thread(thread_id):
13
+ return (thread_id,)
14
+ case Agent():
15
+ return await storage.list_thread_ids()
16
+
17
+
18
+ async def unread_in_reach(
19
+ storage: IStorage,
20
+ actor: Actor,
21
+ *,
22
+ limit: int,
23
+ ) -> UnreadSummary:
24
+ """Say what one actor has unread, counted and carried from the same read."""
25
+
26
+ match actor:
27
+ case Thread(thread_id):
28
+ return await storage.read_unread_summary(thread_id, limit=limit)
29
+ case Agent():
30
+ return await storage.read_unread_summary(None, limit=limit)
@@ -13,7 +13,7 @@ from ..actor import Agent as AgentActor
13
13
  from ..actor import Thread as ThreadActor
14
14
  from ..agent import Agent, State
15
15
  from ..approval import ApprovalBinding, IApprovalHandler
16
- from ..audit import ErrorKind
16
+ from ..audit import AuditRecorder, ErrorKind
17
17
  from ..channel import ChannelApprovalRequest, IChannel
18
18
  from ..concurrency import IThreadConcurrency
19
19
  from ..correlation import CorrelationContext
@@ -52,7 +52,6 @@ from ..models import (
52
52
  from ..runtime import IRuntimeTurnStream, Runtime, RuntimeSessionUnavailable
53
53
  from ..storage import IStorageScope
54
54
  from .reminder import resolve_reminder_anchor
55
- from .services import AuditRecorder
56
55
 
57
56
 
58
57
  def _is_turn_event(event_name: str) -> bool:
@@ -1,23 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import os
4
-
5
- from ...core.channel import ChannelContext, IChannel, IChannelBuilder
6
- from .outbound import TelegramOutboundChannel
7
-
8
-
9
- class TelegramBuilder(IChannelBuilder):
10
- def build(self, context: ChannelContext) -> IChannel:
11
- token_env = context.options.get("token_env")
12
- if not isinstance(token_env, str) or not token_env:
13
- raise ValueError("agent.channel.token_env is required for telegram")
14
- token = os.environ.get(token_env)
15
- if token is None or not token.strip():
16
- raise ValueError(f"telegram credential environment is missing: {token_env}")
17
- return TelegramOutboundChannel(context, token=token)
18
-
19
-
20
- builder = TelegramBuilder()
21
-
22
-
23
- __all__ = ["TelegramBuilder", "builder"]
@@ -1,70 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Mapping
4
- from dataclasses import dataclass, field
5
- from enum import StrEnum
6
-
7
- from .correlation import CorrelationContext
8
- from .models import RuntimeEventState
9
- from .observability import LogLevel
10
- from .utils.sanitization import is_sensitive_field
11
-
12
-
13
- class ErrorKind(StrEnum):
14
- CANCELLED = "cancelled"
15
- TIMEOUT = "timeout"
16
- VALIDATION = "validation"
17
- SESSION_NOT_FOUND = "session_not_found"
18
- TARGET_NOT_REPLYABLE = "target_not_replyable"
19
- EMPTY_BODY = "empty_body"
20
- FRESH_CHECK_REQUIRED = "fresh_check_required"
21
- FRESH_CHECK_FAILED = "fresh_check_failed"
22
- PROVIDER_FAILED = "provider_failed"
23
- PROVIDER_PARTIAL = "provider_partial"
24
- PROVIDER_UNKNOWN = "provider_unknown"
25
- PROTOCOL = "protocol"
26
- STORAGE = "storage"
27
- SHUTDOWN_TIMEOUT = "shutdown_timeout"
28
- INTERNAL = "internal"
29
-
30
-
31
- @dataclass(frozen=True, slots=True)
32
- class AuditEvent:
33
- """Sanitized append-only event contract shared by all adapters."""
34
-
35
- event_name: str
36
- state: RuntimeEventState
37
- created_at_ms: int
38
- correlation: CorrelationContext
39
- level: LogLevel = LogLevel.INFO
40
- duration_ms: int | None = None
41
- error_kind: ErrorKind | None = None
42
- error_type: str | None = None
43
- error_message: str | None = None
44
- traceback_ref: str | None = None
45
- metadata: Mapping[str, object] = field(default_factory=dict)
46
-
47
- def __post_init__(self) -> None:
48
- if self.error_kind is None and any(
49
- value is not None
50
- for value in (
51
- self.error_type,
52
- self.error_message,
53
- self.traceback_ref,
54
- )
55
- ):
56
- raise ValueError("error details require an error_kind")
57
- pending: list[object] = [self.metadata]
58
- while pending:
59
- value = pending.pop()
60
- if isinstance(value, Mapping):
61
- for key, item in value.items():
62
- if not isinstance(key, str):
63
- raise TypeError("audit metadata keys must be strings")
64
- if is_sensitive_field(key):
65
- raise ValueError(
66
- f"audit metadata cannot contain sensitive field: {key}"
67
- )
68
- pending.append(item)
69
- elif isinstance(value, list | tuple):
70
- pending.extend(value)