ommlds 0.0.0.dev512__py3-none-any.whl → 0.0.0.dev514__py3-none-any.whl

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.
@@ -59,6 +59,12 @@ class ChatAppScreen(tx.Screen):
59
59
  'Copy selected text',
60
60
  show=False,
61
61
  ),
62
+
63
+ tx.Binding(
64
+ 'f10',
65
+ 'app.confirm_all_pending_tool_uses',
66
+ 'Confirms all pending tool uses',
67
+ ),
62
68
  ]
63
69
 
64
70
  @classmethod
@@ -110,6 +116,8 @@ class ChatApp(
110
116
 
111
117
  self._input_focused_key_events: weakref.WeakSet[tx.Key] = weakref.WeakSet()
112
118
 
119
+ self._pending_tool_confirmations: set[ToolConfirmationMessage] = set()
120
+
113
121
  def get_driver_class(self) -> type[tx.Driver]:
114
122
  return tx.get_pending_writes_driver_class(super().get_driver_class())
115
123
 
@@ -409,6 +417,10 @@ class ChatApp(
409
417
  fut,
410
418
  )
411
419
 
420
+ fut.add_done_callback(lambda _: self._pending_tool_confirmations.discard(tcm))
421
+
422
+ self._pending_tool_confirmations.add(tcm)
423
+
412
424
  async def inner() -> None:
413
425
  await self._mount_messages(tcm)
414
426
 
@@ -427,3 +439,13 @@ class ChatApp(
427
439
  async def action_cancel(self) -> None:
428
440
  if (cat := self._cur_chat_action) is not None:
429
441
  cat.cancel()
442
+
443
+ async def action_confirm_all_pending_tool_uses(self) -> None:
444
+ for tcm in list(self._pending_tool_confirmations):
445
+ if not tcm.has_rendered:
446
+ continue
447
+
448
+ if not tcm.has_confirmed:
449
+ await tcm.confirm()
450
+
451
+ self._pending_tool_confirmations.discard(tcm)
@@ -3,6 +3,7 @@ import asyncio
3
3
  import typing as ta
4
4
 
5
5
  from omdev.tui import textual as tx
6
+ from omlish import check
6
7
  from omlish import lang
7
8
 
8
9
 
@@ -145,14 +146,14 @@ class StreamAiMessage(AiMessage):
145
146
 
146
147
 
147
148
  class ToolConfirmationControls(tx.Static):
148
- class Allowed(tx.Message):
149
+ class ClickedAllow(tx.Message):
149
150
  pass
150
151
 
151
152
  def compose(self) -> tx.ComposeResult:
152
153
  yield tx.Button('Allow', action='allow')
153
154
 
154
155
  def action_allow(self) -> None:
155
- self.post_message(self.Allowed())
156
+ self.post_message(self.ClickedAllow())
156
157
 
157
158
 
158
159
  class ToolConfirmationMessage(Message):
@@ -170,24 +171,58 @@ class ToolConfirmationMessage(Message):
170
171
  self._inner_content = inner_content
171
172
  self._fut = fut
172
173
 
173
- def compose(self) -> tx.ComposeResult:
174
- with tx.Horizontal(classes='tool-confirmation-message-outer message-outer'):
175
- yield tx.Static('? ', classes='tool-confirmation-message-glyph message-glyph')
176
- with tx.Vertical(classes='tool-confirmation-message-inner tool-confirmation-message-inner-open message-inner'): # noqa
177
- yield tx.Static(self._outer_content, classes='tool-confirmation-message-outer-content')
178
- yield tx.Static(self._inner_content, classes='tool-confirmation-message-inner-content')
179
- yield ToolConfirmationControls(classes='tool-confirmation-message-controls')
174
+ self._has_rendered = False
175
+ self._has_confirmed = False
176
+
177
+ @property
178
+ def has_rendered(self) -> bool:
179
+ return self._has_rendered
180
+
181
+ @property
182
+ def has_confirmed(self) -> bool:
183
+ return self._has_confirmed
184
+
185
+ async def confirm(self) -> None:
186
+ check.equal(self._fut.done(), self._has_confirmed)
187
+
188
+ if self._has_confirmed:
189
+ return
190
+ self._has_confirmed = True
180
191
 
181
- @tx.on(ToolConfirmationControls.Allowed)
182
- async def on_allowed(self, event: ToolConfirmationControls.Allowed) -> None:
183
192
  inner = self.query_one(tx.Vertical)
193
+
184
194
  await inner.query_one(ToolConfirmationControls).remove()
195
+
185
196
  inner.remove_class('tool-confirmation-message-inner-open')
186
197
  inner.add_class('tool-confirmation-message-inner-closed')
198
+
187
199
  inner.query_one('.tool-confirmation-message-outer-content', tx.Static).update('Tool use confirmed.')
188
200
 
189
201
  self._fut.set_result(True)
190
202
 
203
+ def compose(self) -> tx.ComposeResult:
204
+ with tx.Horizontal(classes='tool-confirmation-message-outer message-outer'):
205
+ yield tx.Static('? ', classes='tool-confirmation-message-glyph message-glyph')
206
+ with tx.Vertical(classes=' '.join([
207
+ 'tool-confirmation-message-inner',
208
+ 'tool-confirmation-message-inner-open',
209
+ 'message-inner',
210
+ ])):
211
+ yield tx.Static(self._outer_content, classes='tool-confirmation-message-outer-content')
212
+ yield tx.Static(self._inner_content, classes='tool-confirmation-message-inner-content')
213
+
214
+ yield ToolConfirmationControls(classes='tool-confirmation-message-controls')
215
+
216
+ def on_mount(self) -> None:
217
+ def inner():
218
+ self._has_rendered = True
219
+
220
+ self.call_after_refresh(inner)
221
+
222
+ @tx.on(ToolConfirmationControls.ClickedAllow)
223
+ async def on_clicked_allow(self, event: ToolConfirmationControls.ClickedAllow) -> None:
224
+ await self.confirm()
225
+
191
226
 
192
227
  #
193
228
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommlds
3
- Version: 0.0.0.dev512
3
+ Version: 0.0.0.dev514
4
4
  Summary: ommlds
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,9 +14,9 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: omlish==0.0.0.dev512
17
+ Requires-Dist: omlish==0.0.0.dev514
18
18
  Provides-Extra: all
19
- Requires-Dist: omdev==0.0.0.dev512; extra == "all"
19
+ Requires-Dist: omdev==0.0.0.dev514; extra == "all"
20
20
  Requires-Dist: llama-cpp-python~=0.3; extra == "all"
21
21
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "all"
22
22
  Requires-Dist: mlx-lm~=0.29; sys_platform == "darwin" and extra == "all"
@@ -39,7 +39,7 @@ Requires-Dist: mwparserfromhell~=0.7; extra == "all"
39
39
  Requires-Dist: wikitextparser~=0.56; extra == "all"
40
40
  Requires-Dist: lxml>=5.3; python_version < "3.13" and extra == "all"
41
41
  Provides-Extra: omdev
42
- Requires-Dist: omdev==0.0.0.dev512; extra == "omdev"
42
+ Requires-Dist: omdev==0.0.0.dev514; extra == "omdev"
43
43
  Provides-Extra: backends
44
44
  Requires-Dist: llama-cpp-python~=0.3; extra == "backends"
45
45
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "backends"
@@ -214,7 +214,7 @@ ommlds/cli/sessions/chat/interfaces/bare/interactive.py,sha256=ZnYoePvXtUbhkDQ0j
214
214
  ommlds/cli/sessions/chat/interfaces/bare/oneshot.py,sha256=b758OIa0gf9I_0UdxYJ6re-g8-8xndgr3R0OotUOsmc,387
215
215
  ommlds/cli/sessions/chat/interfaces/bare/tools.py,sha256=_UsuoXLIvfpFP_We5DBBlhm6rwB3_cFA3lmFvpG9b-A,824
216
216
  ommlds/cli/sessions/chat/interfaces/textual/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
217
- ommlds/cli/sessions/chat/interfaces/textual/app.py,sha256=glO32FiPn4T1nLXBOe2QpTwkFv0yGKchGZQHGFQVaOw,12614
217
+ ommlds/cli/sessions/chat/interfaces/textual/app.py,sha256=hgEQ9QEAxYVR-d7z4FJsXycbkHKcLzzAWQ6zR0jy_Zs,13301
218
218
  ommlds/cli/sessions/chat/interfaces/textual/configs.py,sha256=-pvG2_Uai70ohDfK4Tt8yaHnvdCs10_gaoQkr-CsOqA,213
219
219
  ommlds/cli/sessions/chat/interfaces/textual/facades.py,sha256=zXVG7DKVl-Xtdc893O_yktHCMvM0do6hLesMd8hbqeo,411
220
220
  ommlds/cli/sessions/chat/interfaces/textual/inject.py,sha256=eBhFVZ2VmQdoTPSZvi2OSkZ-fX8Mw2TKo28bHZeACJY,3056
@@ -227,7 +227,7 @@ ommlds/cli/sessions/chat/interfaces/textual/styles/markdown.tcss,sha256=KCKlgt_E
227
227
  ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss,sha256=tl0ZPnYY3jsumj_Y_AFaA1Vbz7AvgWC7xMuS-JOAPEk,1820
228
228
  ommlds/cli/sessions/chat/interfaces/textual/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
229
229
  ommlds/cli/sessions/chat/interfaces/textual/widgets/input.py,sha256=MMONcOi3Aq8ZzmvJn6tHNPbfV3EOol25fABxtW1h--E,1827
230
- ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py,sha256=_xu24596FT0MZMWOdE0-2SkPF_na_J6lG35CstKCI94,5614
230
+ ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py,sha256=RiERDoNe7HwSbQx0ATh0cToGhwOXnNLdnkVZnWV203g,6332
231
231
  ommlds/cli/sessions/completion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
232
232
  ommlds/cli/sessions/completion/configs.py,sha256=jOtadH46Esx6CztbQazAgIx9Tt5uuu4pGPov3G3O5Ac,286
233
233
  ommlds/cli/sessions/completion/inject.py,sha256=oWRS2D4d-mdCwi7jT_Is462k1UBlCruz4nrUeT9xedY,848
@@ -526,9 +526,9 @@ ommlds/wiki/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
526
526
  ommlds/wiki/utils/io.py,sha256=UKgDJGtmpnWvIqVd2mJc2QNPOqlToEY1GEveNp6_pMo,7088
527
527
  ommlds/wiki/utils/progress.py,sha256=EhvKcMFYtsarCQhIahlO6f0SboyAKP3UwUyrnVnP-Vk,3222
528
528
  ommlds/wiki/utils/xml.py,sha256=sNJNkZ9rT8B-kJMO6bRz8J1USy4fyPx0m2PwTX7vxYY,3846
529
- ommlds-0.0.0.dev512.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
530
- ommlds-0.0.0.dev512.dist-info/METADATA,sha256=iYOryaX8qoz-w6zU-x-e47TdQae2phv2yBnh4828-KU,3602
531
- ommlds-0.0.0.dev512.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
532
- ommlds-0.0.0.dev512.dist-info/entry_points.txt,sha256=Z5YWtX7ClfiCKdW-dd_CSVvM0h4yQpJPi-2G3q6gNFo,35
533
- ommlds-0.0.0.dev512.dist-info/top_level.txt,sha256=Rbnk5d5wi58vnAXx13WFZqdQ4VX8hBCS2hEL3WeXOhY,7
534
- ommlds-0.0.0.dev512.dist-info/RECORD,,
529
+ ommlds-0.0.0.dev514.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
530
+ ommlds-0.0.0.dev514.dist-info/METADATA,sha256=q4ShoZYDFsg8DlxflkSxvX0wF1O_W0ENF79Ne0-WEJQ,3602
531
+ ommlds-0.0.0.dev514.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
532
+ ommlds-0.0.0.dev514.dist-info/entry_points.txt,sha256=Z5YWtX7ClfiCKdW-dd_CSVvM0h4yQpJPi-2G3q6gNFo,35
533
+ ommlds-0.0.0.dev514.dist-info/top_level.txt,sha256=Rbnk5d5wi58vnAXx13WFZqdQ4VX8hBCS2hEL3WeXOhY,7
534
+ ommlds-0.0.0.dev514.dist-info/RECORD,,