bazaar-compute-node 0.1.28__tar.gz → 0.1.30__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.28 → bazaar_compute_node-0.1.30}/PKG-INFO +2 -2
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/README.md +1 -1
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/pyproject.toml +2 -1
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/pyproject.toml.orig +2 -1
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/agent.py +1 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/application.py +85 -25
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/system_service.py +57 -161
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/transport.py +11 -2
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/windows_pipe.py +14 -2
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/__init__.py +28 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/approval.py +117 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/client.py +484 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/events.py +481 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/process.py +339 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/protocol.py +102 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude/runtime.py +628 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -2
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/client.py +0 -20
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/events.py +0 -8
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/codex/plugin.py +15 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/process.py +22 -36
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/protocol.py +4 -1
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/runtime.py +84 -52
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/channel.py +20 -1
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/database.py +4 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/executor.py +41 -5
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/storage.py +1 -1
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/channel.py +40 -1
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/core/lifecycle.py +100 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/reminder.py +57 -10
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/services.py +24 -12
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/session.py +190 -19
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/runtime.py +15 -9
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/timerwheel.py +9 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/core/utils/__init__.py +3 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/core/utils/line_reader.py +37 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/resources/system_service/launchd.plist +37 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/resources/system_service/launchd.sh +11 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/resources/system_service/systemd.service +19 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/resources/system_service/windows.ps1 +98 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/resources/system_service/windows.vbs +11 -0
- bazaar_compute_node-0.1.30/src/bazaar_compute_node/resources/system_service/windows.xml +39 -0
- bazaar_compute_node-0.1.28/src/bazaar_compute_node/core/lifecycle.py +0 -48
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/LICENSE +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/agent_management.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/attachments.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/command.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/config.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/registry.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/resource_dispatch.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/wrapper.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/bcc.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/cli.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/__init__.py +0 -0
- {bazaar_compute_node-0.1.28/src/bazaar_compute_node/contrib/codex → bazaar_compute_node-0.1.30/src/bazaar_compute_node/contrib/claude}/plugin.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/codex/approval.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/api.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/approval.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/attachments.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/frame.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/identity.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/outbound.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/plugin.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/lark/transport.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/logging/audit.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/codec.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/model.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/registry.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v01_initial_node_schema.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v02_session_mapping_indexes.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v03_message_log_indexes.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v04_runtime_attempt_facts.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v05_inbound_message_references.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v06_inbound_message_reference_integrity.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v07_inbound_provider_identity.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v08_transient_stream_events.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v09_remove_runtime_events.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v10_add_outbound_attachments.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v11_remove_runtime_session_mapping.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v12_add_reminders.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v13_add_agent_ownership.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v14_add_inbox_discovery_indexes.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v15_add_handoffs.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v16_remove_outbound_drafts.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v17_remove_agent_identity_triggers.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v18_unify_messages.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v19_reminder_system_messages.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v20_remove_freshness_persistence.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v21_remove_handoffs.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/migrations/v22_readable_targets.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/repository/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/repository/base.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/repository/facade.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/repository/messages.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/repository/reminders.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/sqlite/repository/sessions.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/api.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/approval.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/attachments.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/markdown.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/outbound.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/wecom/channel.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/wecom/markdown.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/approval.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/audit.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/channel.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/client.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/command.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/concurrency.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/correlation.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/inbox.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/instruction.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/models/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/models/entities.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/models/reminder.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/models/reminder_owner.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/models/states.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/observability.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/command.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/error_feedback.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/reminder_command.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/orchestration/turn.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/outcomes.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/paths.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/reminder.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/core/storage.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/i18n/__init__.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/i18n/catalog.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/rendering.py +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/resources/developer_instructions.md +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/resources/locales/en.toml +0 -0
- {bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/resources/locales/zh-CN.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bazaar-compute-node
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.30
|
|
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
|
|
@@ -110,7 +110,7 @@ Windows: Get-Content "$env:USERPROFILE\.bcn\system-service.log" -Wait
|
|
|
110
110
|
| Status / 状态 | Runtime / 运行时 |
|
|
111
111
|
| --- | --- |
|
|
112
112
|
| ✅ | Codex |
|
|
113
|
-
|
|
|
113
|
+
| ✅ | Claude Code |
|
|
114
114
|
| 🚧 | Pi |
|
|
115
115
|
| 🚧 | Hermes Agent |
|
|
116
116
|
| 🚧 | DeepSeek Harness |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bazaar-compute-node"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.30"
|
|
4
4
|
description = "Runtime-agnostic computer node daemon for agents and channels."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-only"
|
|
@@ -24,6 +24,7 @@ bcn = "bazaar_compute_node.cli:main"
|
|
|
24
24
|
|
|
25
25
|
[project.entry-points."bazaar_compute_node.runtimes"]
|
|
26
26
|
codex = "bazaar_compute_node.contrib.codex.plugin:create_runtime"
|
|
27
|
+
claudecode = "bazaar_compute_node.contrib.claude.plugin:create_runtime"
|
|
27
28
|
|
|
28
29
|
[project.entry-points."bazaar_compute_node.channels"]
|
|
29
30
|
wecom = "bazaar_compute_node.contrib.wecom.plugin:builder"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bazaar-compute-node"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.30"
|
|
4
4
|
description = "Runtime-agnostic computer node daemon for agents and channels."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-only"
|
|
@@ -24,6 +24,7 @@ bcn = "bazaar_compute_node.cli:main"
|
|
|
24
24
|
|
|
25
25
|
[project.entry-points."bazaar_compute_node.runtimes"]
|
|
26
26
|
codex = "bazaar_compute_node.contrib.codex.plugin:create_runtime"
|
|
27
|
+
claudecode = "bazaar_compute_node.contrib.claude.plugin:create_runtime"
|
|
27
28
|
|
|
28
29
|
[project.entry-points."bazaar_compute_node.channels"]
|
|
29
30
|
wecom = "bazaar_compute_node.contrib.wecom.plugin:builder"
|
{bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/agent.py
RENAMED
|
@@ -277,6 +277,7 @@ class AgentApplication:
|
|
|
277
277
|
"channel": self.channel.name,
|
|
278
278
|
"runtime": self.runtime.name,
|
|
279
279
|
"channel_health": dict(self.channel.health),
|
|
280
|
+
"orchestrator_health": self.orchestrator.health,
|
|
280
281
|
}
|
|
281
282
|
|
|
282
283
|
async def _cleanup_partial_start(self) -> None:
|
{bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/application.py
RENAMED
|
@@ -10,7 +10,7 @@ from dataclasses import dataclass
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
12
|
from ..core.concurrency import SessionLockRegistry
|
|
13
|
-
from ..core.lifecycle import TimeoutBudget
|
|
13
|
+
from ..core.lifecycle import ITaskFailureSource, TimeoutBudget
|
|
14
14
|
from ..core.models import InboundAttachment, Message
|
|
15
15
|
from ..core.observability import IAudit
|
|
16
16
|
from ..core.orchestration import ReminderScheduler
|
|
@@ -117,8 +117,12 @@ class NodeApplication:
|
|
|
117
117
|
|
|
118
118
|
self._started = True
|
|
119
119
|
self._stopped.clear()
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
async with asyncio.TaskGroup() as group:
|
|
121
|
+
for agent_configuration in self.configuration.agents:
|
|
122
|
+
group.create_task(
|
|
123
|
+
self._start_agent(agent_configuration),
|
|
124
|
+
name=f"bcn-agent-start-{agent_configuration.id}",
|
|
125
|
+
)
|
|
122
126
|
try:
|
|
123
127
|
await self.reminder_scheduler.start(
|
|
124
128
|
timeout=self.timeout_budget.startup_seconds,
|
|
@@ -141,26 +145,27 @@ class NodeApplication:
|
|
|
141
145
|
async def _start_agent(self, configuration: AgentConfiguration) -> None:
|
|
142
146
|
application: AgentApplication | None = None
|
|
143
147
|
try:
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
148
|
+
async with asyncio.timeout(self.timeout_budget.startup_seconds):
|
|
149
|
+
factories = await asyncio.to_thread(
|
|
150
|
+
self._registry.load_agent,
|
|
151
|
+
channel=configuration.channel.kind,
|
|
152
|
+
runtime=configuration.runtime.kind,
|
|
153
|
+
storage=self.configuration.storage,
|
|
154
|
+
)
|
|
155
|
+
storage_scope = self.storage.scope(configuration.id, configuration.name)
|
|
156
|
+
application = AgentApplication(
|
|
157
|
+
configuration=configuration,
|
|
158
|
+
factories=factories,
|
|
159
|
+
storage=storage_scope,
|
|
160
|
+
audit=self.audit,
|
|
161
|
+
timer_wheel=self.timer_wheel,
|
|
162
|
+
reminder_concurrency=self._reminder_concurrency,
|
|
163
|
+
reminder_poke=self.reminder_scheduler.poke,
|
|
164
|
+
endpoint=lambda: self.endpoint,
|
|
165
|
+
timeout_budget=self.timeout_budget,
|
|
166
|
+
translator=self.translator,
|
|
167
|
+
)
|
|
168
|
+
await application.start()
|
|
164
169
|
except asyncio.CancelledError:
|
|
165
170
|
if application is not None:
|
|
166
171
|
await self._stop_agent_after_failed_start(application)
|
|
@@ -245,7 +250,61 @@ class NodeApplication:
|
|
|
245
250
|
loop.add_signal_handler(signum, self._stopped.set)
|
|
246
251
|
except NotImplementedError, RuntimeError:
|
|
247
252
|
pass
|
|
248
|
-
|
|
253
|
+
stop_task = asyncio.create_task(self._stopped.wait(), name="bcn-stop-signal")
|
|
254
|
+
sources: list[tuple[str, ITaskFailureSource]] = [
|
|
255
|
+
("timer_wheel", self.timer_wheel),
|
|
256
|
+
("reminder_scheduler", self.reminder_scheduler),
|
|
257
|
+
("command_server", self.command_server),
|
|
258
|
+
]
|
|
259
|
+
if isinstance(self.storage, ITaskFailureSource):
|
|
260
|
+
sources.append(("storage", self.storage))
|
|
261
|
+
failure_tasks = {
|
|
262
|
+
asyncio.create_task(
|
|
263
|
+
source.wait_failure(),
|
|
264
|
+
name=f"bcn-critical-{name}",
|
|
265
|
+
): name
|
|
266
|
+
for name, source in sources
|
|
267
|
+
}
|
|
268
|
+
tasks = {stop_task, *failure_tasks}
|
|
269
|
+
try:
|
|
270
|
+
done, _ = await asyncio.wait(
|
|
271
|
+
tasks,
|
|
272
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
273
|
+
)
|
|
274
|
+
failure: tuple[str, BaseException] | None = None
|
|
275
|
+
for task in done:
|
|
276
|
+
if task is stop_task:
|
|
277
|
+
continue
|
|
278
|
+
try:
|
|
279
|
+
task.result()
|
|
280
|
+
except asyncio.CancelledError:
|
|
281
|
+
caught: BaseException = RuntimeError(
|
|
282
|
+
f"{failure_tasks[task]} failure monitor stopped unexpectedly"
|
|
283
|
+
)
|
|
284
|
+
except BaseException as error: # noqa: BLE001
|
|
285
|
+
caught = error
|
|
286
|
+
else:
|
|
287
|
+
caught = RuntimeError(
|
|
288
|
+
f"{failure_tasks[task]} failure monitor returned unexpectedly"
|
|
289
|
+
)
|
|
290
|
+
if failure is None:
|
|
291
|
+
failure = failure_tasks[task], caught
|
|
292
|
+
if failure is not None:
|
|
293
|
+
component, error = failure
|
|
294
|
+
self._ready = False
|
|
295
|
+
self._accepting = False
|
|
296
|
+
self._log(
|
|
297
|
+
"bcn.critical.failed",
|
|
298
|
+
component=component,
|
|
299
|
+
error_type=type(error).__name__,
|
|
300
|
+
error=_safe_error(error),
|
|
301
|
+
)
|
|
302
|
+
raise error
|
|
303
|
+
finally:
|
|
304
|
+
for task in tasks:
|
|
305
|
+
if not task.done():
|
|
306
|
+
task.cancel()
|
|
307
|
+
await asyncio.gather(*tasks, return_exceptions=True)
|
|
249
308
|
|
|
250
309
|
async def _publish_inbox_wake(
|
|
251
310
|
self,
|
|
@@ -356,7 +415,8 @@ class NodeApplication:
|
|
|
356
415
|
|
|
357
416
|
async def _stop_agent_after_failed_start(self, agent: AgentApplication) -> None:
|
|
358
417
|
try:
|
|
359
|
-
|
|
418
|
+
async with asyncio.timeout(self.timeout_budget.shutdown_seconds):
|
|
419
|
+
await agent.stop()
|
|
360
420
|
except BaseException as error:
|
|
361
421
|
self._logger.debug(
|
|
362
422
|
"agent cleanup after failed start failed",
|
|
@@ -6,7 +6,6 @@ import getpass
|
|
|
6
6
|
import locale
|
|
7
7
|
import os
|
|
8
8
|
import platform
|
|
9
|
-
import plistlib
|
|
10
9
|
import shlex
|
|
11
10
|
import shutil
|
|
12
11
|
import subprocess
|
|
@@ -15,10 +14,10 @@ import tempfile
|
|
|
15
14
|
import time
|
|
16
15
|
from dataclasses import dataclass
|
|
17
16
|
from pathlib import Path
|
|
18
|
-
from xml.etree import ElementTree
|
|
19
17
|
|
|
20
18
|
from ..core.paths import resolve_data_dir
|
|
21
19
|
from ..i18n import Translator, create_translator
|
|
20
|
+
from ..rendering import TextTemplate
|
|
22
21
|
from .config import ConfigurationError, load_control_configuration, resolve_config_path
|
|
23
22
|
from .transport import LocalCommandClient, local_endpoint_for_path
|
|
24
23
|
|
|
@@ -26,10 +25,16 @@ SYSTEMD_UNIT_NAME = "bcn.service"
|
|
|
26
25
|
LAUNCHD_LABEL = "io.github.yuchanns.bazaar-compute-node"
|
|
27
26
|
WINDOWS_TASK_NAME = r"\BazaarComputeNode"
|
|
28
27
|
MANAGED_MARKER = "Managed by bazaar-compute-node."
|
|
29
|
-
TASK_NAMESPACE = "http://schemas.microsoft.com/windows/2004/02/mit/task"
|
|
30
28
|
WINDOWS_STOP_ATTEMPTS = 100
|
|
31
29
|
WINDOWS_STOP_INTERVAL = 0.05
|
|
32
30
|
|
|
31
|
+
_SYSTEMD_UNIT_TEMPLATE = TextTemplate.from_resource("system_service/systemd.service")
|
|
32
|
+
_LAUNCHD_PLIST_TEMPLATE = TextTemplate.from_resource("system_service/launchd.plist")
|
|
33
|
+
_LAUNCHD_WRAPPER_TEMPLATE = TextTemplate.from_resource("system_service/launchd.sh")
|
|
34
|
+
_WINDOWS_TASK_TEMPLATE = TextTemplate.from_resource("system_service/windows.xml")
|
|
35
|
+
_WINDOWS_LAUNCHER_TEMPLATE = TextTemplate.from_resource("system_service/windows.vbs")
|
|
36
|
+
_WINDOWS_WRAPPER_TEMPLATE = TextTemplate.from_resource("system_service/windows.ps1")
|
|
37
|
+
|
|
33
38
|
|
|
34
39
|
@dataclass(frozen=True, slots=True)
|
|
35
40
|
class SystemServiceContext:
|
|
@@ -166,109 +171,53 @@ def _powershell_literal(path: Path | str | None) -> str:
|
|
|
166
171
|
|
|
167
172
|
|
|
168
173
|
def _render_systemd_unit(context: SystemServiceContext) -> str:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
]
|
|
180
|
-
if context.env_file is not None:
|
|
181
|
-
lines.append(f"EnvironmentFile=-{_systemd_quote(context.env_file)}")
|
|
182
|
-
lines.extend(
|
|
183
|
-
(
|
|
184
|
-
"Restart=on-failure",
|
|
185
|
-
"RestartSec=5",
|
|
186
|
-
"KillSignal=SIGTERM",
|
|
187
|
-
"TimeoutStopSec=15",
|
|
188
|
-
"UMask=0077",
|
|
189
|
-
"StandardOutput=journal",
|
|
190
|
-
"StandardError=journal",
|
|
191
|
-
"",
|
|
192
|
-
"[Install]",
|
|
193
|
-
"WantedBy=default.target",
|
|
194
|
-
"",
|
|
195
|
-
)
|
|
174
|
+
return _SYSTEMD_UNIT_TEMPLATE.render(
|
|
175
|
+
{
|
|
176
|
+
"managed_marker": MANAGED_MARKER,
|
|
177
|
+
"executable": _systemd_quote(_require_executable(context)),
|
|
178
|
+
"config_path": _systemd_quote(context.config_path),
|
|
179
|
+
"data_dir": _systemd_quote(context.data_dir),
|
|
180
|
+
"environment_file": (
|
|
181
|
+
"" if context.env_file is None else _systemd_quote(context.env_file)
|
|
182
|
+
),
|
|
183
|
+
}
|
|
196
184
|
)
|
|
197
|
-
return "\n".join(lines)
|
|
198
185
|
|
|
199
186
|
|
|
200
187
|
def _render_launchd_wrapper() -> str:
|
|
201
|
-
return
|
|
202
|
-
# {MANAGED_MARKER}
|
|
203
|
-
set -eu
|
|
204
|
-
|
|
205
|
-
if [ -n "${{BCN_ENV_FILE:-}}" ] && [ -f "$BCN_ENV_FILE" ]; then
|
|
206
|
-
set -a
|
|
207
|
-
. "$BCN_ENV_FILE"
|
|
208
|
-
set +a
|
|
209
|
-
fi
|
|
210
|
-
|
|
211
|
-
exec "$BCN_EXECUTABLE" run --config "$BCN_CONFIG"
|
|
212
|
-
"""
|
|
188
|
+
return _LAUNCHD_WRAPPER_TEMPLATE.render({"managed_marker": MANAGED_MARKER})
|
|
213
189
|
|
|
214
190
|
|
|
215
191
|
def _render_launchd_plist(
|
|
216
192
|
context: SystemServiceContext,
|
|
217
193
|
wrapper_path: Path,
|
|
218
194
|
) -> bytes:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
"
|
|
226
|
-
"
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
"StandardOutPath": str(context.log_path),
|
|
234
|
-
"StandardErrorPath": str(context.log_path),
|
|
235
|
-
}
|
|
236
|
-
return plistlib.dumps(payload, fmt=plistlib.FMT_XML, sort_keys=False)
|
|
195
|
+
return _LAUNCHD_PLIST_TEMPLATE.render(
|
|
196
|
+
{
|
|
197
|
+
"label": LAUNCHD_LABEL,
|
|
198
|
+
"managed_marker": MANAGED_MARKER,
|
|
199
|
+
"wrapper_path": str(wrapper_path),
|
|
200
|
+
"data_dir": str(context.data_dir),
|
|
201
|
+
"config_path": str(context.config_path),
|
|
202
|
+
"environment_file": (
|
|
203
|
+
"" if context.env_file is None else str(context.env_file)
|
|
204
|
+
),
|
|
205
|
+
"executable": str(_require_executable(context)),
|
|
206
|
+
"log_path": str(context.log_path),
|
|
207
|
+
}
|
|
208
|
+
).encode("utf-8")
|
|
237
209
|
|
|
238
210
|
|
|
239
211
|
def _render_windows_wrapper(context: SystemServiceContext) -> str:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
$environmentScript = {environment_script}
|
|
250
|
-
$logPath = {log_path}
|
|
251
|
-
|
|
252
|
-
if ($environmentScript -and (Test-Path -LiteralPath $environmentScript)) {{
|
|
253
|
-
try {{
|
|
254
|
-
. $environmentScript
|
|
255
|
-
}} catch {{
|
|
256
|
-
$_ | Out-String | Add-Content -LiteralPath $logPath -Encoding utf8
|
|
257
|
-
exit 1
|
|
258
|
-
}}
|
|
259
|
-
}}
|
|
260
|
-
|
|
261
|
-
# Native stderr is routed to the service log and must not terminate the wrapper.
|
|
262
|
-
$ErrorActionPreference = 'Continue'
|
|
263
|
-
try {{
|
|
264
|
-
& $executable run --config $configPath *>> $logPath
|
|
265
|
-
$exitCode = $LASTEXITCODE
|
|
266
|
-
}} catch {{
|
|
267
|
-
$_ | Out-String | Add-Content -LiteralPath $logPath -Encoding utf8
|
|
268
|
-
exit 1
|
|
269
|
-
}}
|
|
270
|
-
exit $exitCode
|
|
271
|
-
"""
|
|
212
|
+
return _WINDOWS_WRAPPER_TEMPLATE.render(
|
|
213
|
+
{
|
|
214
|
+
"managed_marker": MANAGED_MARKER,
|
|
215
|
+
"executable": _powershell_literal(_require_executable(context)),
|
|
216
|
+
"config_path": _powershell_literal(context.config_path),
|
|
217
|
+
"environment_script": _powershell_literal(context.env_file),
|
|
218
|
+
"log_path": _powershell_literal(context.log_path),
|
|
219
|
+
}
|
|
220
|
+
)
|
|
272
221
|
|
|
273
222
|
|
|
274
223
|
def _vbs_literal(value: Path | str) -> str:
|
|
@@ -280,80 +229,27 @@ def _render_windows_launcher(wrapper_path: Path) -> str:
|
|
|
280
229
|
"powershell.exe -NoProfile -NonInteractive -WindowStyle Hidden "
|
|
281
230
|
f'-ExecutionPolicy Bypass -File "{wrapper_path}"'
|
|
282
231
|
)
|
|
283
|
-
return
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
Set shell = CreateObject("WScript.Shell")
|
|
291
|
-
command = {command}
|
|
292
|
-
exitCode = shell.Run(command, 0, True)
|
|
293
|
-
WScript.Quit exitCode
|
|
294
|
-
"""
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
def _add_task_element(
|
|
298
|
-
parent: ElementTree.Element,
|
|
299
|
-
name: str,
|
|
300
|
-
text: str | None = None,
|
|
301
|
-
) -> ElementTree.Element:
|
|
302
|
-
element = ElementTree.SubElement(parent, f"{{{TASK_NAMESPACE}}}{name}")
|
|
303
|
-
if text is not None:
|
|
304
|
-
element.text = text
|
|
305
|
-
return element
|
|
232
|
+
return _WINDOWS_LAUNCHER_TEMPLATE.render(
|
|
233
|
+
{
|
|
234
|
+
"managed_marker": MANAGED_MARKER,
|
|
235
|
+
"command": command,
|
|
236
|
+
}
|
|
237
|
+
)
|
|
306
238
|
|
|
307
239
|
|
|
308
240
|
def _render_windows_task(
|
|
309
241
|
context: SystemServiceContext,
|
|
310
242
|
launcher_path: Path,
|
|
311
243
|
) -> bytes:
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
logon_trigger = _add_task_element(triggers, "LogonTrigger")
|
|
322
|
-
_add_task_element(logon_trigger, "Enabled", "true")
|
|
323
|
-
_add_task_element(logon_trigger, "UserId", context.user)
|
|
324
|
-
principals = _add_task_element(task, "Principals")
|
|
325
|
-
principal = ElementTree.SubElement(
|
|
326
|
-
principals,
|
|
327
|
-
f"{{{TASK_NAMESPACE}}}Principal",
|
|
328
|
-
{"id": "Author"},
|
|
329
|
-
)
|
|
330
|
-
_add_task_element(principal, "UserId", context.user)
|
|
331
|
-
_add_task_element(principal, "LogonType", "InteractiveToken")
|
|
332
|
-
_add_task_element(principal, "RunLevel", "LeastPrivilege")
|
|
333
|
-
settings = _add_task_element(task, "Settings")
|
|
334
|
-
_add_task_element(settings, "MultipleInstancesPolicy", "IgnoreNew")
|
|
335
|
-
_add_task_element(settings, "DisallowStartIfOnBatteries", "false")
|
|
336
|
-
_add_task_element(settings, "StopIfGoingOnBatteries", "false")
|
|
337
|
-
_add_task_element(settings, "AllowHardTerminate", "true")
|
|
338
|
-
_add_task_element(settings, "StartWhenAvailable", "true")
|
|
339
|
-
_add_task_element(settings, "ExecutionTimeLimit", "PT0S")
|
|
340
|
-
restart = _add_task_element(settings, "RestartOnFailure")
|
|
341
|
-
_add_task_element(restart, "Interval", "PT5M")
|
|
342
|
-
_add_task_element(restart, "Count", "3")
|
|
343
|
-
actions = ElementTree.SubElement(
|
|
344
|
-
task,
|
|
345
|
-
f"{{{TASK_NAMESPACE}}}Actions",
|
|
346
|
-
{"Context": "Author"},
|
|
347
|
-
)
|
|
348
|
-
action = _add_task_element(actions, "Exec")
|
|
349
|
-
_add_task_element(action, "Command", "wscript.exe")
|
|
350
|
-
_add_task_element(
|
|
351
|
-
action,
|
|
352
|
-
"Arguments",
|
|
353
|
-
f'//B //Nologo "{launcher_path}"',
|
|
354
|
-
)
|
|
355
|
-
_add_task_element(action, "WorkingDirectory", str(context.data_dir))
|
|
356
|
-
return ElementTree.tostring(task, encoding="utf-16", xml_declaration=True)
|
|
244
|
+
rendered = _WINDOWS_TASK_TEMPLATE.render(
|
|
245
|
+
{
|
|
246
|
+
"user": context.user,
|
|
247
|
+
"managed_marker": MANAGED_MARKER,
|
|
248
|
+
"arguments": f'//B //Nologo "{launcher_path}"',
|
|
249
|
+
"data_dir": str(context.data_dir),
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
return rendered.encode("utf-16")
|
|
357
253
|
|
|
358
254
|
|
|
359
255
|
def _write_managed_file(path: Path, content: str | bytes, *, mode: int) -> None:
|
{bazaar_compute_node-0.1.28 → bazaar_compute_node-0.1.30}/src/bazaar_compute_node/app/transport.py
RENAMED
|
@@ -12,6 +12,8 @@ from pathlib import Path
|
|
|
12
12
|
from typing import Any
|
|
13
13
|
from urllib.parse import parse_qs, urlsplit
|
|
14
14
|
|
|
15
|
+
from ..core.utils import UnlimitedLineReader
|
|
16
|
+
|
|
15
17
|
RequestHandler = Callable[[Mapping[str, object]], Awaitable[Mapping[str, object]]]
|
|
16
18
|
StreamPair = tuple[asyncio.StreamReader, asyncio.StreamWriter]
|
|
17
19
|
|
|
@@ -134,13 +136,20 @@ class LocalCommandServer:
|
|
|
134
136
|
if (path_stat.st_dev, path_stat.st_ino) == identity:
|
|
135
137
|
await asyncio.to_thread(path.unlink)
|
|
136
138
|
|
|
139
|
+
async def wait_failure(self) -> None:
|
|
140
|
+
windows_server = self._windows_server
|
|
141
|
+
if windows_server is not None:
|
|
142
|
+
await windows_server.wait_failure()
|
|
143
|
+
return
|
|
144
|
+
await asyncio.Future()
|
|
145
|
+
|
|
137
146
|
async def _handle_client(
|
|
138
147
|
self,
|
|
139
148
|
reader: asyncio.StreamReader,
|
|
140
149
|
writer: asyncio.StreamWriter,
|
|
141
150
|
) -> None:
|
|
142
151
|
try:
|
|
143
|
-
line = await reader.readline()
|
|
152
|
+
line = await UnlimitedLineReader(reader).readline()
|
|
144
153
|
if not line:
|
|
145
154
|
return
|
|
146
155
|
payload = json.loads(line)
|
|
@@ -260,7 +269,7 @@ class LocalCommandClient:
|
|
|
260
269
|
+ b"\n"
|
|
261
270
|
)
|
|
262
271
|
await writer.drain()
|
|
263
|
-
line = await reader.readline()
|
|
272
|
+
line = await UnlimitedLineReader(reader).readline()
|
|
264
273
|
if not line:
|
|
265
274
|
raise ConnectionError("local command server closed without a response")
|
|
266
275
|
response = json.loads(line)
|
|
@@ -12,6 +12,7 @@ from pathlib import Path
|
|
|
12
12
|
from typing import Any
|
|
13
13
|
from urllib.parse import urlsplit
|
|
14
14
|
|
|
15
|
+
from bazaar_compute_node.core.lifecycle import TaskFailureSignal
|
|
15
16
|
from bazaar_compute_node.core.paths import resolve_data_dir
|
|
16
17
|
|
|
17
18
|
RequestHandler = Callable[[Mapping[str, object]], Awaitable[Mapping[str, object]]]
|
|
@@ -301,6 +302,7 @@ class WindowsNamedPipeServer:
|
|
|
301
302
|
self._stop = threading.Event()
|
|
302
303
|
self._ready = threading.Event()
|
|
303
304
|
self._startup_errors: list[BaseException] = []
|
|
305
|
+
self._failure = TaskFailureSignal()
|
|
304
306
|
self._thread: threading.Thread | None = None
|
|
305
307
|
self._workers: set[threading.Thread] = set()
|
|
306
308
|
self._workers_lock = threading.Lock()
|
|
@@ -317,6 +319,7 @@ class WindowsNamedPipeServer:
|
|
|
317
319
|
self._stop.clear()
|
|
318
320
|
self._ready.clear()
|
|
319
321
|
self._startup_errors.clear()
|
|
322
|
+
self._failure.reset()
|
|
320
323
|
self._thread = threading.Thread(
|
|
321
324
|
target=self._serve,
|
|
322
325
|
name="bcn-windows-named-pipe",
|
|
@@ -332,6 +335,7 @@ class WindowsNamedPipeServer:
|
|
|
332
335
|
raise TimeoutError("Windows named pipe server did not become ready")
|
|
333
336
|
|
|
334
337
|
async def stop(self) -> None:
|
|
338
|
+
self._failure.disable()
|
|
335
339
|
thread = self._thread
|
|
336
340
|
if thread is None:
|
|
337
341
|
_release_mutex(self._mutex)
|
|
@@ -352,8 +356,16 @@ class WindowsNamedPipeServer:
|
|
|
352
356
|
try:
|
|
353
357
|
self._serve_loop()
|
|
354
358
|
except Exception as error: # noqa: BLE001
|
|
355
|
-
self.
|
|
356
|
-
|
|
359
|
+
if not self._ready.is_set():
|
|
360
|
+
self._startup_errors.append(error)
|
|
361
|
+
self._ready.set()
|
|
362
|
+
return
|
|
363
|
+
loop = self._loop
|
|
364
|
+
if loop is not None:
|
|
365
|
+
loop.call_soon_threadsafe(self._failure.fail, error)
|
|
366
|
+
|
|
367
|
+
async def wait_failure(self) -> None:
|
|
368
|
+
await self._failure.wait()
|
|
357
369
|
|
|
358
370
|
def _serve_loop(self) -> None:
|
|
359
371
|
initialized = False
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Claude Code streaming process, protocol, and runtime adapter."""
|
|
2
|
+
|
|
3
|
+
from .client import Client
|
|
4
|
+
from .events import TurnEventStream
|
|
5
|
+
from .process import ProcessSpec, ProcessState, ProcessSupervisor, build_arguments
|
|
6
|
+
from .protocol import (
|
|
7
|
+
ClaudeControlError,
|
|
8
|
+
ClaudeProcessExited,
|
|
9
|
+
ClaudeProcessNotRunning,
|
|
10
|
+
ClaudeProtocolError,
|
|
11
|
+
ClaudeTransportError,
|
|
12
|
+
)
|
|
13
|
+
from .runtime import Runtime
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ClaudeControlError",
|
|
17
|
+
"ClaudeProcessExited",
|
|
18
|
+
"ClaudeProcessNotRunning",
|
|
19
|
+
"ClaudeProtocolError",
|
|
20
|
+
"ClaudeTransportError",
|
|
21
|
+
"Client",
|
|
22
|
+
"ProcessSpec",
|
|
23
|
+
"ProcessState",
|
|
24
|
+
"ProcessSupervisor",
|
|
25
|
+
"Runtime",
|
|
26
|
+
"TurnEventStream",
|
|
27
|
+
"build_arguments",
|
|
28
|
+
]
|