bazaar-compute-node 0.1.38__tar.gz → 0.1.39__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.38 → bazaar_compute_node-0.1.39}/PKG-INFO +2 -1
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/pyproject.toml +2 -1
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/pyproject.toml.orig +2 -1
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/agent.py +7 -15
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/app/agent_management.py +213 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/application.py +5 -9
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/attachments.py +70 -58
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/command.py +145 -140
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/resource_dispatch.py +188 -148
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/system_service.py +4 -45
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/transport.py +2 -1
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/app/usage.py +12 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/windows_pipe.py +4 -6
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/bcc.py +9 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cli.py +9 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/__init__.py +0 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/__init__.py +62 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/_client.py +84 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/_format.py +277 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/inbox.py +37 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/message.py +125 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/node.py +52 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/reminder.py +175 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcc/thread.py +31 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcn/__init__.py +70 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcn/_options.py +94 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcn/_runner.py +22 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcn/agent.py +125 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcn/node.py +189 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/cmd/bcn/service.py +63 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/approval.py +22 -18
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/contrib/claude/events.py +633 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/runtime.py +80 -49
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/approval.py +83 -65
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/contrib/codex/events.py +747 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/process.py +0 -4
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/runtime.py +247 -217
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/api.py +196 -162
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/approval.py +19 -86
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/attachments.py +65 -77
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/channel.py +357 -272
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/outbound.py +162 -255
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/transport.py +254 -104
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/database.py +42 -43
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/registry.py +3 -6
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/repository/facade.py +69 -34
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/repository/messages.py +161 -125
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/storage.py +0 -6
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/api.py +16 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/approval.py +150 -91
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/attachments.py +63 -46
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/channel.py +203 -91
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/markdown.py +100 -85
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/outbound.py +253 -190
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/contrib/wecom/channel.py +1792 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/agent.py +49 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/approval.py +85 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/audit.py +15 -34
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/channel.py +34 -56
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/command.py +0 -6
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/correlation.py +22 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/inbox.py +0 -4
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/models/__init__.py +50 -24
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/models/entities.py +1 -33
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/models/events.py +177 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/models/reminder.py +1 -8
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/models/states.py +62 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/command.py +208 -97
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/error_feedback.py +12 -1
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/reminder.py +33 -6
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/reminder_command.py +2 -6
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/services.py +4 -80
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/session.py +512 -514
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/orchestration/turn.py +901 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/outcomes.py +0 -11
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/reminder.py +0 -12
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/reminder_schedule.py +0 -8
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/runtime.py +87 -24
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/utils/clock.py +15 -0
- {bazaar_compute_node-0.1.38/src/bazaar_compute_node/contrib/wecom → bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/utils}/markdown.py +103 -85
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/utils/sanitization.py +44 -0
- bazaar_compute_node-0.1.39/src/bazaar_compute_node/core/utils/text.py +36 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/rendering.py +5 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/locales/en.toml +5 -1
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/locales/zh-CN.toml +5 -1
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/app/agent_management.py +0 -269
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/bcc.py +0 -808
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/cli.py +0 -302
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/contrib/claude/events.py +0 -481
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/contrib/codex/events.py +0 -398
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/contrib/wecom/channel.py +0 -1340
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/core/approval.py +0 -51
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/core/correlation.py +0 -42
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/core/models/states.py +0 -375
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/core/orchestration/runtime_pool.py +0 -62
- bazaar_compute_node-0.1.38/src/bazaar_compute_node/core/orchestration/turn.py +0 -714
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/LICENSE +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/README.md +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/config.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/registry.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/upgrade.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/version_check.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/wrapper.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/client.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/process.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/claude/protocol.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/frame.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/identity.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/lark/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/logging/audit.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/codec.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/executor.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/model.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v01_initial_node_schema.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v02_session_mapping_indexes.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v03_message_log_indexes.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v04_runtime_attempt_facts.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v05_inbound_message_references.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v06_inbound_message_reference_integrity.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v07_inbound_provider_identity.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v08_transient_stream_events.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v09_remove_runtime_events.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v10_add_outbound_attachments.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v11_remove_runtime_session_mapping.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v12_add_reminders.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v13_add_agent_ownership.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v14_add_inbox_discovery_indexes.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v15_add_handoffs.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v16_remove_outbound_drafts.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v17_remove_agent_identity_triggers.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v18_unify_messages.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v19_reminder_system_messages.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v20_remove_freshness_persistence.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v21_remove_handoffs.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v22_readable_targets.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v23_persist_sender_identity.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/migrations/v24_persist_sender_display_name.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/repository/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/repository/base.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/repository/reminders.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/sqlite/repository/sessions.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/client.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/concurrency.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/instruction.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/lifecycle.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/models/reminder_owner.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/observability.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/orchestration/upgrade_notice.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/paths.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/restart.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/storage.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/timerwheel.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/utils/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/core/utils/line_reader.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/i18n/__init__.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/i18n/catalog.py +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/approval_no_person.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/check.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/error.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/inbox_list.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/inbox_target.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/read.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/reminder_list.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/reminder_mutation.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/reminder_schedule.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/unfollow.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/upgrade.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/bcc/version.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/command/attachment_suffix.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/command/check_message.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/command/freshness_hold.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/command/read_message.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/command/send_result.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/command/sender.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/developer_instructions.md +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/inbox_notice.tpl +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/system_service/launchd.plist +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/system_service/launchd.sh +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/system_service/systemd.service +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/system_service/windows.ps1 +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/system_service/windows.vbs +0 -0
- {bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/resources/system_service/windows.xml +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bazaar-compute-node
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.39
|
|
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
|
|
7
7
|
Requires-Dist: aiohttp>=3.12.0
|
|
8
8
|
Requires-Dist: aiosqlite>=0.20.0
|
|
9
|
+
Requires-Dist: click>=8.1.0
|
|
9
10
|
Requires-Dist: cryptography>=45.0.0
|
|
10
11
|
Requires-Dist: jinja2>=3.1.6
|
|
11
12
|
Requires-Dist: packaging>=25.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bazaar-compute-node"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.39"
|
|
4
4
|
description = "Runtime-agnostic computer node daemon for agents and channels."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-only"
|
|
@@ -9,6 +9,7 @@ requires-python = ">=3.14"
|
|
|
9
9
|
dependencies = [
|
|
10
10
|
"aiohttp>=3.12.0",
|
|
11
11
|
"aiosqlite>=0.20.0",
|
|
12
|
+
"click>=8.1.0",
|
|
12
13
|
"cryptography>=45.0.0",
|
|
13
14
|
"jinja2>=3.1.6",
|
|
14
15
|
"packaging>=25.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bazaar-compute-node"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.39"
|
|
4
4
|
description = "Runtime-agnostic computer node daemon for agents and channels."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-only"
|
|
@@ -9,6 +9,7 @@ requires-python = ">=3.14"
|
|
|
9
9
|
dependencies = [
|
|
10
10
|
"aiohttp>=3.12.0",
|
|
11
11
|
"aiosqlite>=0.20.0",
|
|
12
|
+
"click>=8.1.0",
|
|
12
13
|
"cryptography>=45.0.0",
|
|
13
14
|
"jinja2>=3.1.6",
|
|
14
15
|
"packaging>=25.0",
|
{bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/agent.py
RENAMED
|
@@ -12,7 +12,7 @@ from dataclasses import dataclass
|
|
|
12
12
|
from functools import partial
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
|
|
15
|
-
from ..core.channel import
|
|
15
|
+
from ..core.channel import Channel, ChannelContext, IChannel
|
|
16
16
|
from ..core.concurrency import ISessionConcurrency, SessionLockRegistry
|
|
17
17
|
from ..core.lifecycle import TimeoutBudget
|
|
18
18
|
from ..core.models import (
|
|
@@ -113,7 +113,7 @@ class AgentApplication:
|
|
|
113
113
|
timer_wheel=self.timer_wheel,
|
|
114
114
|
)
|
|
115
115
|
)
|
|
116
|
-
self.channel: IChannel =
|
|
116
|
+
self.channel: IChannel = Channel(self.agent_id, provider_channel)
|
|
117
117
|
runtime_contexts: list[RuntimeCommandContext] = []
|
|
118
118
|
runtimes: list[IRuntime] = []
|
|
119
119
|
for index, runtime_configuration in enumerate(configuration.runtimes):
|
|
@@ -170,7 +170,7 @@ class AgentApplication:
|
|
|
170
170
|
),
|
|
171
171
|
workspace=self.workspace_path,
|
|
172
172
|
translator=self.translator,
|
|
173
|
-
error_feedback_detail=self.
|
|
173
|
+
error_feedback_detail=self._redact_session_secrets,
|
|
174
174
|
upgrade_notice=upgrade_notice,
|
|
175
175
|
concurrency=self._concurrency,
|
|
176
176
|
)
|
|
@@ -440,21 +440,13 @@ class AgentApplication:
|
|
|
440
440
|
)
|
|
441
441
|
return environment
|
|
442
442
|
|
|
443
|
-
def
|
|
444
|
-
self,
|
|
445
|
-
session_id: object,
|
|
446
|
-
error_message: object,
|
|
447
|
-
) -> str:
|
|
448
|
-
if not isinstance(session_id, str) or not session_id:
|
|
449
|
-
raise ValueError("session_id must be a non-empty string")
|
|
450
|
-
if not isinstance(error_message, str):
|
|
451
|
-
raise TypeError("error_message must be text")
|
|
443
|
+
def _redact_session_secrets(self, session_id: str, text: str) -> str:
|
|
452
444
|
binding = self._session_capabilities.get(session_id)
|
|
453
445
|
if binding is None:
|
|
454
|
-
return
|
|
446
|
+
return text
|
|
455
447
|
for token in binding.token_values:
|
|
456
|
-
|
|
457
|
-
return
|
|
448
|
+
text = text.replace(token, "<redacted>")
|
|
449
|
+
return text
|
|
458
450
|
|
|
459
451
|
async def _run_runtime_command(
|
|
460
452
|
self,
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from collections.abc import Sequence
|
|
5
|
+
from dataclasses import dataclass, replace
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from types import MappingProxyType
|
|
8
|
+
from typing import Any
|
|
9
|
+
from uuid import uuid7
|
|
10
|
+
|
|
11
|
+
from ..core.runtime import RuntimeSandboxMode
|
|
12
|
+
from ..i18n import create_translator
|
|
13
|
+
from .config import (
|
|
14
|
+
AgentConfiguration,
|
|
15
|
+
ChannelConfiguration,
|
|
16
|
+
ConfigurationError,
|
|
17
|
+
NodeConfiguration,
|
|
18
|
+
RuntimeConfiguration,
|
|
19
|
+
_write_configuration,
|
|
20
|
+
load_node_configuration,
|
|
21
|
+
resolve_config_path,
|
|
22
|
+
)
|
|
23
|
+
from .usage import Usage
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True, slots=True)
|
|
27
|
+
class _SetOptions:
|
|
28
|
+
agent: dict[str, object]
|
|
29
|
+
channel: dict[str, object]
|
|
30
|
+
runtime: dict[str, object]
|
|
31
|
+
env: dict[str, str]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _set_options(
|
|
35
|
+
agent_options: Sequence[tuple[str, str, Any]], parser: Usage
|
|
36
|
+
) -> _SetOptions:
|
|
37
|
+
"""Sort every --set value under the scope it names."""
|
|
38
|
+
|
|
39
|
+
options = _SetOptions(agent={}, channel={}, runtime={}, env={})
|
|
40
|
+
seen: set[tuple[str, str]] = set()
|
|
41
|
+
for scope, key, value in agent_options:
|
|
42
|
+
# runtime.env accumulates one name per --set; a repeated name is
|
|
43
|
+
# simply overwritten, the same as a hand-edited config.toml would be
|
|
44
|
+
if (scope, key) == ("runtime", "env"):
|
|
45
|
+
options.env.update(value)
|
|
46
|
+
continue
|
|
47
|
+
identity = (scope, key)
|
|
48
|
+
if identity in seen:
|
|
49
|
+
parser.error(f"duplicate --set option: {scope}.{key}")
|
|
50
|
+
seen.add(identity)
|
|
51
|
+
if scope == "agent":
|
|
52
|
+
options.agent[key] = value
|
|
53
|
+
elif scope == "channel":
|
|
54
|
+
options.channel[key] = value
|
|
55
|
+
else:
|
|
56
|
+
options.runtime[key] = value
|
|
57
|
+
return options
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _runtime_configuration(
|
|
61
|
+
kind: str, options: _SetOptions, parser: Usage
|
|
62
|
+
) -> RuntimeConfiguration:
|
|
63
|
+
"""Read the runtime settings out of what --set collected."""
|
|
64
|
+
|
|
65
|
+
values = options.runtime
|
|
66
|
+
model = values.pop("model", None)
|
|
67
|
+
effort = values.pop("effort", None)
|
|
68
|
+
raw_sandbox_mode = values.pop(
|
|
69
|
+
"sandbox_mode",
|
|
70
|
+
RuntimeSandboxMode.WORKSPACE_WRITE.value,
|
|
71
|
+
)
|
|
72
|
+
if not isinstance(raw_sandbox_mode, str):
|
|
73
|
+
parser.error("runtime.sandbox_mode must be text")
|
|
74
|
+
try:
|
|
75
|
+
sandbox_mode = RuntimeSandboxMode(raw_sandbox_mode)
|
|
76
|
+
except ValueError:
|
|
77
|
+
allowed = ", ".join(mode.value for mode in RuntimeSandboxMode)
|
|
78
|
+
parser.error(f"runtime.sandbox_mode must be one of: {allowed}")
|
|
79
|
+
network_access = values.pop("network_access", True)
|
|
80
|
+
if not isinstance(network_access, bool):
|
|
81
|
+
parser.error("runtime.network_access must be a boolean")
|
|
82
|
+
if model is not None and not isinstance(model, str):
|
|
83
|
+
parser.error("runtime.model must be text")
|
|
84
|
+
if effort is not None and not isinstance(effort, str):
|
|
85
|
+
parser.error("runtime.effort must be text")
|
|
86
|
+
return RuntimeConfiguration(
|
|
87
|
+
kind=kind,
|
|
88
|
+
model=model,
|
|
89
|
+
effort=effort,
|
|
90
|
+
sandbox_mode=sandbox_mode,
|
|
91
|
+
network_access=network_access,
|
|
92
|
+
env=MappingProxyType(options.env),
|
|
93
|
+
options=MappingProxyType(values),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _list_agents(configuration: NodeConfiguration) -> int:
|
|
98
|
+
if not configuration.agents:
|
|
99
|
+
print(create_translator(None).text("cli.agent.empty"), flush=True)
|
|
100
|
+
return 0
|
|
101
|
+
for agent in configuration.agents:
|
|
102
|
+
print(
|
|
103
|
+
f"id={agent.id} name={agent.name} "
|
|
104
|
+
f"channel={agent.channel.kind} runtime={_runtime_kinds(agent)}",
|
|
105
|
+
flush=True,
|
|
106
|
+
)
|
|
107
|
+
return 0
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _add_agent(
|
|
111
|
+
args: argparse.Namespace,
|
|
112
|
+
parser: Usage,
|
|
113
|
+
configuration: NodeConfiguration,
|
|
114
|
+
config_path: Path,
|
|
115
|
+
) -> int:
|
|
116
|
+
options = _set_options(args.agent_options, parser)
|
|
117
|
+
|
|
118
|
+
idle_timeout = options.agent.pop("idle_timeout", 0)
|
|
119
|
+
if isinstance(idle_timeout, bool) or not isinstance(idle_timeout, int | float):
|
|
120
|
+
parser.error("agent.idle_timeout must be a number")
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
agent = AgentConfiguration(
|
|
124
|
+
id=str(uuid7()),
|
|
125
|
+
name=args.name,
|
|
126
|
+
channel=ChannelConfiguration(
|
|
127
|
+
kind=args.channel,
|
|
128
|
+
options=MappingProxyType(options.channel),
|
|
129
|
+
),
|
|
130
|
+
runtimes=(_runtime_configuration(args.runtime, options, parser),),
|
|
131
|
+
idle_timeout_seconds=idle_timeout,
|
|
132
|
+
)
|
|
133
|
+
updated = replace(
|
|
134
|
+
configuration,
|
|
135
|
+
agents=(*configuration.agents, agent),
|
|
136
|
+
)
|
|
137
|
+
_write_configuration(config_path, updated)
|
|
138
|
+
except ConfigurationError as error:
|
|
139
|
+
parser.error(str(error))
|
|
140
|
+
print(
|
|
141
|
+
f"Agent added id={agent.id} name={agent.name} "
|
|
142
|
+
f"channel={agent.channel.kind} runtime={_runtime_kinds(agent)}",
|
|
143
|
+
flush=True,
|
|
144
|
+
)
|
|
145
|
+
print("Run `bcn restart` to apply.", flush=True)
|
|
146
|
+
return 0
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _remove_agent(
|
|
150
|
+
args: argparse.Namespace,
|
|
151
|
+
parser: Usage,
|
|
152
|
+
configuration: NodeConfiguration,
|
|
153
|
+
config_path: Path,
|
|
154
|
+
) -> int:
|
|
155
|
+
matches = [
|
|
156
|
+
agent
|
|
157
|
+
for agent in configuration.agents
|
|
158
|
+
if agent.id == args.selector or agent.name == args.selector
|
|
159
|
+
]
|
|
160
|
+
if not matches:
|
|
161
|
+
parser.error(f"Agent not found: {args.selector}")
|
|
162
|
+
if len(matches) > 1:
|
|
163
|
+
parser.error(f"Agent selector is ambiguous: {args.selector}")
|
|
164
|
+
removed = matches[0]
|
|
165
|
+
updated = replace(
|
|
166
|
+
configuration,
|
|
167
|
+
agents=tuple(agent for agent in configuration.agents if agent.id != removed.id),
|
|
168
|
+
)
|
|
169
|
+
try:
|
|
170
|
+
_write_configuration(config_path, updated)
|
|
171
|
+
except ConfigurationError as error:
|
|
172
|
+
parser.error(str(error))
|
|
173
|
+
print(f"Agent removed id={removed.id} name={removed.name}", flush=True)
|
|
174
|
+
print("Workspace and durable data were preserved.", flush=True)
|
|
175
|
+
print("Run `bcn restart` to apply.", flush=True)
|
|
176
|
+
return 0
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def run_agent_command(
|
|
180
|
+
args: argparse.Namespace,
|
|
181
|
+
parser: Usage,
|
|
182
|
+
) -> int:
|
|
183
|
+
if (
|
|
184
|
+
args.storage is not None
|
|
185
|
+
or args.audit is not None
|
|
186
|
+
or args.database_name is not None
|
|
187
|
+
or args.endpoint is not None
|
|
188
|
+
or args.foreground
|
|
189
|
+
):
|
|
190
|
+
parser.error("bcn agent commands only accept the node-level --config option")
|
|
191
|
+
|
|
192
|
+
config_path = (args.config or resolve_config_path()).expanduser()
|
|
193
|
+
try:
|
|
194
|
+
configuration = load_node_configuration(config_path)
|
|
195
|
+
except ConfigurationError as error:
|
|
196
|
+
parser.error(str(error))
|
|
197
|
+
|
|
198
|
+
match args.agent_command:
|
|
199
|
+
case "list":
|
|
200
|
+
return _list_agents(configuration)
|
|
201
|
+
case "add":
|
|
202
|
+
return _add_agent(args, parser, configuration, config_path)
|
|
203
|
+
case "remove":
|
|
204
|
+
return _remove_agent(args, parser, configuration, config_path)
|
|
205
|
+
case unsupported:
|
|
206
|
+
raise AssertionError(f"unsupported Agent command: {unsupported}")
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _runtime_kinds(agent: AgentConfiguration) -> str:
|
|
210
|
+
return ",".join(runtime.kind for runtime in agent.runtimes)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
__all__ = ["run_agent_command"]
|
{bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/application.py
RENAMED
|
@@ -19,6 +19,7 @@ from ..core.paths import resolve_data_dir
|
|
|
19
19
|
from ..core.restart import RESTART_EXIT_CODE
|
|
20
20
|
from ..core.storage import IStorage
|
|
21
21
|
from ..core.timerwheel import TimerWheel
|
|
22
|
+
from ..core.utils.text import format_exception
|
|
22
23
|
from ..i18n import create_translator
|
|
23
24
|
from .agent import AgentApplication
|
|
24
25
|
from .config import AgentConfiguration, NodeConfiguration
|
|
@@ -214,7 +215,7 @@ class NodeApplication:
|
|
|
214
215
|
runtimes=_runtime_kinds(configuration),
|
|
215
216
|
status="failed",
|
|
216
217
|
error_type=type(error).__name__,
|
|
217
|
-
error=
|
|
218
|
+
error=format_exception(error),
|
|
218
219
|
)
|
|
219
220
|
self.agent_startup_results[configuration.id] = result
|
|
220
221
|
self._log("agent.start.failed", **result.as_health_record())
|
|
@@ -265,7 +266,7 @@ class NodeApplication:
|
|
|
265
266
|
"agent.stop.failed",
|
|
266
267
|
agent_id=agent_id,
|
|
267
268
|
error_type=type(error).__name__,
|
|
268
|
-
error=
|
|
269
|
+
error=format_exception(error),
|
|
269
270
|
)
|
|
270
271
|
self.agents.clear()
|
|
271
272
|
try:
|
|
@@ -349,7 +350,7 @@ class NodeApplication:
|
|
|
349
350
|
"bcn.critical.failed",
|
|
350
351
|
component=component,
|
|
351
352
|
error_type=type(error).__name__,
|
|
352
|
-
error=
|
|
353
|
+
error=format_exception(error),
|
|
353
354
|
)
|
|
354
355
|
raise error
|
|
355
356
|
finally:
|
|
@@ -381,7 +382,7 @@ class NodeApplication:
|
|
|
381
382
|
agent_id=agent_id,
|
|
382
383
|
owner_session_id=message.session_id,
|
|
383
384
|
error_type=type(error).__name__,
|
|
384
|
-
error=
|
|
385
|
+
error=format_exception(error),
|
|
385
386
|
)
|
|
386
387
|
return False
|
|
387
388
|
return True
|
|
@@ -508,9 +509,4 @@ class NodeApplication:
|
|
|
508
509
|
)
|
|
509
510
|
|
|
510
511
|
|
|
511
|
-
def _safe_error(error: BaseException) -> str:
|
|
512
|
-
message = str(error).strip()
|
|
513
|
-
return message or type(error).__name__
|
|
514
|
-
|
|
515
|
-
|
|
516
512
|
__all__ = ["AgentStartupResult", "NodeApplication"]
|
{bazaar_compute_node-0.1.38 → bazaar_compute_node-0.1.39}/src/bazaar_compute_node/app/attachments.py
RENAMED
|
@@ -61,6 +61,75 @@ class AttachmentMaterializer:
|
|
|
61
61
|
continue
|
|
62
62
|
await asyncio.to_thread(shutil.rmtree, path)
|
|
63
63
|
|
|
64
|
+
async def _stage(
|
|
65
|
+
self,
|
|
66
|
+
source: bytes | AsyncIterable[bytes],
|
|
67
|
+
temporary: Path,
|
|
68
|
+
destination: Path,
|
|
69
|
+
root: Path,
|
|
70
|
+
) -> int:
|
|
71
|
+
"""Write an attachment aside, then move it into place once it is whole."""
|
|
72
|
+
|
|
73
|
+
current_size = await asyncio.to_thread(self._stored_size, root)
|
|
74
|
+
descriptor: int | None = None
|
|
75
|
+
try:
|
|
76
|
+
descriptor = await asyncio.to_thread(
|
|
77
|
+
os.open,
|
|
78
|
+
temporary,
|
|
79
|
+
os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_BINARY", 0),
|
|
80
|
+
0o600,
|
|
81
|
+
)
|
|
82
|
+
try:
|
|
83
|
+
size = await self._write(descriptor, source, current_size)
|
|
84
|
+
await asyncio.to_thread(os.fsync, descriptor)
|
|
85
|
+
stored = await asyncio.to_thread(os.fstat, descriptor)
|
|
86
|
+
if stored.st_size != size:
|
|
87
|
+
raise OSError(
|
|
88
|
+
"attachment write size mismatch: "
|
|
89
|
+
f"expected {size}, got {stored.st_size}"
|
|
90
|
+
)
|
|
91
|
+
finally:
|
|
92
|
+
await asyncio.to_thread(os.close, descriptor)
|
|
93
|
+
descriptor = None
|
|
94
|
+
await asyncio.to_thread(destination.parent.mkdir, parents=True, mode=0o700)
|
|
95
|
+
await asyncio.to_thread(os.replace, temporary, destination)
|
|
96
|
+
if os.name != "nt":
|
|
97
|
+
await asyncio.to_thread(destination.chmod, 0o600)
|
|
98
|
+
return size
|
|
99
|
+
except BaseException:
|
|
100
|
+
if descriptor is not None:
|
|
101
|
+
await asyncio.to_thread(os.close, descriptor)
|
|
102
|
+
if await asyncio.to_thread(temporary.exists):
|
|
103
|
+
await asyncio.to_thread(temporary.unlink)
|
|
104
|
+
raise
|
|
105
|
+
|
|
106
|
+
async def _write(
|
|
107
|
+
self,
|
|
108
|
+
descriptor: int,
|
|
109
|
+
source: bytes | AsyncIterable[bytes],
|
|
110
|
+
current_size: int,
|
|
111
|
+
) -> int:
|
|
112
|
+
"""Write the source through, refusing it the moment it goes over a limit."""
|
|
113
|
+
|
|
114
|
+
if isinstance(source, bytes):
|
|
115
|
+
self._check_room(len(source), current_size)
|
|
116
|
+
await asyncio.to_thread(_write_all, descriptor, source)
|
|
117
|
+
return len(source)
|
|
118
|
+
size = 0
|
|
119
|
+
async for chunk in source:
|
|
120
|
+
if not isinstance(chunk, bytes):
|
|
121
|
+
raise TypeError("attachment stream must yield bytes")
|
|
122
|
+
size += len(chunk)
|
|
123
|
+
self._check_room(size, current_size)
|
|
124
|
+
await asyncio.to_thread(_write_all, descriptor, chunk)
|
|
125
|
+
return size
|
|
126
|
+
|
|
127
|
+
def _check_room(self, size: int, current_size: int) -> None:
|
|
128
|
+
if size > self._max_file_bytes:
|
|
129
|
+
raise ValueError("attachment exceeds the per-file size limit")
|
|
130
|
+
if current_size + size > self._max_workspace_bytes:
|
|
131
|
+
raise ValueError("attachment workspace quota exceeded")
|
|
132
|
+
|
|
64
133
|
async def materialize(
|
|
65
134
|
self,
|
|
66
135
|
source: bytes | AsyncIterable[bytes],
|
|
@@ -84,64 +153,7 @@ class AttachmentMaterializer:
|
|
|
84
153
|
await asyncio.to_thread(
|
|
85
154
|
staging.mkdir, parents=True, exist_ok=True, mode=0o700
|
|
86
155
|
)
|
|
87
|
-
|
|
88
|
-
size = 0
|
|
89
|
-
descriptor: int | None = None
|
|
90
|
-
try:
|
|
91
|
-
open_flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
|
|
92
|
-
binary_flag = getattr(os, "O_BINARY", None)
|
|
93
|
-
if binary_flag is not None:
|
|
94
|
-
open_flags |= binary_flag
|
|
95
|
-
descriptor = await asyncio.to_thread(
|
|
96
|
-
os.open,
|
|
97
|
-
temporary,
|
|
98
|
-
open_flags,
|
|
99
|
-
0o600,
|
|
100
|
-
)
|
|
101
|
-
try:
|
|
102
|
-
if isinstance(source, bytes):
|
|
103
|
-
size = len(source)
|
|
104
|
-
if size > self._max_file_bytes:
|
|
105
|
-
raise ValueError(
|
|
106
|
-
"attachment exceeds the per-file size limit"
|
|
107
|
-
)
|
|
108
|
-
if current_size + size > self._max_workspace_bytes:
|
|
109
|
-
raise ValueError("attachment workspace quota exceeded")
|
|
110
|
-
await asyncio.to_thread(_write_all, descriptor, source)
|
|
111
|
-
else:
|
|
112
|
-
async for chunk in source:
|
|
113
|
-
if not isinstance(chunk, bytes):
|
|
114
|
-
raise TypeError("attachment stream must yield bytes")
|
|
115
|
-
size += len(chunk)
|
|
116
|
-
if size > self._max_file_bytes:
|
|
117
|
-
raise ValueError(
|
|
118
|
-
"attachment exceeds the per-file size limit"
|
|
119
|
-
)
|
|
120
|
-
if current_size + size > self._max_workspace_bytes:
|
|
121
|
-
raise ValueError("attachment workspace quota exceeded")
|
|
122
|
-
await asyncio.to_thread(_write_all, descriptor, chunk)
|
|
123
|
-
await asyncio.to_thread(os.fsync, descriptor)
|
|
124
|
-
stored_size = await asyncio.to_thread(os.fstat, descriptor)
|
|
125
|
-
if stored_size.st_size != size:
|
|
126
|
-
raise OSError(
|
|
127
|
-
"attachment write size mismatch: "
|
|
128
|
-
f"expected {size}, got {stored_size.st_size}"
|
|
129
|
-
)
|
|
130
|
-
finally:
|
|
131
|
-
await asyncio.to_thread(os.close, descriptor)
|
|
132
|
-
descriptor = None
|
|
133
|
-
await asyncio.to_thread(
|
|
134
|
-
destination.parent.mkdir, parents=True, mode=0o700
|
|
135
|
-
)
|
|
136
|
-
await asyncio.to_thread(os.replace, temporary, destination)
|
|
137
|
-
if os.name != "nt":
|
|
138
|
-
await asyncio.to_thread(destination.chmod, 0o600)
|
|
139
|
-
except BaseException:
|
|
140
|
-
if descriptor is not None:
|
|
141
|
-
await asyncio.to_thread(os.close, descriptor)
|
|
142
|
-
if await asyncio.to_thread(temporary.exists):
|
|
143
|
-
await asyncio.to_thread(temporary.unlink)
|
|
144
|
-
raise
|
|
156
|
+
size = await self._stage(source, temporary, destination, root)
|
|
145
157
|
return InboundAttachment(
|
|
146
158
|
attachment_id=attachment_id,
|
|
147
159
|
name=Path(name).name,
|