ommlds 0.0.0.dev494__py3-none-any.whl → 0.0.0.dev495__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.
- ommlds/cli/_dataclasses.py +7 -7
- ommlds/cli/backends/inject.py +51 -8
- ommlds/cli/backends/meta.py +35 -0
- ommlds/cli/inject.py +1 -1
- ommlds/cli/sessions/chat/drivers/{driver.py → impl.py} +2 -9
- ommlds/cli/sessions/chat/drivers/inject.py +5 -3
- ommlds/cli/sessions/chat/drivers/state/inject.py +2 -3
- ommlds/cli/sessions/chat/drivers/tools/injection.py +4 -4
- ommlds/cli/sessions/chat/drivers/types.py +21 -0
- ommlds/cli/sessions/chat/drivers/user/inject.py +1 -1
- ommlds/cli/sessions/chat/facades/commands/inject.py +0 -2
- ommlds/cli/sessions/chat/facades/commands/simple.py +2 -8
- ommlds/cli/sessions/chat/facades/facade.py +1 -1
- ommlds/cli/sessions/chat/facades/inject.py +5 -0
- ommlds/cli/sessions/chat/facades/ui.py +11 -0
- ommlds/cli/sessions/chat/interfaces/bare/interactive.py +1 -1
- ommlds/cli/sessions/chat/interfaces/bare/oneshot.py +1 -1
- ommlds/cli/sessions/chat/interfaces/textual/app.py +21 -3
- ommlds/cli/sessions/chat/interfaces/textual/inject.py +2 -5
- ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +2 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +12 -5
- ommlds/minichain/__init__.py +16 -6
- ommlds/minichain/_dataclasses.py +6872 -3644
- ommlds/minichain/backends/strings/resolving.py +1 -1
- ommlds/minichain/chat/messages.py +1 -1
- ommlds/minichain/content/_marshal.py +6 -4
- ommlds/minichain/content/cancontent.py +32 -0
- ommlds/minichain/content/materialize.py +2 -25
- ommlds/minichain/content/prepare.py +3 -3
- ommlds/minichain/content/sequence.py +2 -2
- ommlds/minichain/content/tag.py +19 -0
- ommlds/minichain/content/transforms/interleave.py +10 -3
- ommlds/minichain/lib/fs/tools/read.py +1 -1
- ommlds/minichain/lib/fs/tools/recursivels/rendering.py +1 -1
- ommlds/minichain/lib/fs/tools/recursivels/running.py +1 -1
- ommlds/minichain/lib/todo/types.py +1 -1
- ommlds/minichain/meta/__init__.py +0 -0
- ommlds/minichain/meta/firstinwins.py +131 -0
- ommlds/minichain/text/applypatch.py +2 -1
- ommlds/minichain/text/toolparsing/llamacpp/types.py +1 -1
- ommlds/minichain/tokens/specials.py +1 -1
- ommlds/minichain/tools/execution/errorhandling.py +35 -0
- ommlds/minichain/tools/execution/errors.py +1 -1
- ommlds/minichain/tools/reflect.py +1 -1
- ommlds/minichain/tools/types.py +1 -1
- ommlds/minichain/vectors/_marshal.py +1 -1
- {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev495.dist-info}/METADATA +4 -4
- {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev495.dist-info}/RECORD +52 -46
- {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev495.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev495.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev495.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev495.dist-info}/top_level.txt +0 -0
ommlds/cli/_dataclasses.py
CHANGED
|
@@ -2062,7 +2062,7 @@ def _process_dataclass__55eb2b38eb7d4e32f3a9306577040632e1c376fb():
|
|
|
2062
2062
|
'__dataclass__init__fields__0__annotation',
|
|
2063
2063
|
),
|
|
2064
2064
|
cls_names=(
|
|
2065
|
-
('ommlds.cli.sessions.chat.drivers.
|
|
2065
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'AiDeltaChatEvent'),
|
|
2066
2066
|
),
|
|
2067
2067
|
)
|
|
2068
2068
|
def _process_dataclass__aff24d9a92d53ba94dacb7fb303b9eb4ebd0763f():
|
|
@@ -2196,8 +2196,8 @@ def _process_dataclass__aff24d9a92d53ba94dacb7fb303b9eb4ebd0763f():
|
|
|
2196
2196
|
'__dataclass__init__fields__0__annotation',
|
|
2197
2197
|
),
|
|
2198
2198
|
cls_names=(
|
|
2199
|
-
('ommlds.cli.sessions.chat.drivers.
|
|
2200
|
-
('ommlds.cli.sessions.chat.drivers.
|
|
2199
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'AiMessagesChatEvent'),
|
|
2200
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'UserMessagesChatEvent'),
|
|
2201
2201
|
),
|
|
2202
2202
|
)
|
|
2203
2203
|
def _process_dataclass__b211fde543b7c2c533cdcf9f21b47d2f7f76e5c9():
|
|
@@ -2330,9 +2330,9 @@ def _process_dataclass__b211fde543b7c2c533cdcf9f21b47d2f7f76e5c9():
|
|
|
2330
2330
|
'__dataclass__init__fields__0__annotation',
|
|
2331
2331
|
),
|
|
2332
2332
|
cls_names=(
|
|
2333
|
-
('ommlds.cli.sessions.chat.drivers.
|
|
2333
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'ChatDriverId'),
|
|
2334
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'ChatId'),
|
|
2334
2335
|
('ommlds.cli.sessions.chat.drivers.state.ids', 'ChatStateStorageKey'),
|
|
2335
|
-
('ommlds.cli.sessions.chat.drivers.types', 'ChatDriverId'),
|
|
2336
2336
|
),
|
|
2337
2337
|
)
|
|
2338
2338
|
def _process_dataclass__3576262424b3ef8ff20966fa3744e5dba9a2ae7d():
|
|
@@ -2471,7 +2471,7 @@ def _process_dataclass__3576262424b3ef8ff20966fa3744e5dba9a2ae7d():
|
|
|
2471
2471
|
'__dataclass__init__fields__1__annotation',
|
|
2472
2472
|
),
|
|
2473
2473
|
cls_names=(
|
|
2474
|
-
('ommlds.cli.sessions.chat.drivers.
|
|
2474
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'ChatPhaseCallback'),
|
|
2475
2475
|
),
|
|
2476
2476
|
)
|
|
2477
2477
|
def _process_dataclass__927265170439340895560333250bc087fa726eff():
|
|
@@ -2639,7 +2639,7 @@ def _process_dataclass__927265170439340895560333250bc087fa726eff():
|
|
|
2639
2639
|
'__dataclass__init__fields__3__default',
|
|
2640
2640
|
),
|
|
2641
2641
|
cls_names=(
|
|
2642
|
-
('ommlds.cli.sessions.chat.drivers.
|
|
2642
|
+
('ommlds.cli.sessions.chat.drivers.impl', 'ChatState'),
|
|
2643
2643
|
),
|
|
2644
2644
|
)
|
|
2645
2645
|
def _process_dataclass__9f7e26a87dd163b610f38caa1ce9b3c6356e632a():
|
ommlds/cli/backends/inject.py
CHANGED
|
@@ -12,6 +12,7 @@ from .injection import backend_configs
|
|
|
12
12
|
with lang.auto_proxy_import(globals()):
|
|
13
13
|
from ...minichain.backends.impls.huggingface import repos as hf_repos
|
|
14
14
|
from . import catalog as _catalog
|
|
15
|
+
from . import meta as _meta
|
|
15
16
|
from . import types as _types
|
|
16
17
|
|
|
17
18
|
|
|
@@ -43,14 +44,56 @@ def bind_backends(cfg: BackendConfig = BackendConfig()) -> inj.Elements:
|
|
|
43
44
|
if cfg.backend is not None:
|
|
44
45
|
lst.append(inj.bind(_types.BackendName, to_const=cfg.backend))
|
|
45
46
|
else:
|
|
46
|
-
lst.append(inj.bind(_types.BackendName, to_fn=inj.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
]
|
|
47
|
+
lst.append(inj.bind(_types.BackendName, to_fn=inj.target(dbn=_types.DefaultBackendName)(lambda dbn: dbn)))
|
|
48
|
+
|
|
49
|
+
backend_provider_pairs: list = [
|
|
50
|
+
(_types.ChatChoicesServiceBackendProvider, _catalog.CatalogChatChoicesServiceBackendProvider),
|
|
51
|
+
(_types.ChatChoicesStreamServiceBackendProvider, _catalog.CatalogChatChoicesStreamServiceBackendProvider),
|
|
52
|
+
(_types.CompletionServiceBackendProvider, _catalog.CatalogCompletionServiceBackendProvider),
|
|
53
|
+
(_types.EmbeddingServiceBackendProvider, _catalog.CatalogEmbeddingServiceBackendProvider),
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
for bp_iface, bp_impl in backend_provider_pairs:
|
|
57
|
+
bp_stack = inj.wrapper_binder_helper(bp_iface)
|
|
58
|
+
|
|
59
|
+
if bp_iface is _types.ChatChoicesServiceBackendProvider:
|
|
60
|
+
fiw_ben_lst: list[str] = [
|
|
61
|
+
# 'openai',
|
|
62
|
+
# 'anthropic',
|
|
63
|
+
# 'groq',
|
|
64
|
+
# 'cerebras',
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
if fiw_ben_lst:
|
|
68
|
+
for ben in fiw_ben_lst:
|
|
69
|
+
ben_bp_key: inj.Key = inj.Key(bp_impl, tag=ben)
|
|
70
|
+
lst.extend([
|
|
71
|
+
inj.private(
|
|
72
|
+
inj.bind(_types.BackendName, to_const=ben),
|
|
73
|
+
inj.bind(ben_bp_key, to_ctor=bp_impl, singleton=True),
|
|
74
|
+
inj.bind(bp_iface, to_key=ben_bp_key),
|
|
75
|
+
inj.expose(ben_bp_key),
|
|
76
|
+
),
|
|
77
|
+
bp_stack.push_bind(to_key=ben_bp_key),
|
|
78
|
+
])
|
|
79
|
+
|
|
80
|
+
fiw_key: inj.Key = inj.Key(_meta.FirstInWinsBackendProvider, tag=bp_iface)
|
|
81
|
+
lst.extend([
|
|
82
|
+
inj.private(
|
|
83
|
+
inj.set_binder[_types.BackendProvider]().bind(bp_stack.top),
|
|
84
|
+
inj.bind(fiw_key, to_ctor=_meta.FirstInWinsBackendProvider, singleton=True),
|
|
85
|
+
inj.expose(fiw_key),
|
|
86
|
+
),
|
|
87
|
+
bp_stack.push_bind(to_key=fiw_key),
|
|
88
|
+
])
|
|
89
|
+
|
|
90
|
+
else:
|
|
91
|
+
lst.append(bp_stack.push_bind(to_ctor=bp_impl, singleton=True))
|
|
92
|
+
|
|
93
|
+
else:
|
|
94
|
+
lst.append(bp_stack.push_bind(to_ctor=bp_impl, singleton=True))
|
|
95
|
+
|
|
96
|
+
lst.append(inj.bind(bp_iface, to_key=bp_stack.top))
|
|
54
97
|
|
|
55
98
|
#
|
|
56
99
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from ... import minichain as mc
|
|
5
|
+
from .types import BackendProvider
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
ServiceT = ta.TypeVar('ServiceT', bound=mc.Service)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FirstInWinsBackendProvider(BackendProvider[ServiceT]):
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
backend_providers: ta.AbstractSet[BackendProvider],
|
|
18
|
+
) -> None:
|
|
19
|
+
super().__init__()
|
|
20
|
+
|
|
21
|
+
self._backend_providers = [ta.cast(BackendProvider[ServiceT], bp) for bp in backend_providers]
|
|
22
|
+
|
|
23
|
+
def provide_backend(self) -> ta.AsyncContextManager[ServiceT]:
|
|
24
|
+
@contextlib.asynccontextmanager
|
|
25
|
+
async def inner():
|
|
26
|
+
from ...minichain.meta.firstinwins import AsyncioFirstInWinsService
|
|
27
|
+
|
|
28
|
+
async with contextlib.AsyncExitStack() as aes:
|
|
29
|
+
svcs = [
|
|
30
|
+
await aes.enter_async_context(bp.provide_backend())
|
|
31
|
+
for bp in self._backend_providers
|
|
32
|
+
]
|
|
33
|
+
yield AsyncioFirstInWinsService(*svcs)
|
|
34
|
+
|
|
35
|
+
return inner()
|
ommlds/cli/inject.py
CHANGED
|
@@ -3,10 +3,6 @@ TODO:
|
|
|
3
3
|
- lifecycles
|
|
4
4
|
- StreamService
|
|
5
5
|
"""
|
|
6
|
-
import typing as ta
|
|
7
|
-
|
|
8
|
-
from omlish import lang
|
|
9
|
-
|
|
10
6
|
from ..... import minichain as mc
|
|
11
7
|
from .ai.types import AiChatGenerator
|
|
12
8
|
from .events.manager import ChatEventsManager
|
|
@@ -14,16 +10,13 @@ from .events.types import UserMessagesChatEvent
|
|
|
14
10
|
from .phases.manager import ChatPhaseManager
|
|
15
11
|
from .phases.types import ChatPhase
|
|
16
12
|
from .state.types import ChatStateManager
|
|
13
|
+
from .types import ChatDriver
|
|
17
14
|
|
|
18
15
|
|
|
19
16
|
##
|
|
20
17
|
|
|
21
18
|
|
|
22
|
-
class
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class ChatDriver:
|
|
19
|
+
class ChatDriverImpl(ChatDriver):
|
|
27
20
|
def __init__(
|
|
28
21
|
self,
|
|
29
22
|
*,
|
|
@@ -14,7 +14,7 @@ from .configs import DriverConfig
|
|
|
14
14
|
|
|
15
15
|
with lang.auto_proxy_import(globals()):
|
|
16
16
|
from ....backends import inject as _backends
|
|
17
|
-
from . import
|
|
17
|
+
from . import impl as _impl
|
|
18
18
|
from . import types as _types
|
|
19
19
|
from .ai import inject as _ai
|
|
20
20
|
from .events import inject as _events
|
|
@@ -51,8 +51,10 @@ def bind_driver(cfg: DriverConfig = DriverConfig()) -> inj.Elements:
|
|
|
51
51
|
#
|
|
52
52
|
|
|
53
53
|
els.extend([
|
|
54
|
-
inj.bind(
|
|
55
|
-
inj.
|
|
54
|
+
inj.bind(_impl.ChatDriverImpl, singleton=True),
|
|
55
|
+
inj.bind(_types.ChatDriver, to_key=_impl.ChatDriverImpl),
|
|
56
|
+
|
|
57
|
+
inj.bind_async_late(_types.ChatDriver, _types.ChatDriverGetter),
|
|
56
58
|
])
|
|
57
59
|
|
|
58
60
|
#
|
|
@@ -59,11 +59,10 @@ def bind_state(cfg: StateConfig = StateConfig()) -> inj.Elements:
|
|
|
59
59
|
els.extend([
|
|
60
60
|
inj.bind(_ids.LastChatIdManager, singleton=True),
|
|
61
61
|
|
|
62
|
-
phase_callbacks().bind_item(to_fn=inj.
|
|
63
|
-
lambda lcim, cid: ChatPhaseCallback(ChatPhase.STARTED, lambda: lcim.set_last_chat_id(cid)),
|
|
62
|
+
phase_callbacks().bind_item(to_fn=inj.target(
|
|
64
63
|
lcim=_ids.LastChatIdManager,
|
|
65
64
|
cid=_types.ChatId,
|
|
66
|
-
)),
|
|
65
|
+
)(lambda lcim, cid: ChatPhaseCallback(ChatPhase.STARTED, lambda: lcim.set_last_chat_id(cid)))),
|
|
67
66
|
])
|
|
68
67
|
|
|
69
68
|
elif cfg.state == 'ephemeral':
|
|
@@ -29,10 +29,10 @@ def tool_context_providers() -> 'inj.ItemsBinderHelper[_execution.ToolContextPro
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def bind_tool_context_provider_to_key(key: ta.Any) -> inj.Elements:
|
|
32
|
-
return tool_context_providers().bind_item(
|
|
33
|
-
lambda v: _execution.ToolContextProvider(lambda: [v]),
|
|
34
|
-
|
|
35
|
-
)
|
|
32
|
+
return tool_context_providers().bind_item(
|
|
33
|
+
to_fn=inj.target(v=key)(lambda v: _execution.ToolContextProvider(lambda: [v])),
|
|
34
|
+
singleton=True,
|
|
35
|
+
)
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
##
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import typing as ta
|
|
1
3
|
import uuid
|
|
2
4
|
|
|
5
|
+
from omlish import lang
|
|
3
6
|
from omlish import typedvalues as tv
|
|
4
7
|
|
|
8
|
+
from ..... import minichain as mc
|
|
9
|
+
|
|
5
10
|
|
|
6
11
|
##
|
|
7
12
|
|
|
8
13
|
|
|
9
14
|
class ChatDriverId(tv.UniqueScalarTypedValue[uuid.UUID]):
|
|
10
15
|
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ChatDriverGetter(lang.Func0[ta.Awaitable['ChatDriver']]):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ChatDriver(lang.Abstract):
|
|
23
|
+
async def start(self) -> None:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
async def stop(self) -> None:
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
@abc.abstractmethod
|
|
30
|
+
def send_user_messages(self, next_user_chat: 'mc.UserChat') -> ta.Awaitable[None]:
|
|
31
|
+
raise NotImplementedError
|
|
@@ -32,8 +32,6 @@ def bind_commands(cfg: CommandsConfig = CommandsConfig()) -> inj.Elements:
|
|
|
32
32
|
inj.bind(_simple.EchoCommand, singleton=True),
|
|
33
33
|
commands().bind_item(to_key=_simple.EchoCommand),
|
|
34
34
|
|
|
35
|
-
inj.bind(_simple.QuitSignal, to_const=lang.as_async(lambda: None)), # type: ignore # FIXME: lol
|
|
36
|
-
|
|
37
35
|
inj.bind(_simple.QuitCommand, singleton=True),
|
|
38
36
|
commands().bind_item(to_key=_simple.QuitCommand),
|
|
39
37
|
])
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import lang
|
|
4
1
|
from omlish.argparse import all as argparse
|
|
5
2
|
|
|
3
|
+
from ..ui import UiQuitSignal
|
|
6
4
|
from .base import Command
|
|
7
5
|
|
|
8
6
|
|
|
@@ -22,15 +20,11 @@ class EchoCommand(Command):
|
|
|
22
20
|
##
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
class QuitSignal(lang.Func0[ta.Awaitable[None]]):
|
|
26
|
-
pass
|
|
27
|
-
|
|
28
|
-
|
|
29
23
|
class QuitCommand(Command):
|
|
30
24
|
def __init__(
|
|
31
25
|
self,
|
|
32
26
|
*,
|
|
33
|
-
quit_signal:
|
|
27
|
+
quit_signal: UiQuitSignal,
|
|
34
28
|
) -> None:
|
|
35
29
|
super().__init__()
|
|
36
30
|
|
|
@@ -6,6 +6,7 @@ from .configs import FacadeConfig
|
|
|
6
6
|
|
|
7
7
|
with lang.auto_proxy_import(globals()):
|
|
8
8
|
from . import facade as _facade
|
|
9
|
+
from . import ui as _ui
|
|
9
10
|
from .commands import inject as _commands
|
|
10
11
|
|
|
11
12
|
|
|
@@ -27,4 +28,8 @@ def bind_facade(cfg: FacadeConfig = FacadeConfig()) -> inj.Elements:
|
|
|
27
28
|
|
|
28
29
|
#
|
|
29
30
|
|
|
31
|
+
els.append(inj.bind(_ui.UiQuitSignal(_ui.raise_system_exit_ui_quit_signal)))
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
|
|
30
35
|
return inj.as_elements(*els)
|
|
@@ -21,3 +21,14 @@ class NopUiMessageDisplayer(UiMessageDisplayer):
|
|
|
21
21
|
class PrintMessageDisplayer(UiMessageDisplayer):
|
|
22
22
|
async def display_ui_message(self, content: str) -> None:
|
|
23
23
|
print(content)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class UiQuitSignal(lang.Func0[ta.Awaitable[None]]):
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def raise_system_exit_ui_quit_signal() -> None:
|
|
34
|
+
raise SystemExit
|
|
@@ -3,7 +3,7 @@ import typing as ta
|
|
|
3
3
|
from .....inputs.asyncs import AsyncStringInput
|
|
4
4
|
from .....inputs.asyncs import SyncAsyncStringInput
|
|
5
5
|
from .....inputs.sync import InputSyncStringInput
|
|
6
|
-
from ...drivers.
|
|
6
|
+
from ...drivers.types import ChatDriver
|
|
7
7
|
from ...facades.facade import ChatFacade
|
|
8
8
|
from ..base import ChatInterface
|
|
9
9
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import os
|
|
3
3
|
import typing as ta
|
|
4
|
+
import weakref
|
|
4
5
|
|
|
5
6
|
from omdev.tui import textual as tx
|
|
6
7
|
from omlish import check
|
|
@@ -10,14 +11,15 @@ from omlish.logs import all as logs
|
|
|
10
11
|
|
|
11
12
|
from ...... import minichain as mc
|
|
12
13
|
from .....backends.types import BackendName
|
|
13
|
-
from ...drivers.driver import ChatDriver
|
|
14
14
|
from ...drivers.events.types import AiDeltaChatEvent
|
|
15
15
|
from ...drivers.events.types import AiMessagesChatEvent
|
|
16
|
+
from ...drivers.types import ChatDriver
|
|
16
17
|
from ...facades.facade import ChatFacade
|
|
17
18
|
from .styles import read_app_css
|
|
18
19
|
from .widgets.input import InputOuter
|
|
19
20
|
from .widgets.input import InputTextArea
|
|
20
21
|
from .widgets.messages import AiMessage
|
|
22
|
+
from .widgets.messages import MessagesContainer
|
|
21
23
|
from .widgets.messages import StaticAiMessage
|
|
22
24
|
from .widgets.messages import StreamAiMessage
|
|
23
25
|
from .widgets.messages import ToolConfirmationMessage
|
|
@@ -66,6 +68,8 @@ class ChatApp(tx.App):
|
|
|
66
68
|
|
|
67
69
|
self._chat_action_queue: asyncio.Queue[ta.Any] = asyncio.Queue()
|
|
68
70
|
|
|
71
|
+
self._input_focused_key_events: weakref.WeakSet[tx.Key] = weakref.WeakSet()
|
|
72
|
+
|
|
69
73
|
def get_driver_class(self) -> type[tx.Driver]:
|
|
70
74
|
return tx.get_pending_writes_driver_class(super().get_driver_class())
|
|
71
75
|
|
|
@@ -74,7 +78,7 @@ class ChatApp(tx.App):
|
|
|
74
78
|
#
|
|
75
79
|
|
|
76
80
|
def compose(self) -> tx.ComposeResult:
|
|
77
|
-
yield
|
|
81
|
+
yield MessagesContainer(id='messages-container')
|
|
78
82
|
|
|
79
83
|
yield InputOuter(id='input-outer')
|
|
80
84
|
|
|
@@ -84,7 +88,7 @@ class ChatApp(tx.App):
|
|
|
84
88
|
return self.query_one('#input', InputTextArea)
|
|
85
89
|
|
|
86
90
|
def _get_messages_container(self) -> tx.VerticalScroll:
|
|
87
|
-
return self.query_one('#messages-container',
|
|
91
|
+
return self.query_one('#messages-container', MessagesContainer)
|
|
88
92
|
|
|
89
93
|
#
|
|
90
94
|
|
|
@@ -261,6 +265,20 @@ class ChatApp(tx.App):
|
|
|
261
265
|
|
|
262
266
|
await self._chat_action_queue.put(ChatApp.UserInput(event.text))
|
|
263
267
|
|
|
268
|
+
@tx.on(tx.Key)
|
|
269
|
+
async def on_key(self, event: tx.Key) -> None:
|
|
270
|
+
if event in self._input_focused_key_events:
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
chat_input = self._get_input_text_area()
|
|
274
|
+
|
|
275
|
+
if not chat_input.has_focus:
|
|
276
|
+
self._input_focused_key_events.add(event)
|
|
277
|
+
|
|
278
|
+
chat_input.focus()
|
|
279
|
+
|
|
280
|
+
self.screen.post_message(tx.Key(event.key, event.character))
|
|
281
|
+
|
|
264
282
|
#
|
|
265
283
|
|
|
266
284
|
async def confirm_tool_use(
|
|
@@ -44,10 +44,7 @@ def bind_textual(cfg: TextualInterfaceConfig = TextualInterfaceConfig()) -> inj.
|
|
|
44
44
|
els.extend([
|
|
45
45
|
inj.bind(_app.ChatEventQueue, to_const=asyncio.Queue()),
|
|
46
46
|
|
|
47
|
-
event_callbacks().bind_item(to_fn=inj.
|
|
48
|
-
lambda eq: lambda ev: eq.put(ev),
|
|
49
|
-
eq=_app.ChatEventQueue,
|
|
50
|
-
)),
|
|
47
|
+
event_callbacks().bind_item(to_fn=inj.target(eq=_app.ChatEventQueue)(lambda eq: lambda ev: eq.put(ev))),
|
|
51
48
|
])
|
|
52
49
|
|
|
53
50
|
#
|
|
@@ -83,7 +80,7 @@ def bind_textual(cfg: TextualInterfaceConfig = TextualInterfaceConfig()) -> inj.
|
|
|
83
80
|
|
|
84
81
|
inj.bind(
|
|
85
82
|
tx.DevtoolsSetup,
|
|
86
|
-
to_async_fn=inj.
|
|
83
|
+
to_async_fn=inj.target(mgr=tx.DevtoolsManager)(lambda mgr: mgr.get_setup()),
|
|
87
84
|
singleton=True,
|
|
88
85
|
),
|
|
89
86
|
])
|
|
@@ -9,6 +9,13 @@ from omlish import lang
|
|
|
9
9
|
##
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
class MessagesContainer(tx.VerticalScroll):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
12
19
|
class Message(tx.Static, lang.Abstract):
|
|
13
20
|
def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
|
|
14
21
|
super().__init__(*args, **kwargs)
|
|
@@ -16,7 +23,7 @@ class Message(tx.Static, lang.Abstract):
|
|
|
16
23
|
self.add_class('message')
|
|
17
24
|
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
#
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
class WelcomeMessage(Message):
|
|
@@ -32,7 +39,7 @@ class WelcomeMessage(Message):
|
|
|
32
39
|
yield tx.Static(self._content, classes='welcome-message-content')
|
|
33
40
|
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
#
|
|
36
43
|
|
|
37
44
|
|
|
38
45
|
class UserMessage(Message):
|
|
@@ -50,7 +57,7 @@ class UserMessage(Message):
|
|
|
50
57
|
yield tx.Static(self._content)
|
|
51
58
|
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
#
|
|
54
61
|
|
|
55
62
|
|
|
56
63
|
class AiMessage(Message, lang.Abstract):
|
|
@@ -124,7 +131,7 @@ class StreamAiMessage(AiMessage):
|
|
|
124
131
|
self._stream_ = None
|
|
125
132
|
|
|
126
133
|
|
|
127
|
-
|
|
134
|
+
#
|
|
128
135
|
|
|
129
136
|
|
|
130
137
|
class ToolConfirmationControls(tx.Static):
|
|
@@ -172,7 +179,7 @@ class ToolConfirmationMessage(Message):
|
|
|
172
179
|
self._fut.set_result(True)
|
|
173
180
|
|
|
174
181
|
|
|
175
|
-
|
|
182
|
+
#
|
|
176
183
|
|
|
177
184
|
|
|
178
185
|
class UiMessage(Message):
|
ommlds/minichain/__init__.py
CHANGED
|
@@ -227,6 +227,10 @@ with _lang.auto_proxy_init(
|
|
|
227
227
|
|
|
228
228
|
##
|
|
229
229
|
|
|
230
|
+
from .content.cancontent import ( # noqa
|
|
231
|
+
CanContent,
|
|
232
|
+
)
|
|
233
|
+
|
|
230
234
|
from .content.images import ( # noqa
|
|
231
235
|
ImageContent,
|
|
232
236
|
)
|
|
@@ -236,8 +240,6 @@ with _lang.auto_proxy_init(
|
|
|
236
240
|
)
|
|
237
241
|
|
|
238
242
|
from .content.materialize import ( # noqa
|
|
239
|
-
CanContent,
|
|
240
|
-
|
|
241
243
|
materialize_content,
|
|
242
244
|
)
|
|
243
245
|
|
|
@@ -275,6 +277,10 @@ with _lang.auto_proxy_init(
|
|
|
275
277
|
SequenceContent,
|
|
276
278
|
)
|
|
277
279
|
|
|
280
|
+
from .content.tag import ( # noqa
|
|
281
|
+
TagContent,
|
|
282
|
+
)
|
|
283
|
+
|
|
278
284
|
from .content.text import ( # noqa
|
|
279
285
|
TextContent,
|
|
280
286
|
)
|
|
@@ -391,6 +397,14 @@ with _lang.auto_proxy_init(
|
|
|
391
397
|
tool_context,
|
|
392
398
|
)
|
|
393
399
|
|
|
400
|
+
from .tools.execution.errorhandling import ( # noqa
|
|
401
|
+
ErrorHandlingToolExecutor,
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
from .tools.execution.errors import ( # noqa
|
|
405
|
+
ToolExecutionError,
|
|
406
|
+
)
|
|
407
|
+
|
|
394
408
|
from .tools.execution.executors import ( # noqa
|
|
395
409
|
ToolExecutor,
|
|
396
410
|
|
|
@@ -403,10 +417,6 @@ with _lang.auto_proxy_init(
|
|
|
403
417
|
reflect_tool_catalog_entry,
|
|
404
418
|
)
|
|
405
419
|
|
|
406
|
-
from .tools.execution.errors import ( # noqa
|
|
407
|
-
ToolExecutionError,
|
|
408
|
-
)
|
|
409
|
-
|
|
410
420
|
from .tools.fns import ( # noqa
|
|
411
421
|
ToolFn,
|
|
412
422
|
|