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.
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/PKG-INFO +5 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/README.md +4 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/pyproject.toml +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/pyproject.toml.orig +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent.py +56 -39
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/application.py +4 -4
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/command.py +66 -56
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/config.py +12 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/resource_dispatch.py +33 -25
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/wrapper.py +6 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/__init__.py +5 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/_client.py +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/_format.py +13 -52
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/cmd/bcc/inbox.py +22 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/message.py +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/thread.py +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/approval.py +3 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/events.py +4 -3
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/runtime.py +3 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/approval.py +3 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/events.py +5 -4
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/runtime.py +7 -6
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/channel.py +2 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/audit.py +5 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/codec.py +9 -9
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/registry.py +4 -0
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/sqlite/migrations/v25_rename_sessions_to_threads.py +37 -0
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/sqlite/migrations/v26_remove_handoff_messages.py +43 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/base.py +13 -11
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/facade.py +20 -20
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/messages.py +120 -84
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/reminders.py +27 -27
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/sessions.py +34 -32
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/storage.py +10 -3
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/approval.py +8 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/channel.py +41 -6
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/outbound.py +2 -1
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/contrib/telegram/plugin.py +43 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/channel.py +2 -2
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/actor.py +65 -0
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/agent.py +51 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/approval.py +3 -2
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/audit.py +154 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/channel.py +7 -14
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/command.py +24 -32
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/concurrency.py +29 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/correlation.py +4 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/instruction.py +3 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/__init__.py +2 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/entities.py +15 -11
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/events.py +3 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/reminder.py +1 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/reminder_owner.py +2 -2
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/models/states.py +0 -1
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/orchestration/__init__.py +6 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/command.py +123 -140
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/error_feedback.py +6 -7
- 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
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/reminder.py +11 -11
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/reminder_command.py +91 -83
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/core/orchestration/services.py +30 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/turn.py +165 -79
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/runtime.py +9 -7
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/storage.py +205 -232
- bazaar_compute_node-0.2.0rc2/src/bazaar_compute_node/resources/bcc/inbox_check.tpl +2 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/developer_instructions.md +5 -8
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/cmd/bcc/inbox.py +0 -37
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -23
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/agent.py +0 -49
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/audit.py +0 -70
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/concurrency.py +0 -29
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/orchestration/__init__.py +0 -6
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/core/orchestration/services.py +0 -90
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/resources/bcc/inbox_list.tpl +0 -3
- bazaar_compute_node-0.1.39rc4/src/bazaar_compute_node/resources/bcc/inbox_target.tpl +0 -1
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/LICENSE +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent_management.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/attachments.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/registry.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/system_service.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/transport.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/upgrade.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/usage.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/version_check.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/windows_pipe.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/bcc.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cli.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/node.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcc/reminder.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/_options.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/_runner.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/agent.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/node.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/cmd/bcn/service.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/client.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/plugin.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/process.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/claude/protocol.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/process.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/api.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/approval.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/attachments.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/frame.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/identity.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/outbound.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/plugin.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/lark/transport.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/database.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/executor.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/migrations/model.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/sqlite/repository/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/api.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/attachments.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/telegram/markdown.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/client.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/inbox.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/lifecycle.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/observability.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/orchestration/upgrade_notice.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/outcomes.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/paths.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/reminder.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/restart.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/timerwheel.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/clock.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/line_reader.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/markdown.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/sanitization.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/core/utils/text.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/i18n/__init__.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/i18n/catalog.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/rendering.py +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/approval_no_person.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/check.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/error.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/read.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_list.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_mutation.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/reminder_schedule.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/unfollow.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/upgrade.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/bcc/version.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/attachment_suffix.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/check_message.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/freshness_hold.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/read_message.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/send_result.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/command/sender.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/inbox_notice.tpl +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/locales/en.toml +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/locales/zh-CN.toml +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/launchd.plist +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/launchd.sh +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/systemd.service +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.ps1 +0 -0
- {bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/resources/system_service/windows.vbs +0 -0
- {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.
|
|
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 / 示例文件内容:
|
{bazaar_compute_node-0.1.39rc4 → bazaar_compute_node-0.2.0rc2}/src/bazaar_compute_node/app/agent.py
RENAMED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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.
|
|
159
|
-
|
|
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.
|
|
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.
|
|
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,
|
|
272
|
-
if not isinstance(
|
|
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.
|
|
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
|
|
328
|
+
async def _validate_actor_binding(
|
|
316
329
|
self,
|
|
317
|
-
|
|
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
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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[
|
|
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
|
-
"
|
|
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,
|
|
444
|
-
binding = self._session_capabilities.get(
|
|
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
|
-
|
|
468
|
+
thread_id: str,
|
|
454
469
|
arguments: Sequence[str],
|
|
455
470
|
body: str | None,
|
|
456
471
|
) -> None:
|
|
457
|
-
if not
|
|
458
|
-
raise ValueError("
|
|
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((
|
|
467
|
-
runtime_session = self.orchestrator.runtime_session(
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
|
222
|
+
class _InboxCheckRequest(_CommandRequest):
|
|
234
223
|
resource: Literal["inbox"]
|
|
235
|
-
command: Literal["
|
|
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", "
|
|
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
|
-
"
|
|
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[[
|
|
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
|
|
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
|
-
|
|
474
|
+
actor = self._resolve_actor(request.actor_id)
|
|
480
475
|
if self._session_binding_validator is not None:
|
|
481
|
-
await self._session_binding_validator(
|
|
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(
|
|
480
|
+
return await self._check_messages(actor)
|
|
486
481
|
case ("message", "read"):
|
|
487
482
|
return await self._read_messages(
|
|
488
|
-
|
|
483
|
+
actor, cast(_MessageReadRequest, request)
|
|
489
484
|
)
|
|
490
485
|
case ("message", "send"):
|
|
491
486
|
return await self._send_message(
|
|
492
|
-
|
|
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
|
-
|
|
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,
|
|
506
|
-
|
|
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(
|
|
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
|
-
|
|
520
|
+
tuple(
|
|
521
|
+
message
|
|
522
|
+
for result in drained
|
|
523
|
+
for message in result.referenced_messages
|
|
524
|
+
),
|
|
525
|
+
projections,
|
|
513
526
|
),
|
|
514
|
-
|
|
515
|
-
|
|
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,
|
|
540
|
+
self, actor: Actor, request: _MessageReadRequest
|
|
521
541
|
) -> Mapping[str, object]:
|
|
522
542
|
result = await self._service.read(
|
|
523
|
-
|
|
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,
|
|
562
|
+
self, actor: Actor, request: _MessageSendRequest
|
|
543
563
|
) -> Mapping[str, object]:
|
|
544
564
|
result = await self._service.send(
|
|
545
|
-
|
|
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,
|
|
605
|
+
self, actor: Actor, request: _ThreadUnfollowRequest
|
|
596
606
|
) -> Mapping[str, object]:
|
|
597
|
-
result = await self._service.unfollow(
|
|
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},
|