webbee 0.5.4__tar.gz → 0.5.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. {webbee-0.5.4 → webbee-0.5.5}/CHANGELOG.md +13 -0
  2. {webbee-0.5.4 → webbee-0.5.5}/PKG-INFO +24 -11
  3. {webbee-0.5.4 → webbee-0.5.5}/README.md +21 -7
  4. {webbee-0.5.4 → webbee-0.5.5}/pyproject.toml +3 -4
  5. webbee-0.5.5/src/webbee/__init__.py +1 -0
  6. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/steer.py +19 -14
  7. {webbee-0.5.4 → webbee-0.5.5}/tests/test_packaging.py +5 -1
  8. {webbee-0.5.4 → webbee-0.5.5}/tests/test_version.py +3 -1
  9. webbee-0.5.4/src/webbee/__init__.py +0 -1
  10. {webbee-0.5.4 → webbee-0.5.5}/.github/workflows/publish.yml +0 -0
  11. {webbee-0.5.4 → webbee-0.5.5}/.gitignore +0 -0
  12. {webbee-0.5.4 → webbee-0.5.5}/LICENSE +0 -0
  13. {webbee-0.5.4 → webbee-0.5.5}/install.sh +0 -0
  14. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/__main__.py +0 -0
  15. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/account.py +0 -0
  16. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/active_sessions.py +0 -0
  17. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/banner_art.py +0 -0
  18. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/boot.py +0 -0
  19. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/browser.py +0 -0
  20. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/checkpoints.py +0 -0
  21. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/cli.py +0 -0
  22. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/clipboard.py +0 -0
  23. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/clipboard_read.py +0 -0
  24. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/clipboard_session.py +0 -0
  25. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/coding_context.py +0 -0
  26. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/commands.py +0 -0
  27. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/config.py +0 -0
  28. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/consent.py +0 -0
  29. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/details.py +0 -0
  30. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/events.py +0 -0
  31. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/frames.py +0 -0
  32. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/home.py +0 -0
  33. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/home_view.py +0 -0
  34. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/http.py +0 -0
  35. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/instance_lock.py +0 -0
  36. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/__init__.py +0 -0
  37. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/graph.py +0 -0
  38. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/outline.py +0 -0
  39. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/query.py +0 -0
  40. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/service.py +0 -0
  41. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/store.py +0 -0
  42. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/vectors.py +0 -0
  43. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/intel/watch.py +0 -0
  44. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/media.py +0 -0
  45. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/modals.py +0 -0
  46. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/mode_store.py +0 -0
  47. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/native_files.py +0 -0
  48. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/native_read.py +0 -0
  49. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/newtab_mode.py +0 -0
  50. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/output_pane.py +0 -0
  51. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/pricing_constants.py +0 -0
  52. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/queue_panel.py +0 -0
  53. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/reflow.py +0 -0
  54. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/remote.py +0 -0
  55. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/render.py +0 -0
  56. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/repl.py +0 -0
  57. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/repo.py +0 -0
  58. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/selection.py +0 -0
  59. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/session.py +0 -0
  60. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/sessions.py +0 -0
  61. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/sizing.py +0 -0
  62. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/slots.py +0 -0
  63. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/stream.py +0 -0
  64. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/tab_store.py +0 -0
  65. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/tabs.py +0 -0
  66. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/thread.py +0 -0
  67. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/tier_store.py +0 -0
  68. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/todo_panel.py +0 -0
  69. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/tokens.py +0 -0
  70. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/tools.py +0 -0
  71. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/tui.py +0 -0
  72. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/update.py +0 -0
  73. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/urlopen.py +0 -0
  74. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/wallet.py +0 -0
  75. {webbee-0.5.4 → webbee-0.5.5}/src/webbee/worktrees.py +0 -0
  76. {webbee-0.5.4 → webbee-0.5.5}/tests/__init__.py +0 -0
  77. {webbee-0.5.4 → webbee-0.5.5}/tests/conftest.py +0 -0
  78. {webbee-0.5.4 → webbee-0.5.5}/tests/test_account.py +0 -0
  79. {webbee-0.5.4 → webbee-0.5.5}/tests/test_active_sessions.py +0 -0
  80. {webbee-0.5.4 → webbee-0.5.5}/tests/test_audit_2026_07_25_findings.py +0 -0
  81. {webbee-0.5.4 → webbee-0.5.5}/tests/test_checkpoints.py +0 -0
  82. {webbee-0.5.4 → webbee-0.5.5}/tests/test_cli.py +0 -0
  83. {webbee-0.5.4 → webbee-0.5.5}/tests/test_clipboard.py +0 -0
  84. {webbee-0.5.4 → webbee-0.5.5}/tests/test_clipboard_read.py +0 -0
  85. {webbee-0.5.4 → webbee-0.5.5}/tests/test_coding_context.py +0 -0
  86. {webbee-0.5.4 → webbee-0.5.5}/tests/test_commands.py +0 -0
  87. {webbee-0.5.4 → webbee-0.5.5}/tests/test_config.py +0 -0
  88. {webbee-0.5.4 → webbee-0.5.5}/tests/test_cpc_contract_stable.py +0 -0
  89. {webbee-0.5.4 → webbee-0.5.5}/tests/test_cpc_outline.py +0 -0
  90. {webbee-0.5.4 → webbee-0.5.5}/tests/test_cross_loop_token.py +0 -0
  91. {webbee-0.5.4 → webbee-0.5.5}/tests/test_details.py +0 -0
  92. {webbee-0.5.4 → webbee-0.5.5}/tests/test_events.py +0 -0
  93. {webbee-0.5.4 → webbee-0.5.5}/tests/test_freeze_fix.py +0 -0
  94. {webbee-0.5.4 → webbee-0.5.5}/tests/test_home.py +0 -0
  95. {webbee-0.5.4 → webbee-0.5.5}/tests/test_home_view.py +0 -0
  96. {webbee-0.5.4 → webbee-0.5.5}/tests/test_home_view_mouse.py +0 -0
  97. {webbee-0.5.4 → webbee-0.5.5}/tests/test_inspect_page.py +0 -0
  98. {webbee-0.5.4 → webbee-0.5.5}/tests/test_instance_lock.py +0 -0
  99. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_chunker.py +0 -0
  100. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_embed.py +0 -0
  101. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_graph.py +0 -0
  102. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_no_numpy.py +0 -0
  103. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_query.py +0 -0
  104. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_service.py +0 -0
  105. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_store.py +0 -0
  106. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_vectors.py +0 -0
  107. {webbee-0.5.4 → webbee-0.5.5}/tests/test_intel_watch.py +0 -0
  108. {webbee-0.5.4 → webbee-0.5.5}/tests/test_marathon.py +0 -0
  109. {webbee-0.5.4 → webbee-0.5.5}/tests/test_modals_e2e.py +0 -0
  110. {webbee-0.5.4 → webbee-0.5.5}/tests/test_mode_store.py +0 -0
  111. {webbee-0.5.4 → webbee-0.5.5}/tests/test_native_files.py +0 -0
  112. {webbee-0.5.4 → webbee-0.5.5}/tests/test_newtab_mode.py +0 -0
  113. {webbee-0.5.4 → webbee-0.5.5}/tests/test_queue_manage_0337.py +0 -0
  114. {webbee-0.5.4 → webbee-0.5.5}/tests/test_reflow.py +0 -0
  115. {webbee-0.5.4 → webbee-0.5.5}/tests/test_render.py +0 -0
  116. {webbee-0.5.4 → webbee-0.5.5}/tests/test_repl.py +0 -0
  117. {webbee-0.5.4 → webbee-0.5.5}/tests/test_repo.py +0 -0
  118. {webbee-0.5.4 → webbee-0.5.5}/tests/test_resilient_http.py +0 -0
  119. {webbee-0.5.4 → webbee-0.5.5}/tests/test_session.py +0 -0
  120. {webbee-0.5.4 → webbee-0.5.5}/tests/test_sessions.py +0 -0
  121. {webbee-0.5.4 → webbee-0.5.5}/tests/test_sizing.py +0 -0
  122. {webbee-0.5.4 → webbee-0.5.5}/tests/test_slots.py +0 -0
  123. {webbee-0.5.4 → webbee-0.5.5}/tests/test_steer.py +0 -0
  124. {webbee-0.5.4 → webbee-0.5.5}/tests/test_stream.py +0 -0
  125. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tab_bar_stability.py +0 -0
  126. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tab_restore_0337.py +0 -0
  127. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tabs.py +0 -0
  128. {webbee-0.5.4 → webbee-0.5.5}/tests/test_terminal_ux_0336.py +0 -0
  129. {webbee-0.5.4 → webbee-0.5.5}/tests/test_thread.py +0 -0
  130. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tier_invalidation.py +0 -0
  131. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tier_store.py +0 -0
  132. {webbee-0.5.4 → webbee-0.5.5}/tests/test_todo_panel.py +0 -0
  133. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tokens.py +0 -0
  134. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tools.py +0 -0
  135. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tools_vision_websearch.py +0 -0
  136. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tui.py +0 -0
  137. {webbee-0.5.4 → webbee-0.5.5}/tests/test_tui_hardening.py +0 -0
  138. {webbee-0.5.4 → webbee-0.5.5}/tests/test_update.py +0 -0
  139. {webbee-0.5.4 → webbee-0.5.5}/tests/test_update_badge_0340.py +0 -0
  140. {webbee-0.5.4 → webbee-0.5.5}/tests/test_urlopen.py +0 -0
  141. {webbee-0.5.4 → webbee-0.5.5}/tests/test_version_badge_corner.py +0 -0
  142. {webbee-0.5.4 → webbee-0.5.5}/tests/test_wallet.py +0 -0
  143. {webbee-0.5.4 → webbee-0.5.5}/tests/test_worktrees.py +0 -0
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.5
4
+
5
+ * **Installs on Python 3.10 again**: pip and pipx stopped with "conflicting dependencies / ResolutionImpossible"
6
+ because imperal-mcp up to 0.5.6 required Python 3.11 -- Ubuntu 22.04 and Pop!_OS 22.04 ship 3.10. webbee now
7
+ needs imperal-mcp >= 0.5.7, which runs on 3.10.
8
+ * **`/exit` no longer hangs on Python 3.10**: the steer poller asked `Task.cancelling()` (3.11+) whether a
9
+ turn had swallowed its cancel; on 3.10 the call failed, the poller kept looping and the terminal never
10
+ closed. A submitted turn now runs as its own task the poller waits on, so the cancel always reaches the
11
+ poller -- one path for every Python.
12
+ * **Python 3.10 is the stated floor** (was 3.9, which no dependency set could satisfy): an older Python now gets
13
+ pip's plain "requires a different Python" instead of a dependency conflict.
14
+ * **README installs through uv first** (it brings its own Python) and lists the install errors people hit.
15
+
3
16
  ## 0.5.4
