bazaar-compute-node 0.1.8__tar.gz → 0.1.9__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.9/PKG-INFO +106 -0
- bazaar_compute_node-0.1.9/README.md +93 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/pyproject.toml +3 -2
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/pyproject.toml.orig +3 -2
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/application.py +1 -1
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/command.py +4 -2
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/config.py +14 -10
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/registry.py +24 -7
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/cli.py +2 -5
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/approval.py +50 -3
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/__init__.py +1 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/api.py +356 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/approval.py +411 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/attachments.py +442 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/channel.py +846 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/identity.py +68 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/markdown.py +343 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/outbound.py +796 -0
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/telegram/plugin.py +20 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/wecom/channel.py +10 -5
- bazaar_compute_node-0.1.9/src/bazaar_compute_node/contrib/wecom/plugin.py +33 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/channel.py +50 -5
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/models/entities.py +3 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/turn.py +23 -4
- bazaar_compute_node-0.1.8/PKG-INFO +0 -184
- bazaar_compute_node-0.1.8/README.md +0 -171
- bazaar_compute_node-0.1.8/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -29
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/LICENSE +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/attachments.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/reminder_dispatch.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/transport.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/windows_pipe.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/wrapper.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/bcc.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/events.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/process.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/codex/runtime.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/logging/audit.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/codec.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/database.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/migrations.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/reminder_database.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/reminder_migration.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/reminder_repository.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/sqlite/repository.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/wecom/markdown.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/approval.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/audit.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/client.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/command.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/concurrency.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/correlation.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/instruction.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/lifecycle.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/models/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/models/reminder.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/models/states.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/observability.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/__init__.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/command.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/reminder.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/reminder_command.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/services.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/orchestration/session.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/outcomes.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/paths.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/reminder.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/runtime.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/storage.py +0 -0
- {bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/core/timerwheel.py +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bazaar-compute-node
|
|
3
|
+
Version: 0.1.9
|
|
4
|
+
Summary: Runtime-agnostic computer node daemon for agents and channels.
|
|
5
|
+
License-Expression: AGPL-3.0-only
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Dist: aiohttp>=3.12.0
|
|
8
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
9
|
+
Requires-Dist: cryptography>=45.0.0
|
|
10
|
+
Requires-Python: >=3.14
|
|
11
|
+
Project-URL: Repository, https://github.com/yuchanns/bazaar-compute-node
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# Bazaar Compute Node
|
|
15
|
+
|
|
16
|
+
Collaborate with your Agents in the bazaar across compute nodes, through any interface, with any harness runtime.
|
|
17
|
+
在集市里与你的 Agent 们合作,透过任意界面与任意 Harness。
|
|
18
|
+
|
|
19
|
+
<p align="left">
|
|
20
|
+
<a href="https://github.com/yuchanns/bazaar-compute-node/actions"><img
|
|
21
|
+
src="https://github.com/yuchanns/bazaar-compute-node/actions/workflows/release.yml/badge.svg"
|
|
22
|
+
alt="Release"
|
|
23
|
+
/></a>
|
|
24
|
+
<a href="https://pypi.org/project/bazaar-compute-node"><img
|
|
25
|
+
src="https://img.shields.io/pypi/v/bazaar-compute-node.svg"
|
|
26
|
+
alt="Python Package Index"
|
|
27
|
+
/></a>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
**Documentation is coming soon...**
|
|
31
|
+
|
|
32
|
+
## Quick Start / 快速开始
|
|
33
|
+
|
|
34
|
+
Python 3.14+ is required:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
# Install
|
|
38
|
+
uv tool install bazaar-compute-node
|
|
39
|
+
bcn --version
|
|
40
|
+
|
|
41
|
+
# Upgrade
|
|
42
|
+
uv tool upgrade bazaar-compute-node
|
|
43
|
+
|
|
44
|
+
# Start daemon
|
|
45
|
+
export BCN_WECOM_BOT_SECRET='your-bot-secret'
|
|
46
|
+
|
|
47
|
+
bcn start --channel wecom --runtime codex \
|
|
48
|
+
--model gpt-5.6-luna --effort max \
|
|
49
|
+
--sandbox-mode workspace-write \
|
|
50
|
+
--network-access true \
|
|
51
|
+
--idle-timeout 600
|
|
52
|
+
|
|
53
|
+
# Stop daemon
|
|
54
|
+
bcn stop
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Features / 功能
|
|
58
|
+
|
|
59
|
+
- ✅ Done / 已完成
|
|
60
|
+
- 🚧 Working in progress / 开发中
|
|
61
|
+
|
|
62
|
+
### Facilities / 通用能力
|
|
63
|
+
|
|
64
|
+
| Status / 状态 | Ability / 能力 |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| ✅ | Reminders / 定时器 |
|
|
67
|
+
| ✅ | Attachments / 附件 |
|
|
68
|
+
| 🚧 | Multi-Agents / 多 Agent |
|
|
69
|
+
| 🚧 | Teams / 团队协作 |
|
|
70
|
+
|
|
71
|
+
### Channels / 渠道
|
|
72
|
+
|
|
73
|
+
| Status / 状态 | Channel / 渠道 |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| ✅ | WeCom / 企业微信 |
|
|
76
|
+
| ✅ | Telegram |
|
|
77
|
+
| 🚧 | GitHub |
|
|
78
|
+
| 🚧 | GitLab |
|
|
79
|
+
|
|
80
|
+
### Harnesses
|
|
81
|
+
|
|
82
|
+
| Status / 状态 | Runtime / 运行时 |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| ✅ | Codex |
|
|
85
|
+
| 🚧 | Claude Code |
|
|
86
|
+
| 🚧 | Pi |
|
|
87
|
+
| 🚧 | Hermes Agent |
|
|
88
|
+
| 🚧 | DeepSeek Harness |
|
|
89
|
+
|
|
90
|
+
### Platforms / 平台
|
|
91
|
+
|
|
92
|
+
| Status / 状态 | Platform / 平台 |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| ✅ | Windows |
|
|
95
|
+
| ✅ | macOS |
|
|
96
|
+
| ✅ | Linux |
|
|
97
|
+
|
|
98
|
+
## License / 许可证
|
|
99
|
+
|
|
100
|
+
This project is licensed under the [AGPLv3](./LICENSE).
|
|
101
|
+
本项目采用 [AGPLv3](./LICENSE) 许可证。
|
|
102
|
+
|
|
103
|
+
## Credits / 致谢
|
|
104
|
+
|
|
105
|
+
This project is inspired by [raft.build](https://raft.build).
|
|
106
|
+
本项目的灵感来自 [raft.build](https://raft.build)。
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Bazaar Compute Node
|
|
2
|
+
|
|
3
|
+
Collaborate with your Agents in the bazaar across compute nodes, through any interface, with any harness runtime.
|
|
4
|
+
在集市里与你的 Agent 们合作,透过任意界面与任意 Harness。
|
|
5
|
+
|
|
6
|
+
<p align="left">
|
|
7
|
+
<a href="https://github.com/yuchanns/bazaar-compute-node/actions"><img
|
|
8
|
+
src="https://github.com/yuchanns/bazaar-compute-node/actions/workflows/release.yml/badge.svg"
|
|
9
|
+
alt="Release"
|
|
10
|
+
/></a>
|
|
11
|
+
<a href="https://pypi.org/project/bazaar-compute-node"><img
|
|
12
|
+
src="https://img.shields.io/pypi/v/bazaar-compute-node.svg"
|
|
13
|
+
alt="Python Package Index"
|
|
14
|
+
/></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
**Documentation is coming soon...**
|
|
18
|
+
|
|
19
|
+
## Quick Start / 快速开始
|
|
20
|
+
|
|
21
|
+
Python 3.14+ is required:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
# Install
|
|
25
|
+
uv tool install bazaar-compute-node
|
|
26
|
+
bcn --version
|
|
27
|
+
|
|
28
|
+
# Upgrade
|
|
29
|
+
uv tool upgrade bazaar-compute-node
|
|
30
|
+
|
|
31
|
+
# Start daemon
|
|
32
|
+
export BCN_WECOM_BOT_SECRET='your-bot-secret'
|
|
33
|
+
|
|
34
|
+
bcn start --channel wecom --runtime codex \
|
|
35
|
+
--model gpt-5.6-luna --effort max \
|
|
36
|
+
--sandbox-mode workspace-write \
|
|
37
|
+
--network-access true \
|
|
38
|
+
--idle-timeout 600
|
|
39
|
+
|
|
40
|
+
# Stop daemon
|
|
41
|
+
bcn stop
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Features / 功能
|
|
45
|
+
|
|
46
|
+
- ✅ Done / 已完成
|
|
47
|
+
- 🚧 Working in progress / 开发中
|
|
48
|
+
|
|
49
|
+
### Facilities / 通用能力
|
|
50
|
+
|
|
51
|
+
| Status / 状态 | Ability / 能力 |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| ✅ | Reminders / 定时器 |
|
|
54
|
+
| ✅ | Attachments / 附件 |
|
|
55
|
+
| 🚧 | Multi-Agents / 多 Agent |
|
|
56
|
+
| 🚧 | Teams / 团队协作 |
|
|
57
|
+
|
|
58
|
+
### Channels / 渠道
|
|
59
|
+
|
|
60
|
+
| Status / 状态 | Channel / 渠道 |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| ✅ | WeCom / 企业微信 |
|
|
63
|
+
| ✅ | Telegram |
|
|
64
|
+
| 🚧 | GitHub |
|
|
65
|
+
| 🚧 | GitLab |
|
|
66
|
+
|
|
67
|
+
### Harnesses
|
|
68
|
+
|
|
69
|
+
| Status / 状态 | Runtime / 运行时 |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| ✅ | Codex |
|
|
72
|
+
| 🚧 | Claude Code |
|
|
73
|
+
| 🚧 | Pi |
|
|
74
|
+
| 🚧 | Hermes Agent |
|
|
75
|
+
| 🚧 | DeepSeek Harness |
|
|
76
|
+
|
|
77
|
+
### Platforms / 平台
|
|
78
|
+
|
|
79
|
+
| Status / 状态 | Platform / 平台 |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| ✅ | Windows |
|
|
82
|
+
| ✅ | macOS |
|
|
83
|
+
| ✅ | Linux |
|
|
84
|
+
|
|
85
|
+
## License / 许可证
|
|
86
|
+
|
|
87
|
+
This project is licensed under the [AGPLv3](./LICENSE).
|
|
88
|
+
本项目采用 [AGPLv3](./LICENSE) 许可证。
|
|
89
|
+
|
|
90
|
+
## Credits / 致谢
|
|
91
|
+
|
|
92
|
+
This project is inspired by [raft.build](https://raft.build).
|
|
93
|
+
本项目的灵感来自 [raft.build](https://raft.build)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bazaar-compute-node"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.9"
|
|
4
4
|
description = "Runtime-agnostic computer node daemon for agents and channels."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-only"
|
|
@@ -22,7 +22,8 @@ bcn = "bazaar_compute_node.cli:main"
|
|
|
22
22
|
codex = "bazaar_compute_node.contrib.codex.plugin:create_runtime"
|
|
23
23
|
|
|
24
24
|
[project.entry-points."bazaar_compute_node.channels"]
|
|
25
|
-
wecom = "bazaar_compute_node.contrib.wecom.plugin:
|
|
25
|
+
wecom = "bazaar_compute_node.contrib.wecom.plugin:builder"
|
|
26
|
+
telegram = "bazaar_compute_node.contrib.telegram.plugin:builder"
|
|
26
27
|
|
|
27
28
|
[project.entry-points."bazaar_compute_node.storages"]
|
|
28
29
|
sqlite = "bazaar_compute_node.contrib.sqlite.plugin:create_storage"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bazaar-compute-node"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.9"
|
|
4
4
|
description = "Runtime-agnostic computer node daemon for agents and channels."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "AGPL-3.0-only"
|
|
@@ -22,7 +22,8 @@ bcn = "bazaar_compute_node.cli:main"
|
|
|
22
22
|
codex = "bazaar_compute_node.contrib.codex.plugin:create_runtime"
|
|
23
23
|
|
|
24
24
|
[project.entry-points."bazaar_compute_node.channels"]
|
|
25
|
-
wecom = "bazaar_compute_node.contrib.wecom.plugin:
|
|
25
|
+
wecom = "bazaar_compute_node.contrib.wecom.plugin:builder"
|
|
26
|
+
telegram = "bazaar_compute_node.contrib.telegram.plugin:builder"
|
|
26
27
|
|
|
27
28
|
[project.entry-points."bazaar_compute_node.storages"]
|
|
28
29
|
sqlite = "bazaar_compute_node.contrib.sqlite.plugin:create_storage"
|
{bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/application.py
RENAMED
|
@@ -92,7 +92,7 @@ class NodeApplication:
|
|
|
92
92
|
self._attachment_materializer = AttachmentMaterializer(
|
|
93
93
|
self._workspace_path, self._referenced_attachment_paths
|
|
94
94
|
)
|
|
95
|
-
self.channel: IChannel = factories.channel(
|
|
95
|
+
self.channel: IChannel = factories.channel.build(
|
|
96
96
|
ChannelContext(
|
|
97
97
|
attachments=self._attachment_materializer,
|
|
98
98
|
options=dict(channel_options or {}),
|
{bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/command.py
RENAMED
|
@@ -376,6 +376,8 @@ class CommandDispatcher:
|
|
|
376
376
|
|
|
377
377
|
|
|
378
378
|
def format_message_time(timestamp_ms: int) -> str:
|
|
379
|
-
return
|
|
380
|
-
|
|
379
|
+
return (
|
|
380
|
+
datetime.fromtimestamp(timestamp_ms / 1000, tz=UTC)
|
|
381
|
+
.astimezone()
|
|
382
|
+
.strftime("%Y-%m-%d %H:%M:%S")
|
|
381
383
|
)
|
{bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/config.py
RENAMED
|
@@ -3,8 +3,10 @@ from __future__ import annotations
|
|
|
3
3
|
import math
|
|
4
4
|
import os
|
|
5
5
|
import tomllib
|
|
6
|
-
from
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from dataclasses import dataclass, field
|
|
7
8
|
from pathlib import Path
|
|
9
|
+
from types import MappingProxyType
|
|
8
10
|
|
|
9
11
|
from ..core.paths import resolve_data_dir
|
|
10
12
|
from ..core.runtime import RuntimeSandboxMode
|
|
@@ -28,8 +30,9 @@ class NodeConfiguration:
|
|
|
28
30
|
network_access: bool = True
|
|
29
31
|
runtime_idle_timeout_seconds: float = 0
|
|
30
32
|
runtime_env_include: tuple[str, ...] = ()
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
channel_options: Mapping[str, Mapping[str, object]] = field(
|
|
34
|
+
default_factory=lambda: MappingProxyType({})
|
|
35
|
+
)
|
|
33
36
|
|
|
34
37
|
|
|
35
38
|
class ConfigurationError(ValueError):
|
|
@@ -67,9 +70,13 @@ def load_node_configuration(path: Path | None = None) -> NodeConfiguration:
|
|
|
67
70
|
channel = payload.get("channel", {})
|
|
68
71
|
if not isinstance(channel, dict):
|
|
69
72
|
raise ConfigurationError("[channel] must be a TOML table")
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
channel_options: dict[str, Mapping[str, object]] = {}
|
|
74
|
+
for channel_name, options in channel.items():
|
|
75
|
+
if not channel_name:
|
|
76
|
+
raise ConfigurationError("channel name must be non-empty text")
|
|
77
|
+
if not isinstance(options, dict):
|
|
78
|
+
raise ConfigurationError(f"[channel.{channel_name}] must be a TOML table")
|
|
79
|
+
channel_options[channel_name] = MappingProxyType(dict(options))
|
|
73
80
|
sandbox_mode = runtime.get("sandbox_mode", RuntimeSandboxMode.WORKSPACE_WRITE.value)
|
|
74
81
|
if not isinstance(sandbox_mode, str):
|
|
75
82
|
raise ConfigurationError("runtime.sandbox_mode must be text")
|
|
@@ -105,10 +112,7 @@ def load_node_configuration(path: Path | None = None) -> NodeConfiguration:
|
|
|
105
112
|
runtime_env_include=_text_list(
|
|
106
113
|
runtime_env.get("include", []), "runtime.env.include"
|
|
107
114
|
),
|
|
108
|
-
|
|
109
|
-
wecom_websocket_url=_optional_text(
|
|
110
|
-
wecom.get("websocket_url"), "channel.wecom.websocket_url"
|
|
111
|
-
),
|
|
115
|
+
channel_options=MappingProxyType(channel_options),
|
|
112
116
|
)
|
|
113
117
|
|
|
114
118
|
|
{bazaar_compute_node-0.1.8 → bazaar_compute_node-0.1.9}/src/bazaar_compute_node/app/registry.py
RENAMED
|
@@ -6,7 +6,7 @@ from functools import partial
|
|
|
6
6
|
from importlib.metadata import EntryPoint, entry_points
|
|
7
7
|
from typing import Any, cast
|
|
8
8
|
|
|
9
|
-
from ..core.channel import
|
|
9
|
+
from ..core.channel import IChannelBuilder
|
|
10
10
|
from ..core.observability import IAudit
|
|
11
11
|
from ..core.runtime import IRuntime, RuntimeCommandContext
|
|
12
12
|
from ..core.storage import IStorage
|
|
@@ -18,7 +18,6 @@ STORAGE_ENTRY_POINT_GROUP = "bazaar_compute_node.storages"
|
|
|
18
18
|
AUDIT_ENTRY_POINT_GROUP = "bazaar_compute_node.audits"
|
|
19
19
|
CONTROL_ENTRY_POINT_GROUP = "bazaar_compute_node.controls"
|
|
20
20
|
|
|
21
|
-
ChannelFactory = Callable[[ChannelContext], IChannel]
|
|
22
21
|
RuntimeFactory = Callable[[RuntimeCommandContext], IRuntime]
|
|
23
22
|
StorageFactory = Callable[[], IStorage]
|
|
24
23
|
AuditFactory = Callable[[], IAudit]
|
|
@@ -26,7 +25,7 @@ AuditFactory = Callable[[], IAudit]
|
|
|
26
25
|
|
|
27
26
|
@dataclass(frozen=True, slots=True)
|
|
28
27
|
class AdapterFactories:
|
|
29
|
-
channel:
|
|
28
|
+
channel: IChannelBuilder
|
|
30
29
|
runtime: RuntimeFactory
|
|
31
30
|
storage: StorageFactory
|
|
32
31
|
audit: AuditFactory
|
|
@@ -60,10 +59,7 @@ class AdapterRegistry:
|
|
|
60
59
|
if storage_options:
|
|
61
60
|
storage_factory = partial(storage_factory, dict(storage_options))
|
|
62
61
|
return AdapterFactories(
|
|
63
|
-
channel=
|
|
64
|
-
ChannelFactory,
|
|
65
|
-
self._load(CHANNEL_ENTRY_POINT_GROUP, channel),
|
|
66
|
-
),
|
|
62
|
+
channel=self._load_channel_builder(channel),
|
|
67
63
|
runtime=cast(
|
|
68
64
|
RuntimeFactory,
|
|
69
65
|
self._load(RUNTIME_ENTRY_POINT_GROUP, runtime),
|
|
@@ -79,6 +75,27 @@ class AdapterRegistry:
|
|
|
79
75
|
),
|
|
80
76
|
)
|
|
81
77
|
|
|
78
|
+
def _load_channel_builder(self, name: str) -> IChannelBuilder:
|
|
79
|
+
entry_point = self._find(CHANNEL_ENTRY_POINT_GROUP, name)
|
|
80
|
+
if entry_point is None:
|
|
81
|
+
raise ProviderLoadError(
|
|
82
|
+
f"provider '{name}' is not installed for entry point group "
|
|
83
|
+
f"'{CHANNEL_ENTRY_POINT_GROUP}'"
|
|
84
|
+
)
|
|
85
|
+
try:
|
|
86
|
+
builder = entry_point.load()
|
|
87
|
+
except Exception as error:
|
|
88
|
+
raise ProviderLoadError(
|
|
89
|
+
f"failed to load provider '{name}' from "
|
|
90
|
+
f"'{CHANNEL_ENTRY_POINT_GROUP}': {error}"
|
|
91
|
+
) from error
|
|
92
|
+
if not callable(getattr(builder, "build", None)):
|
|
93
|
+
raise ProviderLoadError(
|
|
94
|
+
f"provider '{name}' from '{CHANNEL_ENTRY_POINT_GROUP}' "
|
|
95
|
+
"does not provide a callable build method"
|
|
96
|
+
)
|
|
97
|
+
return cast(IChannelBuilder, builder)
|
|
98
|
+
|
|
82
99
|
def _load(self, group: str, name: str) -> Any:
|
|
83
100
|
entry_point = self._find(group, name)
|
|
84
101
|
if entry_point is None:
|
|
@@ -174,10 +174,7 @@ def _apply_runtime_configuration(
|
|
|
174
174
|
args.audit = DEFAULT_AUDIT
|
|
175
175
|
args.runtime_env_include = configuration.runtime_env_include
|
|
176
176
|
args.runtime_idle_timeout_seconds = configuration.runtime_idle_timeout_seconds
|
|
177
|
-
args.channel_options = {
|
|
178
|
-
"bot_id": configuration.wecom_bot_id,
|
|
179
|
-
"websocket_url": configuration.wecom_websocket_url,
|
|
180
|
-
}
|
|
177
|
+
args.channel_options = dict(configuration.channel_options.get(args.channel, {}))
|
|
181
178
|
|
|
182
179
|
|
|
183
180
|
async def _run_node(args: argparse.Namespace, parser: argparse.ArgumentParser) -> int:
|
|
@@ -191,7 +188,7 @@ async def _run_node(args: argparse.Namespace, parser: argparse.ArgumentParser) -
|
|
|
191
188
|
runtime_sandbox_mode=args.sandbox_mode,
|
|
192
189
|
runtime_network_access=args.network_access,
|
|
193
190
|
runtime_idle_timeout_seconds=args.runtime_idle_timeout_seconds,
|
|
194
|
-
channel_options=args.channel_options
|
|
191
|
+
channel_options=args.channel_options,
|
|
195
192
|
runtime_environment_include=args.runtime_env_include,
|
|
196
193
|
)
|
|
197
194
|
await node.start()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
from collections.abc import Mapping
|
|
4
5
|
from dataclasses import dataclass
|
|
5
6
|
from typing import cast
|
|
@@ -21,6 +22,7 @@ from .protocol import (
|
|
|
21
22
|
_COMMAND_METHOD = "item/commandExecution/requestApproval"
|
|
22
23
|
_FILE_CHANGE_METHOD = "item/fileChange/requestApproval"
|
|
23
24
|
_PERMISSIONS_METHOD = "item/permissions/requestApproval"
|
|
25
|
+
_MAX_APPROVAL_DESCRIPTION = 4_000
|
|
24
26
|
|
|
25
27
|
_APPROVAL_METHODS = frozenset(
|
|
26
28
|
{
|
|
@@ -90,13 +92,57 @@ def parse_approval_request(
|
|
|
90
92
|
_FILE_CHANGE_METHOD: "file_change",
|
|
91
93
|
_PERMISSIONS_METHOD: "permissions",
|
|
92
94
|
}[method]
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
):
|
|
95
|
+
permissions = params.get("permissions")
|
|
96
|
+
if method == _PERMISSIONS_METHOD and not isinstance(permissions, Mapping):
|
|
96
97
|
raise AppServerProtocolError(
|
|
97
98
|
"permissions approval request has no permissions object"
|
|
98
99
|
)
|
|
99
100
|
|
|
101
|
+
description_parts: list[str] = []
|
|
102
|
+
reason = params.get("reason")
|
|
103
|
+
if isinstance(reason, str) and reason.strip():
|
|
104
|
+
description_parts.append(reason.strip())
|
|
105
|
+
if method == _COMMAND_METHOD:
|
|
106
|
+
command = params.get("command")
|
|
107
|
+
if isinstance(command, str) and command.strip():
|
|
108
|
+
description_parts.append(f"Command: {command.strip()}")
|
|
109
|
+
elif (
|
|
110
|
+
isinstance(command, list)
|
|
111
|
+
and command
|
|
112
|
+
and all(isinstance(argument, str) and argument for argument in command)
|
|
113
|
+
):
|
|
114
|
+
description_parts.append(f"Command: {' '.join(command)}")
|
|
115
|
+
cwd = params.get("cwd")
|
|
116
|
+
if isinstance(cwd, str) and cwd:
|
|
117
|
+
description_parts.append(f"Working directory: {cwd}")
|
|
118
|
+
elif method == _FILE_CHANGE_METHOD:
|
|
119
|
+
grant_root = params.get("grantRoot")
|
|
120
|
+
if isinstance(grant_root, str) and grant_root:
|
|
121
|
+
description_parts.append(f"Grant root: {grant_root}")
|
|
122
|
+
cwd = params.get("cwd")
|
|
123
|
+
if isinstance(cwd, str) and cwd:
|
|
124
|
+
description_parts.append(f"Working directory: {cwd}")
|
|
125
|
+
elif isinstance(permissions, Mapping):
|
|
126
|
+
cwd = params.get("cwd")
|
|
127
|
+
if isinstance(cwd, str) and cwd:
|
|
128
|
+
description_parts.append(f"Working directory: {cwd}")
|
|
129
|
+
try:
|
|
130
|
+
encoded_permissions = json.dumps(
|
|
131
|
+
dict(permissions),
|
|
132
|
+
ensure_ascii=False,
|
|
133
|
+
sort_keys=True,
|
|
134
|
+
separators=(",", ":"),
|
|
135
|
+
)
|
|
136
|
+
except TypeError, ValueError:
|
|
137
|
+
encoded_permissions = None
|
|
138
|
+
if encoded_permissions:
|
|
139
|
+
description_parts.append(f"Permissions: {encoded_permissions}")
|
|
140
|
+
|
|
141
|
+
description: str | None = None
|
|
142
|
+
if description_parts:
|
|
143
|
+
description = "\n".join(description_parts)
|
|
144
|
+
if len(description) > _MAX_APPROVAL_DESCRIPTION:
|
|
145
|
+
description = description[: _MAX_APPROVAL_DESCRIPTION - 1] + "…"
|
|
100
146
|
metadata: dict[str, object] = {
|
|
101
147
|
"provider_method": method,
|
|
102
148
|
"provider_item_id": provider_item_id,
|
|
@@ -119,6 +165,7 @@ def parse_approval_request(
|
|
|
119
165
|
action=action,
|
|
120
166
|
created_at_ms=started_at_ms,
|
|
121
167
|
turn_id=turn_id,
|
|
168
|
+
description=description,
|
|
122
169
|
metadata=metadata,
|
|
123
170
|
),
|
|
124
171
|
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Telegram Bot API Channel adapter."""
|