bazaar-compute-node 0.1.39rc4__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 (207) hide show
  1. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/PKG-INFO +5 -2
  2. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/README.md +4 -1
  3. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/pyproject.toml +1 -1
  4. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/pyproject.toml.orig +1 -1
  5. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent.py +56 -39
  6. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/application.py +4 -4
  7. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/command.py +66 -56
  8. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/config.py +12 -0
  9. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/resource_dispatch.py +33 -25
  10. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/wrapper.py +6 -1
  11. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/__init__.py +5 -1
  12. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/_client.py +1 -1
  13. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/_format.py +13 -52
  14. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/cmd/bcc/inbox.py +22 -0
  15. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/message.py +1 -1
  16. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/thread.py +1 -1
  17. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/approval.py +3 -2
  18. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/events.py +4 -3
  19. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/runtime.py +3 -2
  20. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/approval.py +3 -2
  21. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/events.py +5 -4
  22. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/runtime.py +7 -6
  23. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/channel.py +2 -2
  24. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/audit.py +5 -1
  25. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/codec.py +9 -9
  26. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/registry.py +4 -0
  27. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/sqlite/migrations/v25_rename_sessions_to_threads.py +37 -0
  28. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/sqlite/migrations/v26_remove_handoff_messages.py +43 -0
  29. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +1 -1
  30. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/base.py +13 -11
  31. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/facade.py +20 -20
  32. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/messages.py +120 -84
  33. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/reminders.py +27 -27
  34. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/sessions.py +34 -32
  35. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/storage.py +10 -3
  36. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/approval.py +8 -2
  37. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/channel.py +41 -6
  38. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/outbound.py +2 -1
  39. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/telegram/plugin.py +43 -0
  40. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/channel.py +2 -2
  41. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/actor.py +65 -0
  42. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/agent.py +51 -0
  43. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/approval.py +3 -2
  44. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/audit.py +154 -0
  45. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/channel.py +7 -14
  46. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/command.py +24 -32
  47. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/concurrency.py +29 -0
  48. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/correlation.py +4 -1
  49. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/instruction.py +3 -0
  50. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/__init__.py +2 -2
  51. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/entities.py +15 -11
  52. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/events.py +3 -1
  53. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/reminder.py +1 -1
  54. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/reminder_owner.py +2 -2
  55. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/states.py +0 -1
  56. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/orchestration/__init__.py +6 -0
  57. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/command.py +123 -140
  58. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/error_feedback.py +6 -7
  59. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/orchestration/session.py → bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/orchestration/orchestrator.py +254 -233
  60. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/reminder.py +11 -11
  61. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/reminder_command.py +91 -83
  62. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/orchestration/services.py +30 -0
  63. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/turn.py +165 -79
  64. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/runtime.py +9 -7
  65. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/storage.py +205 -232
  66. bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/resources/bcc/inbox_check.tpl +2 -0
  67. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/developer_instructions.md +5 -8
  68. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/cmd/bcc/inbox.py +0 -37
  69. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -23
  70. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/agent.py +0 -49
  71. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/audit.py +0 -70
  72. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/concurrency.py +0 -29
  73. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/orchestration/__init__.py +0 -6
  74. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/orchestration/services.py +0 -90
  75. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/resources/bcc/inbox_list.tpl +0 -3
  76. bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/resources/bcc/inbox_target.tpl +0 -1
  77. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/LICENSE +0 -0
  78. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/__init__.py +0 -0
  79. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/__init__.py +0 -0
  80. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent_management.py +0 -0
  81. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/attachments.py +0 -0
  82. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/registry.py +0 -0
  83. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/system_service.py +0 -0
  84. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/transport.py +0 -0
  85. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/upgrade.py +0 -0
  86. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/usage.py +0 -0
  87. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/version_check.py +0 -0
  88. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/windows_pipe.py +0 -0
  89. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/bcc.py +0 -0
  90. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cli.py +0 -0
  91. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/__init__.py +0 -0
  92. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/node.py +0 -0
  93. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/reminder.py +0 -0
  94. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/__init__.py +0 -0
  95. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/_options.py +0 -0
  96. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/_runner.py +0 -0
  97. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/agent.py +0 -0
  98. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/node.py +0 -0
  99. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/service.py +0 -0
  100. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/__init__.py +0 -0
  101. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/__init__.py +0 -0
  102. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/client.py +0 -0
  103. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/plugin.py +0 -0
  104. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/process.py +0 -0
  105. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/protocol.py +0 -0
  106. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
  107. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
  108. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
  109. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/process.py +0 -0
  110. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
  111. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/__init__.py +0 -0
  112. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/api.py +0 -0
  113. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/approval.py +0 -0
  114. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/attachments.py +0 -0
  115. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/frame.py +0 -0
  116. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/identity.py +0 -0
  117. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/outbound.py +0 -0
  118. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/plugin.py +0 -0
  119. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/transport.py +0 -0
  120. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
  121. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
  122. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
  123. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/database.py +0 -0
  124. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/executor.py +0 -0
  125. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/__init__.py +0 -0
  126. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/model.py +0 -0
  127. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v01_initial_node_schema.py +0 -0
  128. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v02_session_mapping_indexes.py +0 -0
  129. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v03_message_log_indexes.py +0 -0
  130. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v04_runtime_attempt_facts.py +0 -0
  131. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v05_inbound_message_references.py +0 -0
  132. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v06_inbound_message_reference_integrity.py +0 -0
  133. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v07_inbound_provider_identity.py +0 -0
  134. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v08_transient_stream_events.py +0 -0
  135. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v09_remove_runtime_events.py +0 -0
  136. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v10_add_outbound_attachments.py +0 -0
  137. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v11_remove_runtime_session_mapping.py +0 -0
  138. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v12_add_reminders.py +0 -0
  139. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v13_add_agent_ownership.py +0 -0
  140. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v14_add_inbox_discovery_indexes.py +0 -0
  141. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v15_add_handoffs.py +0 -0
  142. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v16_remove_outbound_drafts.py +0 -0
  143. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v17_remove_agent_identity_triggers.py +0 -0
  144. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v18_unify_messages.py +0 -0
  145. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v19_reminder_system_messages.py +0 -0
  146. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v20_remove_freshness_persistence.py +0 -0
  147. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v21_remove_handoffs.py +0 -0
  148. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v22_readable_targets.py +0 -0
  149. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v23_persist_sender_identity.py +0 -0
  150. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/v24_persist_sender_display_name.py +0 -0
  151. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
  152. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/__init__.py +0 -0
  153. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
  154. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/api.py +0 -0
  155. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/attachments.py +0 -0
  156. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
  157. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/markdown.py +0 -0
  158. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
  159. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
  160. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
  161. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/__init__.py +0 -0
  162. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/client.py +0 -0
  163. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/inbox.py +0 -0
  164. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/lifecycle.py +0 -0
  165. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/observability.py +0 -0
  166. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
  167. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/upgrade_notice.py +0 -0
  168. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/outcomes.py +0 -0
  169. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/paths.py +0 -0
  170. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/reminder.py +0 -0
  171. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
  172. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/restart.py +0 -0
  173. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/timerwheel.py +0 -0
  174. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/__init__.py +0 -0
  175. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/clock.py +0 -0
  176. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/line_reader.py +0 -0
  177. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/markdown.py +0 -0
  178. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/sanitization.py +0 -0
  179. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/text.py +0 -0
  180. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/i18n/__init__.py +0 -0
  181. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/i18n/catalog.py +0 -0
  182. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/rendering.py +0 -0
  183. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/approval_no_person.tpl +0 -0
  184. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/check.tpl +0 -0
  185. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/error.tpl +0 -0
  186. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/read.tpl +0 -0
  187. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_list.tpl +0 -0
  188. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_mutation.tpl +0 -0
  189. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_schedule.tpl +0 -0
  190. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/unfollow.tpl +0 -0
  191. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/upgrade.tpl +0 -0
  192. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/version.tpl +0 -0
  193. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/attachment_suffix.tpl +0 -0
  194. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/check_message.tpl +0 -0
  195. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/freshness_hold.tpl +0 -0
  196. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/read_message.tpl +0 -0
  197. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/send_result.tpl +0 -0
  198. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/sender.tpl +0 -0
  199. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/inbox_notice.tpl +0 -0
  200. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/locales/en.toml +0 -0
  201. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/locales/zh-CN.toml +0 -0
  202. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/launchd.plist +0 -0
  203. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/launchd.sh +0 -0
  204. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/systemd.service +0 -0
  205. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.ps1 +0 -0
  206. {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.vbs +0 -0
  207. {bazaar_compute_node-0.1.39rc4 → 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.1.39rc4
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.1.39rc4"
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.1.39rc4"
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"
@@ -12,8 +12,10 @@ from dataclasses import dataclass
12
12
  from functools import partial
13
13
  from pathlib import Path
14
14
 
15
+ from ..core.actor import Actor, Actors, Agent, Thread
16
+ from ..core.audit import AuditRecorder
15
17
  from ..core.channel import Channel, ChannelContext, IChannel
16
- from ..core.concurrency import ISessionConcurrency, SessionLockRegistry
18
+ from ..core.concurrency import IThreadConcurrency, ThreadLockRegistry
17
19
  from ..core.lifecycle import TimeoutBudget
18
20
  from ..core.models import (
19
21
  InboundAttachment,
@@ -21,12 +23,13 @@ from ..core.models import (
21
23
  RuntimeSession,
22
24
  )
23
25
  from ..core.observability import IAudit
24
- from ..core.orchestration import SessionOrchestrator
26
+ from ..core.orchestration import AgentOrchestrator
25
27
  from ..core.orchestration.reminder_command import ReminderCommandService
26
28
  from ..core.paths import resolve_workspace_dir
27
29
  from ..core.runtime import IRuntime, RuntimeCommandContext
28
30
  from ..core.storage import IStorageScope
29
31
  from ..core.timerwheel import TimerWheel
32
+ from ..core.utils.clock import now_ms
30
33
  from ..i18n import Translator
31
34
  from .attachments import AttachmentMaterializer
32
35
  from .command import CommandDispatchError
@@ -57,7 +60,7 @@ _PLATFORM_ENVIRONMENT = {
57
60
  @dataclass(frozen=True, slots=True)
58
61
  class _SessionCapabilityBinding:
59
62
  agent_id: str
60
- bcn_session_id: str
63
+ actor_id: str
61
64
  runtime_session_id: str
62
65
  capability: str
63
66
  token_values: tuple[str, ...]
@@ -74,7 +77,7 @@ class AgentApplication:
74
77
  storage: IStorageScope,
75
78
  audit: IAudit,
76
79
  timer_wheel: TimerWheel,
77
- reminder_concurrency: ISessionConcurrency,
80
+ reminder_concurrency: IThreadConcurrency,
78
81
  reminder_poke: Callable[[], None],
79
82
  endpoint: Callable[[], str],
80
83
  timeout_budget: TimeoutBudget,
@@ -94,7 +97,7 @@ class AgentApplication:
94
97
  self._wrapper_path: Path | None = None
95
98
  self.command_log: list[CommandRecord] = []
96
99
  self._session_capabilities: dict[str, _SessionCapabilityBinding] = {}
97
- self._concurrency = SessionLockRegistry()
100
+ self._concurrency = ThreadLockRegistry()
98
101
  self._started = False
99
102
  self._stopping = False
100
103
  self._runtime_configurations = configuration.runtimes
@@ -103,6 +106,11 @@ class AgentApplication:
103
106
  self.workspace_path,
104
107
  self._referenced_attachment_paths,
105
108
  )
109
+ self._audit_recorder = AuditRecorder(
110
+ sink=audit,
111
+ timeout_budget=timeout_budget,
112
+ clock=now_ms,
113
+ )
106
114
  provider_channel = factories.channel.build(
107
115
  ChannelContext(
108
116
  agent_id=self.agent_id,
@@ -111,6 +119,7 @@ class AgentApplication:
111
119
  workspace=self.workspace_path,
112
120
  translator=self.translator,
113
121
  timer_wheel=self.timer_wheel,
122
+ audit=self._audit_recorder,
114
123
  )
115
124
  )
116
125
  self.channel: IChannel = Channel(self.agent_id, provider_channel)
@@ -135,6 +144,7 @@ class AgentApplication:
135
144
  agent_name=self.name,
136
145
  bot_name=self._bot_name,
137
146
  runtime_options=runtime_options,
147
+ mode=configuration.mode,
138
148
  sandbox_mode=runtime_configuration.sandbox_mode,
139
149
  network_access=runtime_configuration.network_access,
140
150
  startup_timeout_seconds=timeout_budget.startup_seconds,
@@ -155,12 +165,13 @@ class AgentApplication:
155
165
  raise ValueError("agent idle timeout exceeds the timer horizon")
156
166
  self._runtime_contexts = tuple(runtime_contexts)
157
167
  self.runtimes: tuple[IRuntime, ...] = tuple(runtimes)
158
- self.orchestrator = SessionOrchestrator(
159
- agent_id=self.agent_id,
168
+ self._actors = Actors(agent_id=self.agent_id, mode=configuration.mode)
169
+ self.orchestrator = AgentOrchestrator(
170
+ actors=self._actors,
160
171
  channel=self.channel,
161
172
  runtimes=self.runtimes,
162
173
  storage=self.storage,
163
- audit=self.audit,
174
+ audit=self._audit_recorder,
164
175
  timeout_budget=self.timeout_budget,
165
176
  timer_wheel=self.timer_wheel,
166
177
  runtime_idle_timeout_ms=(
@@ -181,9 +192,10 @@ class AgentApplication:
181
192
  )
182
193
  self.command_dispatcher = CommandDispatcher(
183
194
  self.orchestrator.command_service,
195
+ actors=self._actors,
184
196
  reminder_service=self.reminder_service,
185
197
  timeout_budget=self.timeout_budget,
186
- session_binding_validator=self._validate_session_binding,
198
+ session_binding_validator=self._validate_actor_binding,
187
199
  upgrade_service=upgrade_service,
188
200
  )
189
201
 
@@ -213,6 +225,7 @@ class AgentApplication:
213
225
  install_bcc_wrapper,
214
226
  workspace / ".bcn" / "bin",
215
227
  agent_id=self.agent_id,
228
+ mode=self._actors.mode,
216
229
  )
217
230
  await self._attachment_materializer.reconcile()
218
231
  await self.orchestrator.start(
@@ -268,10 +281,10 @@ class AgentApplication:
268
281
  ) -> Mapping[str, object]:
269
282
  return await self.command_dispatcher(request)
270
283
 
271
- async def has_session(self, session_id: str) -> bool:
272
- if not isinstance(session_id, str) or not session_id:
284
+ async def has_session(self, thread_id: str) -> bool:
285
+ if not isinstance(thread_id, str) or not thread_id:
273
286
  return False
274
- return await self.storage.get_bcn_session(session_id) is not None
287
+ return await self.storage.get_thread(thread_id) is not None
275
288
 
276
289
  async def publish_inbox_wake(self, message: Message[InboundAttachment]) -> None:
277
290
  if not self._started:
@@ -312,9 +325,9 @@ class AgentApplication:
312
325
  async def _referenced_attachment_paths(self) -> set[str]:
313
326
  return set(await self.storage.list_ready_attachment_paths())
314
327
 
315
- async def _validate_session_binding(
328
+ async def _validate_actor_binding(
316
329
  self,
317
- session_id: str,
330
+ actor: Actor,
318
331
  request: Mapping[str, object],
319
332
  ) -> None:
320
333
  request_agent_id = request.get("agent_id")
@@ -325,22 +338,26 @@ class AgentApplication:
325
338
  )
326
339
  runtime_session_id = request.get("runtime_session_id")
327
340
  session_capability = request.get("session_capability")
328
- if await self.storage.get_bcn_session(session_id) is None:
329
- raise CommandDispatchError(
330
- "SESSION_NOT_FOUND",
331
- f"unknown bcn session: {session_id}",
332
- )
333
- runtime_session = self.orchestrator.runtime_session(session_id)
341
+ match actor:
342
+ case Thread(thread_id):
343
+ if await self.storage.get_thread(thread_id) is None:
344
+ raise CommandDispatchError(
345
+ "SESSION_NOT_FOUND",
346
+ f"unknown thread: {thread_id}",
347
+ )
348
+ case Agent():
349
+ pass
350
+ runtime_session = self.orchestrator.runtime_session(actor)
334
351
  if runtime_session is None or runtime_session_id != runtime_session.id:
335
352
  raise CommandDispatchError(
336
353
  "SESSION_BINDING_FAILED",
337
354
  "runtime session binding is invalid",
338
355
  )
339
- binding = self._session_capabilities.get(session_id)
356
+ binding = self._session_capabilities.get(actor.id)
340
357
  if (
341
358
  binding is None
342
359
  or binding.agent_id != self.agent_id
343
- or binding.bcn_session_id != session_id
360
+ or binding.actor_id != actor.id
344
361
  or binding.runtime_session_id != runtime_session.id
345
362
  or not isinstance(session_capability, str)
346
363
  or not hmac.compare_digest(
@@ -357,31 +374,29 @@ class AgentApplication:
357
374
  runtime_index: int,
358
375
  session: RuntimeSession,
359
376
  ) -> Mapping[str, str]:
360
- runtime_session = self.orchestrator.runtime_session(session.bcn_session_id)
377
+ runtime_session = self.orchestrator.runtime_session(session.actor)
361
378
  if runtime_session is None or runtime_session.id != session.id:
362
379
  raise RuntimeError("runtime session is not the current live binding")
363
380
  return self._build_command_environment(
364
- session.bcn_session_id,
381
+ session.actor.id,
365
382
  session.id,
366
383
  runtime_index=runtime_index,
367
384
  )
368
385
 
369
386
  def _build_command_environment(
370
387
  self,
371
- session_id: str,
388
+ actor_id: str,
372
389
  runtime_session_id: str,
373
390
  *,
374
391
  runtime_index: int,
375
392
  ) -> dict[str, str]:
376
- if not session_id:
377
- raise ValueError("session_id must be a non-empty string")
378
393
  if not runtime_session_id:
379
394
  raise ValueError("runtime_session_id must be a non-empty string")
380
395
  wrapper_path = self._wrapper_path
381
396
  if wrapper_path is None:
382
397
  raise RuntimeError("bcc wrapper is not installed")
383
398
  environment_bindings = self._runtime_configurations[runtime_index].env
384
- binding = self._session_capabilities.get(session_id)
399
+ binding = self._session_capabilities.get(actor_id)
385
400
  if binding is None or binding.runtime_session_id != runtime_session_id:
386
401
  capability = secrets.token_urlsafe(32)
387
402
  token_values = [capability]
@@ -393,12 +408,12 @@ class AgentApplication:
393
408
  token_values.append(value)
394
409
  binding = _SessionCapabilityBinding(
395
410
  agent_id=self.agent_id,
396
- bcn_session_id=session_id,
411
+ actor_id=actor_id,
397
412
  runtime_session_id=runtime_session_id,
398
413
  capability=capability,
399
414
  token_values=tuple(token_values),
400
415
  )
401
- self._session_capabilities[session_id] = binding
416
+ self._session_capabilities[actor_id] = binding
402
417
  allowed = set(_PLATFORM_ENVIRONMENT)
403
418
  for name in self.runtimes[runtime_index].environment_variable_names():
404
419
  if not _ENVIRONMENT_NAME.fullmatch(name):
@@ -433,15 +448,15 @@ class AgentApplication:
433
448
  {
434
449
  "BCN_AGENT_ID": self.agent_id,
435
450
  "BCN_ENDPOINT": self._endpoint(),
436
- "BCN_SESSION_ID": session_id,
451
+ "BCN_ACTOR_ID": actor_id,
437
452
  "BCN_RUNTIME_SESSION_ID": runtime_session_id,
438
453
  "BCN_COMMAND_CAPABILITY": binding.capability,
439
454
  }
440
455
  )
441
456
  return environment
442
457
 
443
- def _redact_session_secrets(self, session_id: str, text: str) -> str:
444
- binding = self._session_capabilities.get(session_id)
458
+ def _redact_session_secrets(self, thread_id: str, text: str) -> str:
459
+ binding = self._session_capabilities.get(self._actors.for_thread(thread_id).id)
445
460
  if binding is None:
446
461
  return text
447
462
  for token in binding.token_values:
@@ -450,12 +465,12 @@ class AgentApplication:
450
465
 
451
466
  async def _run_runtime_command(
452
467
  self,
453
- session_id: str,
468
+ thread_id: str,
454
469
  arguments: Sequence[str],
455
470
  body: str | None,
456
471
  ) -> None:
457
- if not session_id:
458
- raise ValueError("session_id must be a non-empty string")
472
+ if not thread_id:
473
+ raise ValueError("thread_id must be a non-empty string")
459
474
  if not arguments or any(
460
475
  not isinstance(argument, str) for argument in arguments
461
476
  ):
@@ -463,12 +478,14 @@ class AgentApplication:
463
478
  wrapper_path = self._wrapper_path
464
479
  if wrapper_path is None:
465
480
  raise RuntimeError("bcc wrapper is not installed")
466
- self.command_log.append((session_id, tuple(arguments)))
467
- runtime_session = self.orchestrator.runtime_session(session_id)
481
+ self.command_log.append((thread_id, tuple(arguments)))
482
+ runtime_session = self.orchestrator.runtime_session(
483
+ self._actors.for_thread(thread_id)
484
+ )
468
485
  if runtime_session is None:
469
486
  raise RuntimeError("runtime session is not live")
470
487
  environment = self._build_command_environment(
471
- session_id,
488
+ runtime_session.actor.id,
472
489
  runtime_session.id,
473
490
  runtime_index=runtime_session.runtime_index,
474
491
  )
@@ -10,7 +10,7 @@ from dataclasses import dataclass
10
10
  from pathlib import Path
11
11
 
12
12
  from .. import __version__
13
- from ..core.concurrency import SessionLockRegistry
13
+ from ..core.concurrency import ThreadLockRegistry
14
14
  from ..core.lifecycle import ITaskFailureSource, TimeoutBudget
15
15
  from ..core.models import InboundAttachment, Message
16
16
  from ..core.observability import IAudit
@@ -82,7 +82,7 @@ class NodeApplication:
82
82
  self.storage: IStorage = shared_factories.storage()
83
83
  self.audit: IAudit = shared_factories.audit()
84
84
  self.timer_wheel = TimerWheel()
85
- self._reminder_concurrency = SessionLockRegistry()
85
+ self._reminder_concurrency = ThreadLockRegistry()
86
86
  self.reminder_scheduler = ReminderScheduler(
87
87
  storage=self.storage,
88
88
  timer_wheel=self.timer_wheel,
@@ -369,7 +369,7 @@ class NodeApplication:
369
369
  self._log(
370
370
  "reminder.wake.agent_unavailable",
371
371
  agent_id=agent_id,
372
- owner_session_id=message.session_id,
372
+ owner_thread_id=message.thread_id,
373
373
  )
374
374
  return False
375
375
  try:
@@ -380,7 +380,7 @@ class NodeApplication:
380
380
  self._log(
381
381
  "reminder.wake.failed",
382
382
  agent_id=agent_id,
383
- owner_session_id=message.session_id,
383
+ owner_thread_id=message.thread_id,
384
384
  error_type=type(error).__name__,
385
385
  error=format_exception(error),
386
386
  )
@@ -17,12 +17,12 @@ from pydantic import (
17
17
  ValidationError,
18
18
  )
19
19
 
20
+ from ..core.actor import Actor, Actors
20
21
  from ..core.command import (
21
22
  ICommandService,
22
- InboxListResult,
23
23
  MessageSendFreshnessHold,
24
- SessionNotFoundError,
25
24
  TargetProjection,
25
+ ThreadNotFoundError,
26
26
  )
27
27
  from ..core.lifecycle import TimeoutBudget
28
28
  from ..core.models import (
@@ -83,7 +83,7 @@ def serialize_message(
83
83
  "seq": message.seq,
84
84
  "message_id": message.message_id,
85
85
  "direction": message.direction.value,
86
- "session_id": message.session_id,
86
+ "thread_id": message.thread_id,
87
87
  "channel_session_id": message.channel_session_id,
88
88
  "channel": message.channel,
89
89
  "received_at_ms": message.received_at_ms,
@@ -144,9 +144,8 @@ def serialize_inbox_target(summary: InboxTargetSummary) -> dict[str, object]:
144
144
  )
145
145
  return {
146
146
  "target": summary.target,
147
- "session_id": summary.session_id,
147
+ "thread_id": summary.thread_id,
148
148
  "target_kind": summary.target_kind.value,
149
- "current": summary.current,
150
149
  "pending_count": summary.pending_count,
151
150
  "last_activity_at_ms": summary.last_activity_at_ms,
152
151
  "latest_message_id": summary.latest_message_id,
@@ -163,16 +162,6 @@ def serialize_inbox_target(summary: InboxTargetSummary) -> dict[str, object]:
163
162
  }
164
163
 
165
164
 
166
- def serialize_inbox_list(result: InboxListResult) -> dict[str, object]:
167
- return {
168
- "targets": [serialize_inbox_target(target) for target in result.targets],
169
- "total": result.total,
170
- "shown": result.shown,
171
- "offset": result.offset,
172
- "has_more": result.has_more,
173
- }
174
-
175
-
176
165
  class CommandDispatchError(ValueError):
177
166
  def __init__(
178
167
  self,
@@ -200,7 +189,7 @@ class _CommandRequest(BaseModel):
200
189
  kind: Literal["command"]
201
190
  resource: StrictStr
202
191
  command: StrictStr
203
- session_id: NonEmptyText
192
+ actor_id: NonEmptyText
204
193
 
205
194
 
206
195
  class _MessageCheckRequest(_CommandRequest):
@@ -230,11 +219,9 @@ class _MessageSendRequest(_CommandRequest):
230
219
  )
231
220
 
232
221
 
233
- class _InboxListRequest(_CommandRequest):
222
+ class _InboxCheckRequest(_CommandRequest):
234
223
  resource: Literal["inbox"]
235
- command: Literal["list"]
236
- limit: PositiveInt = 100
237
- offset: NonNegativeInt = 0
224
+ command: Literal["check"]
238
225
 
239
226
 
240
227
  class _ThreadUnfollowRequest(_CommandRequest):
@@ -249,7 +236,7 @@ _REQUEST_MODELS: dict[tuple[str, str], _RequestModel] = {
249
236
  ("message", "check"): _MessageCheckRequest,
250
237
  ("message", "read"): _MessageReadRequest,
251
238
  ("message", "send"): _MessageSendRequest,
252
- ("inbox", "list"): _InboxListRequest,
239
+ ("inbox", "check"): _InboxCheckRequest,
253
240
  ("thread", "unfollow"): _ThreadUnfollowRequest,
254
241
  }
255
242
 
@@ -275,7 +262,7 @@ _SEND_FAILURES: dict[OutboundDeliveryState, tuple[str, str, str]] = {
275
262
  }
276
263
 
277
264
  _REQUEST_ERRORS: dict[str, tuple[str, str]] = {
278
- "session_id": ("SESSION_REQUIRED", "session_id must be a non-empty string"),
265
+ "actor_id": ("SESSION_REQUIRED", "actor_id must be a non-empty string"),
279
266
  "limit": ("INVALID_LIMIT", "limit must be a positive integer"),
280
267
  "offset": ("INVALID_OFFSET", "offset must be a non-negative integer"),
281
268
  "target": ("TARGET_REQUIRED", "target must be a non-empty string"),
@@ -330,7 +317,7 @@ def _parse_command_request[RequestT: _CommandRequest](
330
317
  raise CommandDispatchError(code, message) from error
331
318
 
332
319
 
333
- SessionBindingValidator = Callable[[str, Mapping[str, object]], Awaitable[None]]
320
+ SessionBindingValidator = Callable[[Actor, Mapping[str, object]], Awaitable[None]]
334
321
 
335
322
 
336
323
  class CommandDispatcher:
@@ -340,9 +327,11 @@ class CommandDispatcher:
340
327
  self,
341
328
  service: ICommandService,
342
329
  *,
330
+ actors: Actors,
343
331
  timeout_budget: TimeoutBudget,
344
332
  session_binding_validator: SessionBindingValidator | None = None,
345
333
  ) -> None:
334
+ self._actors = actors
346
335
  self._service = service
347
336
  self._timeout_budget = timeout_budget
348
337
  self._session_binding_validator = session_binding_validator
@@ -351,6 +340,12 @@ class CommandDispatcher:
351
340
  self._drained = asyncio.Event()
352
341
  self._drained.set()
353
342
 
343
+ def _resolve_actor(self, actor_id: str) -> Actor:
344
+ try:
345
+ return self._actors.resolve(actor_id)
346
+ except ValueError as error:
347
+ raise CommandDispatchError("SESSION_NOT_FOUND", str(error)) from error
348
+
354
349
  @property
355
350
  def accepting(self) -> bool:
356
351
  return self._accepting
@@ -422,7 +417,7 @@ class CommandDispatcher:
422
417
  if error.next_action is not None:
423
418
  response["next_action"] = error.next_action
424
419
  return response
425
- except SessionNotFoundError as error:
420
+ except ThreadNotFoundError as error:
426
421
  return {
427
422
  "ok": False,
428
423
  "code": "SESSION_NOT_FOUND",
@@ -476,51 +471,76 @@ class CommandDispatcher:
476
471
  )
477
472
 
478
473
  request = _parse_command_request(raw_request, _REQUEST_MODELS[route])
479
- session_id = request.session_id
474
+ actor = self._resolve_actor(request.actor_id)
480
475
  if self._session_binding_validator is not None:
481
- await self._session_binding_validator(session_id, raw_request)
476
+ await self._session_binding_validator(actor, raw_request)
482
477
 
483
478
  match route:
484
479
  case ("message", "check"):
485
- return await self._check_messages(session_id)
480
+ return await self._check_messages(actor)
486
481
  case ("message", "read"):
487
482
  return await self._read_messages(
488
- session_id, cast(_MessageReadRequest, request)
483
+ actor, cast(_MessageReadRequest, request)
489
484
  )
490
485
  case ("message", "send"):
491
486
  return await self._send_message(
492
- session_id, cast(_MessageSendRequest, request)
493
- )
494
- case ("inbox", "list"):
495
- return await self._list_inbox(
496
- session_id, cast(_InboxListRequest, request)
487
+ actor, cast(_MessageSendRequest, request)
497
488
  )
489
+ case ("inbox", "check"):
490
+ return await self._check_inbox(actor)
498
491
  case ("thread", "unfollow"):
499
492
  return await self._unfollow_thread(
500
- session_id, cast(_ThreadUnfollowRequest, request)
493
+ actor, cast(_ThreadUnfollowRequest, request)
501
494
  )
502
495
  case _:
503
496
  raise AssertionError("validated command route has no handler")
504
497
 
505
- async def _check_messages(self, session_id: str) -> Mapping[str, object]:
506
- result = await self._service.check(session_id)
498
+ async def _check_messages(self, actor: Actor) -> Mapping[str, object]:
499
+ drained = await self._service.check(actor)
500
+ projections = tuple(
501
+ projection for result in drained for projection in result.target_projections
502
+ )
507
503
  return {
508
504
  "ok": True,
509
505
  "result": {
510
- "messages": _serialized(result.messages, result.target_projections),
506
+ "messages": _serialized(
507
+ sorted(
508
+ (message for result in drained for message in result.messages),
509
+ key=lambda message: (
510
+ message.received_at_ms
511
+ if message.received_at_ms is not None
512
+ else message.created_at_ms or 0,
513
+ message.thread_id,
514
+ message.seq,
515
+ ),
516
+ ),
517
+ projections,
518
+ ),
511
519
  "referenced_messages": _serialized(
512
- result.referenced_messages, result.target_projections
520
+ tuple(
521
+ message
522
+ for result in drained
523
+ for message in result.referenced_messages
524
+ ),
525
+ projections,
513
526
  ),
514
- "snapshot_seq": result.snapshot_seq,
515
- "delivered_through_seq": result.delivered_through_seq,
527
+ },
528
+ }
529
+
530
+ async def _check_inbox(self, actor: Actor) -> Mapping[str, object]:
531
+ result = await self._service.pending_targets(actor)
532
+ return {
533
+ "ok": True,
534
+ "result": {
535
+ "targets": [serialize_inbox_target(target) for target in result.targets]
516
536
  },
517
537
  }
518
538
 
519
539
  async def _read_messages(
520
- self, session_id: str, request: _MessageReadRequest
540
+ self, actor: Actor, request: _MessageReadRequest
521
541
  ) -> Mapping[str, object]:
522
542
  result = await self._service.read(
523
- session_id,
543
+ actor,
524
544
  raw_target=request.target,
525
545
  around_message_id=request.around_message_id,
526
546
  limit=request.limit,
@@ -539,10 +559,10 @@ class CommandDispatcher:
539
559
  }
540
560
 
541
561
  async def _send_message(
542
- self, session_id: str, request: _MessageSendRequest
562
+ self, actor: Actor, request: _MessageSendRequest
543
563
  ) -> Mapping[str, object]:
544
564
  result = await self._service.send(
545
- session_id=session_id,
565
+ actor=actor,
546
566
  command_id=request.command_id,
547
567
  raw_target=request.target,
548
568
  body=request.body,
@@ -581,20 +601,10 @@ class CommandDispatcher:
581
601
  )
582
602
  return {"ok": True, "result": {"text": text}}
583
603
 
584
- async def _list_inbox(
585
- self, session_id: str, request: _InboxListRequest
586
- ) -> Mapping[str, object]:
587
- result = await self._service.list_inbox(
588
- session_id,
589
- limit=request.limit,
590
- offset=request.offset,
591
- )
592
- return {"ok": True, "result": serialize_inbox_list(result)}
593
-
594
604
  async def _unfollow_thread(
595
- self, session_id: str, request: _ThreadUnfollowRequest
605
+ self, actor: Actor, request: _ThreadUnfollowRequest
596
606
  ) -> Mapping[str, object]:
597
- result = await self._service.unfollow(session_id, raw_target=request.target)
607
+ result = await self._service.unfollow(actor, raw_target=request.target)
598
608
  return {
599
609
  "ok": True,
600
610
  "result": {"target": result.target, "changed": result.changed},