4
17
 
5
18
  * **Code search by meaning for repos synced before**: imperal-sdk >= 6.3.6 tells the code map this client
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: webbee
3
- Version: 0.5.4
3
+ Version: 0.5.5
4
4
  Summary: Webbee 🐝 — the Imperal Cloud coding agent in your terminal
5
5
  Project-URL: Homepage, https://imperal.io
6
6
  Project-URL: Documentation, https://docs.imperal.io
@@ -17,7 +17,6 @@ Classifier: Environment :: Console
17
17
  Classifier: Intended Audience :: Developers
18
18
  Classifier: Operating System :: OS Independent
19
19
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.9
21
20
  Classifier: Programming Language :: Python :: 3.10
22
21
  Classifier: Programming Language :: Python :: 3.11
23
22
  Classifier: Programming Language :: Python :: 3.12
@@ -25,11 +24,11 @@ Classifier: Programming Language :: Python :: 3.13
25
24
  Classifier: Programming Language :: Python :: 3.14
26
25
  Classifier: Topic :: Software Development
27
26
  Classifier: Topic :: Utilities
28
- Requires-Python: >=3.9
27
+ Requires-Python: >=3.10
29
28
  Requires-Dist: asyncssh>=2.14
30
29
  Requires-Dist: httpx-sse>=0.4
31
30
  Requires-Dist: httpx>=0.27
32
- Requires-Dist: imperal-mcp>=0.5.0
31
+ Requires-Dist: imperal-mcp>=0.5.7
33
32
  Requires-Dist: imperal-sdk>=6.3.6
34
33
  Requires-Dist: model2vec>=0.8.2; sys_platform != 'darwin' or platform_machine != 'x86_64' or python_version < '3.13'
35
34
  Requires-Dist: numpy>=2; sys_platform != 'darwin' or platform_machine != 'x86_64' or python_version < '3.13'
@@ -79,21 +78,35 @@ Webbee is powered by **ICNLI** (*Infrastructure Contextual Natural Language Inte
79
78
 
80
79
  ## 📦 Installation
81
80
 
82
- Install easily using **pipx** (recommended) or **uv**:
81
+ One line — installs [uv](https://docs.astral.sh/uv/) if needed, which brings its own Python:
83
82
 
84
83
  ```sh
85
- pipx install webbee
86
- # or with uv:
87
- uv tool install webbee
84
+ curl -LsSf https://raw.githubusercontent.com/imperalcloud/webbee-code/main/install.sh | sh
88
85
  ```
89
86
 
90
- Or install in a Python virtual environment:
87
+ Or, if you already have uv or pipx:
91
88
 
92
89
  ```sh
93
- python3 -m venv .venv && source .venv/bin/activate
94
- pip install webbee
90
+ uv tool install webbee
91
+ # or:
92
+ pipx install webbee
95
93
  ```
96
94
 
95
+ Webbee needs **Python 3.10 or newer**. `uv` fetches a suitable Python by itself, so it works even where
96
+ the system Python is older (macOS ships 3.9).
97
+
98
+ <details>
99
+ <summary>Install problems</summary>
100
+
101
+ | You see | Why | Do |
102
+ |---------|-----|----|
103
+ | `Cannot install webbee==… because these package versions have conflicting dependencies` / `ResolutionImpossible` | pip/pipx runs on a Python older than 3.10 (or webbee < 0.5.5 on Python 3.10) | `uv tool install webbee`, or `pipx install --python python3.12 webbee` |
104
+ | `No matching distribution found for webbee` | Python older than 3.10 | same as above |
105
+ | `error: externally-managed-environment` | `pip install` into the system Python is blocked on Homebrew, Debian 12+, Ubuntu 23.04+ | `uv tool install webbee` or `pipx install webbee` |
106
+ | `webbee: command not found` after install | the tool folder is not on `PATH` | `uv tool update-shell` (or `pipx ensurepath`), then open a new terminal |
107
+
108
+ </details>
109
+
97
110
  ---
98
111
 
99
112
  ## 💡 Quick Start
@@ -27,21 +27,35 @@ Webbee is powered by **ICNLI** (*Infrastructure Contextual Natural Language Inte
27
27
 
28
28
  ## 📦 Installation
29
29
 
30
- Install easily using **pipx** (recommended) or **uv**:
30
+ One line — installs [uv](https://docs.astral.sh/uv/) if needed, which brings its own Python:
31
31
 
32
32
  ```sh
33
- pipx install webbee
34
- # or with uv:
35
- uv tool install webbee
33
+ curl -LsSf https://raw.githubusercontent.com/imperalcloud/webbee-code/main/install.sh | sh
36
34
  ```
37
35
 
38
- Or install in a Python virtual environment:
36
+ Or, if you already have uv or pipx:
39
37
 
40
38
  ```sh
41
- python3 -m venv .venv && source .venv/bin/activate
42
- pip install webbee
39
+ uv tool install webbee
40
+ # or:
41
+ pipx install webbee
43
42
  ```
44
43
 
44
+ Webbee needs **Python 3.10 or newer**. `uv` fetches a suitable Python by itself, so it works even where
45
+ the system Python is older (macOS ships 3.9).
46
+
47
+ <details>
48
+ <summary>Install problems</summary>
49
+
50
+ | You see | Why | Do |
51
+ |---------|-----|----|
52
+ | `Cannot install webbee==… because these package versions have conflicting dependencies` / `ResolutionImpossible` | pip/pipx runs on a Python older than 3.10 (or webbee < 0.5.5 on Python 3.10) | `uv tool install webbee`, or `pipx install --python python3.12 webbee` |
53
+ | `No matching distribution found for webbee` | Python older than 3.10 | same as above |
54
+ | `error: externally-managed-environment` | `pip install` into the system Python is blocked on Homebrew, Debian 12+, Ubuntu 23.04+ | `uv tool install webbee` or `pipx install webbee` |
55
+ | `webbee: command not found` after install | the tool folder is not on `PATH` | `uv tool update-shell` (or `pipx ensurepath`), then open a new terminal |
56
+
57
+ </details>
58
+
45
59
  ---
46
60
 
47
61
  ## 💡 Quick Start
@@ -1,14 +1,14 @@
1
1
  [project]
2
2
  name = "webbee"
3
- version = "0.5.4"
3
+ version = "0.5.5"
4
4
  description = "Webbee 🐝 — the Imperal Cloud coding agent in your terminal"
5
5
  readme = "README.md"
6
6
  license = "GPL-3.0-or-later"
7
7
  license-files = ["LICENSE"]
8
- requires-python = ">=3.9"
8
+ requires-python = ">=3.10"
9
9
  authors = [{ name = "Valentin Scerbacov", email = "valentin@imperal.io" }, { name = "Imperal, Inc." }]
10
10
  dependencies = [
11
- "imperal-mcp>=0.5.0",
11
+ "imperal-mcp>=0.5.7",
12
12
  "imperal-sdk>=6.3.6",
13
13
  "asyncssh>=2.14",
14
14
  "httpx>=0.27",
@@ -42,7 +42,6 @@ classifiers = [
42
42
  "Environment :: Console",
43
43
  "Intended Audience :: Developers",
44
44
  "Programming Language :: Python :: 3",
45
- "Programming Language :: Python :: 3.9",
46
45
  "Programming Language :: Python :: 3.10",
47
46
  "Programming Language :: Python :: 3.11",
48
47
  "Programming Language :: Python :: 3.12",
@@ -0,0 +1 @@
1
+ __version__ = "0.5.5"
@@ -75,13 +75,22 @@ def _consume_mode(payload, on_mode) -> bool:
75
75
  return True
76
76
 
77
77
 
78
- def _cancel_absorbed() -> bool:
79
- """True when this task received a cancel that a submitted turn swallowed
80
- (repl._run_turn treats CancelledError as a user interrupt). Without this
81
- check the poller would sail past its own cancellation and asyncio.run's
82
- shutdown would hang on a task that ignored it."""
83
- task = asyncio.current_task()
84
- return task is not None and task.cancelling() > 0
78
+ async def _await_turn(coro) -> None:
79
+ """Run a submitted turn and wait for it, letting a cancel of THIS task end the
80
+ poller even when the turn swallows CancelledError (repl._run_turn treats it as
81
+ a user interrupt). The turn runs as its own task and the poller only waits on
82
+ it, so the cancel lands in the poller's wait, never inside the turn: without
83
+ that the poller would sail past its own cancellation and asyncio.run's
84
+ shutdown would hang on a task that ignored it. Works on every Python
85
+ (Task.cancelling() would need 3.11)."""
86
+ turn = asyncio.ensure_future(coro)
87
+ try:
88
+ await asyncio.wait({turn})
89
+ except asyncio.CancelledError:
90
+ turn.cancel() # the turn ends as a user interrupt would
91
+ await asyncio.wait({turn})
92
+ raise
93
+ turn.result() # a turn's own error reaches the poller as before
85
94
 
86
95
 
87
96
  async def poll_idle_steer(cfg, token_provider, *, workspace: str, is_busy,
@@ -251,9 +260,7 @@ async def poll_idle_steer(cfg, token_provider, *, workspace: str, is_busy,
251
260
  if is_busy():
252
261
  continue
253
262
  last_active = now() # an attach pickup = activity
254
- await attach_turn(attach)
255
- if _cancel_absorbed():
256
- raise asyncio.CancelledError
263
+ await _await_turn(attach_turn(attach))
257
264
  failures = 0
258
265
  continue
259
266
  if not backlog:
@@ -266,10 +273,8 @@ async def poll_idle_steer(cfg, token_provider, *, workspace: str, is_busy,
266
273
  backlog.appendleft(item) # a local line won the race -- defer, don't drop
267
274
  continue
268
275
  last_active = now() # an item arrived = activity
269
- await submit(text, str(item.get("surface") or "telegram"),
270
- str(item.get("iid") or ""))
271
- if _cancel_absorbed():
272
- raise asyncio.CancelledError
276
+ await _await_turn(submit(text, str(item.get("surface") or "telegram"),
277
+ str(item.get("iid") or "")))
273
278
  except asyncio.CancelledError:
274
279
  raise
275
280
  except Exception:
@@ -1,6 +1,10 @@
1
- import tomllib
2
1
  import pathlib
3
2
 
3
+ import pytest
4
+
5
+ # tomllib is 3.11+; on 3.10 these checks run where the release is built
6
+ tomllib = pytest.importorskip("tomllib")
7
+
4
8
  ROOT = pathlib.Path(__file__).resolve().parent.parent
5
9
 
6
10
 
@@ -7,8 +7,10 @@ def test_version_is_semver():
7
7
 
8
8
 
9
9
  def test_version_matches_pyproject():
10
- import tomllib
11
10
  import pathlib
11
+
12
+ import pytest
13
+ tomllib = pytest.importorskip("tomllib") # 3.11+; the release build runs it
12
14
  root = pathlib.Path(__file__).resolve().parent.parent
13
15
  data = tomllib.loads((root / "pyproject.toml").read_text())
14
16
  assert data["project"]["version"] == webbee.__version__
@@ -1 +0,0 @@
1
- __version__ = "0.5.4"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes