ommlds 0.0.0.dev480__py3-none-any.whl → 0.0.0.dev503__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/.omlish-manifests.json +100 -33
- ommlds/README.md +11 -0
- ommlds/__about__.py +9 -6
- ommlds/backends/anthropic/protocol/__init__.py +13 -1
- ommlds/backends/anthropic/protocol/_dataclasses.py +1625 -0
- ommlds/backends/anthropic/protocol/sse/events.py +2 -0
- ommlds/backends/cerebras/__init__.py +7 -0
- ommlds/backends/cerebras/_dataclasses.py +4254 -0
- ommlds/backends/cerebras/_marshal.py +24 -0
- ommlds/backends/cerebras/protocol.py +312 -0
- ommlds/backends/google/protocol/__init__.py +13 -0
- ommlds/backends/google/protocol/_dataclasses.py +5997 -0
- ommlds/backends/groq/__init__.py +7 -0
- ommlds/backends/groq/_dataclasses.py +3901 -0
- ommlds/backends/groq/clients.py +9 -0
- ommlds/backends/llamacpp/logging.py +4 -1
- ommlds/backends/mlx/caching.py +7 -3
- ommlds/backends/mlx/cli.py +10 -7
- ommlds/backends/mlx/generation.py +18 -16
- ommlds/backends/mlx/limits.py +10 -6
- ommlds/backends/mlx/loading.py +7 -4
- ommlds/backends/ollama/__init__.py +7 -0
- ommlds/backends/ollama/_dataclasses.py +3488 -0
- ommlds/backends/ollama/protocol.py +3 -0
- ommlds/backends/openai/protocol/__init__.py +15 -1
- ommlds/backends/openai/protocol/_dataclasses.py +7708 -0
- ommlds/backends/tavily/__init__.py +7 -0
- ommlds/backends/tavily/_dataclasses.py +1734 -0
- ommlds/backends/transformers/__init__.py +14 -0
- ommlds/cli/__init__.py +7 -0
- ommlds/cli/_dataclasses.py +3515 -0
- ommlds/cli/backends/catalog.py +0 -5
- ommlds/cli/backends/inject.py +70 -7
- ommlds/cli/backends/meta.py +82 -0
- ommlds/cli/content/messages.py +1 -1
- ommlds/cli/inject.py +11 -3
- ommlds/cli/main.py +137 -68
- ommlds/cli/rendering/types.py +6 -0
- ommlds/cli/secrets.py +2 -1
- ommlds/cli/sessions/base.py +1 -10
- ommlds/cli/sessions/chat/configs.py +9 -17
- ommlds/cli/sessions/chat/{chat → drivers}/ai/configs.py +3 -1
- ommlds/cli/sessions/chat/drivers/ai/events.py +57 -0
- ommlds/cli/sessions/chat/{chat → drivers}/ai/inject.py +10 -3
- ommlds/cli/sessions/chat/{chat → drivers}/ai/rendering.py +1 -1
- ommlds/cli/sessions/chat/{chat → drivers}/ai/services.py +1 -1
- ommlds/cli/sessions/chat/{chat → drivers}/ai/tools.py +4 -8
- ommlds/cli/sessions/chat/{chat → drivers}/ai/types.py +9 -0
- ommlds/cli/sessions/chat/drivers/configs.py +25 -0
- ommlds/cli/sessions/chat/drivers/events/inject.py +27 -0
- ommlds/cli/sessions/chat/drivers/events/injection.py +14 -0
- ommlds/cli/sessions/chat/drivers/events/manager.py +16 -0
- ommlds/cli/sessions/chat/drivers/events/types.py +38 -0
- ommlds/cli/sessions/chat/drivers/impl.py +50 -0
- ommlds/cli/sessions/chat/drivers/inject.py +70 -0
- ommlds/cli/sessions/chat/{chat → drivers}/state/configs.py +2 -0
- ommlds/cli/sessions/chat/drivers/state/ids.py +25 -0
- ommlds/cli/sessions/chat/drivers/state/inject.py +83 -0
- ommlds/cli/sessions/chat/{chat → drivers}/state/inmemory.py +0 -4
- ommlds/cli/sessions/chat/{chat → drivers}/state/storage.py +17 -10
- ommlds/cli/sessions/chat/{chat → drivers}/state/types.py +10 -5
- ommlds/cli/sessions/chat/{tools → drivers/tools}/configs.py +2 -2
- ommlds/cli/sessions/chat/drivers/tools/confirmation.py +44 -0
- ommlds/cli/sessions/chat/drivers/tools/errorhandling.py +39 -0
- ommlds/cli/sessions/chat/{tools → drivers/tools}/execution.py +3 -4
- ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/inject.py +3 -3
- ommlds/cli/sessions/chat/{tools → drivers/tools}/inject.py +7 -12
- ommlds/cli/sessions/chat/{tools → drivers/tools}/injection.py +5 -5
- ommlds/cli/sessions/chat/{tools → drivers/tools}/rendering.py +3 -3
- ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/inject.py +3 -3
- ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/tools.py +1 -1
- ommlds/cli/sessions/chat/drivers/types.py +31 -0
- ommlds/cli/sessions/chat/{chat → drivers}/user/configs.py +0 -3
- ommlds/cli/sessions/chat/drivers/user/inject.py +41 -0
- ommlds/cli/sessions/chat/facades/__init__.py +0 -0
- ommlds/cli/sessions/chat/facades/commands/__init__.py +0 -0
- ommlds/cli/sessions/chat/facades/commands/base.py +83 -0
- ommlds/cli/sessions/chat/facades/commands/configs.py +9 -0
- ommlds/cli/sessions/chat/facades/commands/inject.py +41 -0
- ommlds/cli/sessions/chat/facades/commands/injection.py +15 -0
- ommlds/cli/sessions/chat/facades/commands/manager.py +59 -0
- ommlds/cli/sessions/chat/facades/commands/simple.py +34 -0
- ommlds/cli/sessions/chat/facades/commands/types.py +13 -0
- ommlds/cli/sessions/chat/facades/configs.py +11 -0
- ommlds/cli/sessions/chat/facades/facade.py +26 -0
- ommlds/cli/sessions/chat/facades/inject.py +35 -0
- ommlds/cli/sessions/chat/facades/ui.py +34 -0
- ommlds/cli/sessions/chat/inject.py +8 -31
- ommlds/cli/sessions/chat/interfaces/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/bare/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/bare/configs.py +15 -0
- ommlds/cli/sessions/chat/interfaces/bare/inject.py +69 -0
- ommlds/cli/sessions/chat/interfaces/bare/interactive.py +49 -0
- ommlds/cli/sessions/chat/interfaces/bare/oneshot.py +21 -0
- ommlds/cli/sessions/chat/{tools/confirmation.py → interfaces/bare/tools.py} +3 -22
- ommlds/cli/sessions/chat/interfaces/base.py +13 -0
- ommlds/cli/sessions/chat/interfaces/configs.py +11 -0
- ommlds/cli/sessions/chat/interfaces/inject.py +29 -0
- ommlds/cli/sessions/chat/interfaces/textual/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/textual/app.py +310 -0
- ommlds/cli/sessions/chat/interfaces/textual/configs.py +11 -0
- ommlds/cli/sessions/chat/interfaces/textual/facades.py +19 -0
- ommlds/cli/sessions/chat/interfaces/textual/inject.py +97 -0
- ommlds/cli/sessions/chat/interfaces/textual/interface.py +24 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/__init__.py +29 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/input.tcss +53 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/markdown.tcss +7 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +157 -0
- ommlds/cli/sessions/chat/interfaces/textual/tools.py +38 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/input.py +36 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +197 -0
- ommlds/cli/sessions/chat/session.py +8 -13
- ommlds/cli/sessions/completion/configs.py +3 -4
- ommlds/cli/sessions/completion/inject.py +1 -2
- ommlds/cli/sessions/completion/session.py +4 -8
- ommlds/cli/sessions/configs.py +10 -0
- ommlds/cli/sessions/embedding/configs.py +3 -4
- ommlds/cli/sessions/embedding/inject.py +1 -2
- ommlds/cli/sessions/embedding/session.py +4 -8
- ommlds/cli/sessions/inject.py +15 -15
- ommlds/cli/state/storage.py +7 -1
- ommlds/minichain/__init__.py +161 -38
- ommlds/minichain/_dataclasses.py +20452 -0
- ommlds/minichain/_typedvalues.py +11 -4
- ommlds/minichain/backends/impls/anthropic/names.py +3 -3
- ommlds/minichain/backends/impls/anthropic/protocol.py +2 -2
- ommlds/minichain/backends/impls/anthropic/stream.py +1 -1
- ommlds/minichain/backends/impls/cerebras/__init__.py +0 -0
- ommlds/minichain/backends/impls/cerebras/chat.py +80 -0
- ommlds/minichain/backends/impls/cerebras/names.py +45 -0
- ommlds/minichain/backends/impls/cerebras/protocol.py +143 -0
- ommlds/minichain/backends/impls/cerebras/stream.py +125 -0
- ommlds/minichain/backends/impls/duckduckgo/search.py +5 -1
- ommlds/minichain/backends/impls/google/names.py +6 -0
- ommlds/minichain/backends/impls/google/stream.py +1 -1
- ommlds/minichain/backends/impls/google/tools.py +2 -2
- ommlds/minichain/backends/impls/groq/chat.py +2 -0
- ommlds/minichain/backends/impls/groq/protocol.py +2 -2
- ommlds/minichain/backends/impls/groq/stream.py +3 -1
- ommlds/minichain/backends/impls/huggingface/repos.py +1 -5
- ommlds/minichain/backends/impls/llamacpp/chat.py +6 -3
- ommlds/minichain/backends/impls/llamacpp/completion.py +7 -3
- ommlds/minichain/backends/impls/llamacpp/stream.py +6 -3
- ommlds/minichain/backends/impls/mlx/chat.py +6 -3
- ommlds/minichain/backends/impls/ollama/chat.py +51 -57
- ommlds/minichain/backends/impls/ollama/protocol.py +144 -0
- ommlds/minichain/backends/impls/openai/format.py +4 -3
- ommlds/minichain/backends/impls/openai/names.py +3 -1
- ommlds/minichain/backends/impls/openai/stream.py +33 -1
- ommlds/minichain/backends/impls/sentencepiece/tokens.py +9 -6
- ommlds/minichain/backends/impls/tinygrad/chat.py +7 -4
- ommlds/minichain/backends/impls/tokenizers/tokens.py +9 -6
- ommlds/minichain/backends/impls/transformers/sentence.py +5 -2
- ommlds/minichain/backends/impls/transformers/tokens.py +9 -6
- ommlds/minichain/backends/impls/transformers/transformers.py +10 -8
- ommlds/minichain/backends/strings/resolving.py +1 -1
- ommlds/minichain/chat/content.py +42 -0
- ommlds/minichain/chat/messages.py +43 -39
- ommlds/minichain/chat/stream/joining.py +36 -12
- ommlds/minichain/chat/stream/types.py +1 -1
- ommlds/minichain/chat/templating.py +3 -3
- ommlds/minichain/content/__init__.py +19 -3
- ommlds/minichain/content/_marshal.py +181 -55
- ommlds/minichain/content/code.py +26 -0
- ommlds/minichain/content/composite.py +28 -0
- ommlds/minichain/content/content.py +27 -0
- ommlds/minichain/content/dynamic.py +12 -0
- ommlds/minichain/content/emphasis.py +27 -0
- ommlds/minichain/content/images.py +2 -2
- ommlds/minichain/content/json.py +2 -2
- ommlds/minichain/content/link.py +13 -0
- ommlds/minichain/content/markdown.py +12 -0
- ommlds/minichain/content/metadata.py +10 -0
- ommlds/minichain/content/namespaces.py +8 -0
- ommlds/minichain/content/placeholders.py +10 -9
- ommlds/minichain/content/quote.py +26 -0
- ommlds/minichain/content/raw.py +49 -0
- ommlds/minichain/content/recursive.py +12 -0
- ommlds/minichain/content/section.py +26 -0
- ommlds/minichain/content/sequence.py +17 -3
- ommlds/minichain/content/standard.py +32 -0
- ommlds/minichain/content/tag.py +28 -0
- ommlds/minichain/content/templates.py +13 -0
- ommlds/minichain/content/text.py +2 -2
- ommlds/minichain/content/transform/__init__.py +0 -0
- ommlds/minichain/content/transform/json.py +55 -0
- ommlds/minichain/content/transform/markdown.py +8 -0
- ommlds/minichain/content/transform/materialize.py +51 -0
- ommlds/minichain/content/transform/metadata.py +16 -0
- ommlds/minichain/content/{prepare.py → transform/prepare.py} +10 -15
- ommlds/minichain/content/transform/recursive.py +97 -0
- ommlds/minichain/content/transform/standard.py +43 -0
- ommlds/minichain/content/{transforms → transform}/stringify.py +1 -7
- ommlds/minichain/content/transform/strings.py +33 -0
- ommlds/minichain/content/transform/templates.py +25 -0
- ommlds/minichain/content/visitors.py +231 -0
- 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/tools/write.py +2 -1
- ommlds/minichain/lib/todo/types.py +1 -1
- ommlds/minichain/metadata.py +56 -2
- ommlds/minichain/resources.py +22 -1
- ommlds/minichain/services/README.md +154 -0
- ommlds/minichain/services/__init__.py +6 -2
- ommlds/minichain/services/_marshal.py +46 -10
- ommlds/minichain/services/_origclasses.py +11 -0
- ommlds/minichain/services/_typedvalues.py +8 -3
- ommlds/minichain/services/requests.py +73 -3
- ommlds/minichain/services/responses.py +73 -3
- ommlds/minichain/services/services.py +9 -0
- ommlds/minichain/stream/services.py +24 -1
- 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/catalog.py +1 -1
- ommlds/minichain/tools/execution/errorhandling.py +36 -0
- ommlds/minichain/tools/execution/errors.py +2 -2
- ommlds/minichain/tools/execution/executors.py +1 -1
- ommlds/minichain/tools/fns.py +1 -1
- ommlds/minichain/tools/jsonschema.py +2 -2
- ommlds/minichain/tools/reflect.py +6 -6
- ommlds/minichain/tools/types.py +12 -15
- ommlds/minichain/vectors/_marshal.py +1 -1
- ommlds/minichain/vectors/embeddings.py +1 -1
- ommlds/minichain/wrappers/__init__.py +7 -0
- ommlds/minichain/wrappers/firstinwins.py +144 -0
- ommlds/minichain/wrappers/instrument.py +146 -0
- ommlds/minichain/wrappers/retry.py +168 -0
- ommlds/minichain/wrappers/services.py +98 -0
- ommlds/minichain/wrappers/stream.py +57 -0
- ommlds/nanochat/rustbpe/README.md +9 -0
- ommlds/nanochat/tokenizers.py +40 -6
- ommlds/specs/mcp/clients.py +146 -0
- ommlds/specs/mcp/protocol.py +123 -18
- ommlds/tools/git.py +82 -65
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/METADATA +13 -11
- ommlds-0.0.0.dev503.dist-info/RECORD +520 -0
- ommlds/cli/sessions/chat/chat/state/inject.py +0 -36
- ommlds/cli/sessions/chat/chat/user/inject.py +0 -62
- ommlds/cli/sessions/chat/chat/user/interactive.py +0 -31
- ommlds/cli/sessions/chat/chat/user/oneshot.py +0 -25
- ommlds/cli/sessions/chat/chat/user/types.py +0 -15
- ommlds/cli/sessions/chat/driver.py +0 -43
- ommlds/minichain/content/materialize.py +0 -196
- ommlds/minichain/content/simple.py +0 -47
- ommlds/minichain/content/transforms/base.py +0 -46
- ommlds/minichain/content/transforms/interleave.py +0 -70
- ommlds/minichain/content/transforms/squeeze.py +0 -72
- ommlds/minichain/content/transforms/strings.py +0 -24
- ommlds/minichain/content/types.py +0 -43
- ommlds/minichain/stream/wrap.py +0 -62
- ommlds-0.0.0.dev480.dist-info/RECORD +0 -427
- /ommlds/cli/sessions/chat/{chat → drivers}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat → drivers}/ai/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat → drivers}/ai/injection.py +0 -0
- /ommlds/cli/sessions/chat/{chat/state → drivers/events}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat/user → drivers/phases}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/inject.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/injection.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/manager.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/types.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/state}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/configs.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/configs.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/configs.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/inject.py +0 -0
- /ommlds/{minichain/content/transforms → cli/sessions/chat/drivers/user}/__init__.py +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from omlish.formats import json
|
|
2
|
+
|
|
3
|
+
from ...... import minichain as mc
|
|
4
|
+
from ...drivers.tools.confirmation import ToolExecutionConfirmation
|
|
5
|
+
from ...drivers.tools.confirmation import ToolExecutionRequestDeniedError
|
|
6
|
+
from .app import ChatAppGetter
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ChatAppToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
app: ChatAppGetter,
|
|
17
|
+
) -> None:
|
|
18
|
+
super().__init__()
|
|
19
|
+
|
|
20
|
+
self._app = app
|
|
21
|
+
|
|
22
|
+
async def confirm_tool_execution_or_raise(
|
|
23
|
+
self,
|
|
24
|
+
use: 'mc.ToolUse',
|
|
25
|
+
entry: 'mc.ToolCatalogEntry',
|
|
26
|
+
) -> None:
|
|
27
|
+
tr_dct = dict(
|
|
28
|
+
id=use.id,
|
|
29
|
+
name=entry.spec.name,
|
|
30
|
+
args=use.args,
|
|
31
|
+
# spec=msh.marshal(tce.spec),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
if not await (await self._app()).confirm_tool_use(
|
|
35
|
+
'Execute requested tool?',
|
|
36
|
+
json.dumps_pretty(tr_dct),
|
|
37
|
+
):
|
|
38
|
+
raise ToolExecutionRequestDeniedError
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import dataclasses as dc
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from omdev.tui import textual as tx
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class InputTextArea(tx.TextArea):
|
|
11
|
+
@dc.dataclass()
|
|
12
|
+
class Submitted(tx.Message):
|
|
13
|
+
text: str
|
|
14
|
+
|
|
15
|
+
def __init__(self, **kwargs: ta.Any) -> None:
|
|
16
|
+
super().__init__(**kwargs)
|
|
17
|
+
|
|
18
|
+
async def _on_key(self, event: tx.Key) -> None:
|
|
19
|
+
if event.key == 'enter':
|
|
20
|
+
event.prevent_default()
|
|
21
|
+
event.stop()
|
|
22
|
+
|
|
23
|
+
if text := self.text.strip():
|
|
24
|
+
self.post_message(self.Submitted(text))
|
|
25
|
+
|
|
26
|
+
else:
|
|
27
|
+
await super()._on_key(event)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class InputOuter(tx.Static):
|
|
31
|
+
def compose(self) -> tx.ComposeResult:
|
|
32
|
+
with tx.Vertical(id='input-vertical'):
|
|
33
|
+
with tx.Vertical(id='input-vertical2'):
|
|
34
|
+
with tx.Horizontal(id='input-horizontal'):
|
|
35
|
+
yield tx.Static('>', id='input-glyph')
|
|
36
|
+
yield InputTextArea(placeholder='...', id='input')
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import asyncio
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
from omdev.tui import textual as tx
|
|
6
|
+
from omlish import lang
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MessagesContainer(tx.VerticalScroll):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Message(tx.Static, lang.Abstract):
|
|
20
|
+
def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
|
|
21
|
+
super().__init__(*args, **kwargs)
|
|
22
|
+
|
|
23
|
+
self.add_class('message')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class WelcomeMessage(Message):
|
|
30
|
+
def __init__(self, content: str) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
|
|
33
|
+
self.add_class('welcome-message')
|
|
34
|
+
|
|
35
|
+
self._content = content
|
|
36
|
+
|
|
37
|
+
def compose(self) -> tx.ComposeResult:
|
|
38
|
+
with tx.Vertical(classes='welcome-message-outer message-outer'):
|
|
39
|
+
yield tx.Static(self._content, classes='welcome-message-content')
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
#
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class UserMessage(Message):
|
|
46
|
+
def __init__(self, content: str) -> None:
|
|
47
|
+
super().__init__()
|
|
48
|
+
|
|
49
|
+
self.add_class('user-message')
|
|
50
|
+
|
|
51
|
+
self._content = content
|
|
52
|
+
|
|
53
|
+
def compose(self) -> tx.ComposeResult:
|
|
54
|
+
with tx.Horizontal(classes='user-message-outer message-outer'):
|
|
55
|
+
yield tx.Static('> ', classes='user-message-glyph message-glyph')
|
|
56
|
+
with tx.Vertical(classes='user-message-inner message-inner'):
|
|
57
|
+
yield tx.Static(self._content)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class AiMessage(Message, lang.Abstract):
|
|
64
|
+
def __init__(self) -> None:
|
|
65
|
+
super().__init__()
|
|
66
|
+
|
|
67
|
+
self.add_class('ai-message')
|
|
68
|
+
|
|
69
|
+
def compose(self) -> tx.ComposeResult:
|
|
70
|
+
with tx.Horizontal(classes='ai-message-outer message-outer'):
|
|
71
|
+
yield tx.Static('< ', classes='ai-message-glyph message-glyph')
|
|
72
|
+
with tx.Vertical(classes='ai-message-inner message-inner'):
|
|
73
|
+
yield from self._compose_content()
|
|
74
|
+
|
|
75
|
+
@abc.abstractmethod
|
|
76
|
+
def _compose_content(self) -> ta.Generator:
|
|
77
|
+
raise NotImplementedError
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class StaticAiMessage(AiMessage):
|
|
81
|
+
def __init__(
|
|
82
|
+
self,
|
|
83
|
+
content: str,
|
|
84
|
+
*,
|
|
85
|
+
markdown: bool = False,
|
|
86
|
+
) -> None:
|
|
87
|
+
super().__init__()
|
|
88
|
+
|
|
89
|
+
self._content = content
|
|
90
|
+
self._markdown = markdown
|
|
91
|
+
|
|
92
|
+
def _compose_content(self) -> ta.Generator:
|
|
93
|
+
if self._markdown:
|
|
94
|
+
yield tx.Markdown(self._content)
|
|
95
|
+
else:
|
|
96
|
+
yield tx.Static(self._content)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class StreamAiMessage(AiMessage):
|
|
100
|
+
def __init__(self, content: str) -> None:
|
|
101
|
+
super().__init__()
|
|
102
|
+
|
|
103
|
+
self._content = content
|
|
104
|
+
|
|
105
|
+
def _compose_content(self) -> ta.Generator:
|
|
106
|
+
yield tx.Markdown('')
|
|
107
|
+
|
|
108
|
+
_stream_: tx.MarkdownStream | None = None
|
|
109
|
+
|
|
110
|
+
def _stream(self) -> tx.MarkdownStream:
|
|
111
|
+
if self._stream_ is None:
|
|
112
|
+
self._stream_ = tx.Markdown.get_stream(self.query_one(tx.Markdown))
|
|
113
|
+
return self._stream_
|
|
114
|
+
|
|
115
|
+
async def write_initial_content(self) -> None:
|
|
116
|
+
if self._content:
|
|
117
|
+
await self._stream().write(self._content)
|
|
118
|
+
|
|
119
|
+
async def append_content(self, content: str) -> None:
|
|
120
|
+
if not content:
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
self._content += content
|
|
124
|
+
await self._stream().write(content)
|
|
125
|
+
|
|
126
|
+
async def stop_stream(self) -> None:
|
|
127
|
+
if (stream := self._stream_) is None:
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
await stream.stop()
|
|
131
|
+
self._stream_ = None
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
#
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class ToolConfirmationControls(tx.Static):
|
|
138
|
+
class Allowed(tx.Message):
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
def compose(self) -> tx.ComposeResult:
|
|
142
|
+
yield tx.Button('Allow', action='allow')
|
|
143
|
+
|
|
144
|
+
def action_allow(self) -> None:
|
|
145
|
+
self.post_message(self.Allowed())
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class ToolConfirmationMessage(Message):
|
|
149
|
+
def __init__(
|
|
150
|
+
self,
|
|
151
|
+
outer_content: str,
|
|
152
|
+
inner_content: str,
|
|
153
|
+
fut: asyncio.Future[bool],
|
|
154
|
+
) -> None:
|
|
155
|
+
super().__init__()
|
|
156
|
+
|
|
157
|
+
self.add_class('tool-confirmation-message')
|
|
158
|
+
|
|
159
|
+
self._outer_content = outer_content
|
|
160
|
+
self._inner_content = inner_content
|
|
161
|
+
self._fut = fut
|
|
162
|
+
|
|
163
|
+
def compose(self) -> tx.ComposeResult:
|
|
164
|
+
with tx.Horizontal(classes='tool-confirmation-message-outer message-outer'):
|
|
165
|
+
yield tx.Static('? ', classes='tool-confirmation-message-glyph message-glyph')
|
|
166
|
+
with tx.Vertical(classes='tool-confirmation-message-inner tool-confirmation-message-inner-open message-inner'): # noqa
|
|
167
|
+
yield tx.Static(self._outer_content, classes='tool-confirmation-message-outer-content')
|
|
168
|
+
yield tx.Static(self._inner_content, classes='tool-confirmation-message-inner-content')
|
|
169
|
+
yield ToolConfirmationControls(classes='tool-confirmation-message-controls')
|
|
170
|
+
|
|
171
|
+
@tx.on(ToolConfirmationControls.Allowed)
|
|
172
|
+
async def on_allowed(self, event: ToolConfirmationControls.Allowed) -> None:
|
|
173
|
+
inner = self.query_one(tx.Vertical)
|
|
174
|
+
await inner.query_one(ToolConfirmationControls).remove()
|
|
175
|
+
inner.remove_class('tool-confirmation-message-inner-open')
|
|
176
|
+
inner.add_class('tool-confirmation-message-inner-closed')
|
|
177
|
+
inner.query_one('.tool-confirmation-message-outer-content', tx.Static).update('Tool use confirmed.')
|
|
178
|
+
|
|
179
|
+
self._fut.set_result(True)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
#
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class UiMessage(Message):
|
|
186
|
+
def __init__(self, content: str) -> None:
|
|
187
|
+
super().__init__()
|
|
188
|
+
|
|
189
|
+
self.add_class('ui-message')
|
|
190
|
+
|
|
191
|
+
self._content = content
|
|
192
|
+
|
|
193
|
+
def compose(self) -> tx.ComposeResult:
|
|
194
|
+
with tx.Horizontal(classes='ui-message-outer message-outer'):
|
|
195
|
+
yield tx.Static('~ ', classes='ui-message-glyph message-glyph')
|
|
196
|
+
with tx.Vertical(classes='ui-message-inner message-inner'):
|
|
197
|
+
yield tx.Static(self._content)
|
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
import typing as ta
|
|
2
2
|
|
|
3
3
|
from ..base import Session
|
|
4
|
-
from .
|
|
5
|
-
from .driver import ChatDriver
|
|
4
|
+
from .interfaces.base import ChatInterface
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
##
|
|
9
8
|
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Config(Session.Config, ChatConfig):
|
|
14
|
-
pass
|
|
15
|
-
|
|
10
|
+
@ta.final
|
|
11
|
+
class ChatSession(Session):
|
|
16
12
|
def __init__(
|
|
17
13
|
self,
|
|
18
|
-
config: Config,
|
|
19
14
|
*,
|
|
20
|
-
|
|
15
|
+
interface: ChatInterface,
|
|
21
16
|
) -> None:
|
|
22
|
-
super().__init__(
|
|
17
|
+
super().__init__()
|
|
23
18
|
|
|
24
|
-
self.
|
|
19
|
+
self._interface = interface
|
|
25
20
|
|
|
26
21
|
async def run(self) -> None:
|
|
27
|
-
await self.
|
|
22
|
+
await self._interface.run()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from omlish import dataclasses as dc
|
|
2
2
|
|
|
3
3
|
from .... import minichain as mc
|
|
4
|
+
from ..configs import SessionConfig
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
##
|
|
@@ -12,10 +13,8 @@ DEFAULT_BACKEND = 'openai'
|
|
|
12
13
|
##
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
@dc.dataclass(frozen=True)
|
|
16
|
-
class CompletionConfig:
|
|
16
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
17
|
+
class CompletionConfig(SessionConfig):
|
|
17
18
|
content: 'mc.Content'
|
|
18
19
|
|
|
19
|
-
_: dc.KW_ONLY
|
|
20
|
-
|
|
21
20
|
backend: str | None = None
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from omlish import dataclasses as dc
|
|
2
1
|
from omlish import inject as inj
|
|
3
2
|
from omlish import lang
|
|
4
3
|
|
|
@@ -23,7 +22,7 @@ def bind_completion(cfg: CompletionConfig) -> inj.Elements:
|
|
|
23
22
|
#
|
|
24
23
|
|
|
25
24
|
els.extend([
|
|
26
|
-
inj.bind(
|
|
25
|
+
inj.bind(cfg),
|
|
27
26
|
inj.bind(Session, to_ctor=_session.CompletionSession, singleton=True),
|
|
28
27
|
])
|
|
29
28
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from omlish import check
|
|
2
|
-
from omlish import dataclasses as dc
|
|
3
2
|
|
|
4
3
|
from .... import minichain as mc
|
|
5
4
|
from ...backends.types import CompletionServiceBackendProvider
|
|
@@ -10,19 +9,16 @@ from .configs import CompletionConfig
|
|
|
10
9
|
##
|
|
11
10
|
|
|
12
11
|
|
|
13
|
-
class CompletionSession(Session
|
|
14
|
-
@dc.dataclass(frozen=True)
|
|
15
|
-
class Config(Session.Config, CompletionConfig):
|
|
16
|
-
pass
|
|
17
|
-
|
|
12
|
+
class CompletionSession(Session):
|
|
18
13
|
def __init__(
|
|
19
14
|
self,
|
|
20
|
-
config:
|
|
15
|
+
config: CompletionConfig,
|
|
21
16
|
*,
|
|
22
17
|
service_provider: CompletionServiceBackendProvider,
|
|
23
18
|
) -> None:
|
|
24
|
-
super().__init__(
|
|
19
|
+
super().__init__()
|
|
25
20
|
|
|
21
|
+
self._config = config
|
|
26
22
|
self._service_provider = service_provider
|
|
27
23
|
|
|
28
24
|
async def run(self) -> None:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from omlish import dataclasses as dc
|
|
2
2
|
|
|
3
3
|
from .... import minichain as mc
|
|
4
|
+
from ..configs import SessionConfig
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
##
|
|
@@ -12,10 +13,8 @@ DEFAULT_BACKEND = 'openai'
|
|
|
12
13
|
##
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
@dc.dataclass(frozen=True)
|
|
16
|
-
class EmbeddingConfig:
|
|
16
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
17
|
+
class EmbeddingConfig(SessionConfig):
|
|
17
18
|
content: 'mc.Content'
|
|
18
19
|
|
|
19
|
-
_: dc.KW_ONLY
|
|
20
|
-
|
|
21
20
|
backend: str | None = None
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from omlish import dataclasses as dc
|
|
2
1
|
from omlish import inject as inj
|
|
3
2
|
from omlish import lang
|
|
4
3
|
|
|
@@ -23,7 +22,7 @@ def bind_embedding(cfg: EmbeddingConfig) -> inj.Elements:
|
|
|
23
22
|
#
|
|
24
23
|
|
|
25
24
|
els.extend([
|
|
26
|
-
inj.bind(
|
|
25
|
+
inj.bind(cfg),
|
|
27
26
|
inj.bind(Session, to_ctor=_session.EmbeddingSession, singleton=True),
|
|
28
27
|
])
|
|
29
28
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from omlish import dataclasses as dc
|
|
2
1
|
from omlish.formats import json
|
|
3
2
|
|
|
4
3
|
from .... import minichain as mc
|
|
@@ -10,19 +9,16 @@ from .configs import EmbeddingConfig
|
|
|
10
9
|
##
|
|
11
10
|
|
|
12
11
|
|
|
13
|
-
class EmbeddingSession(Session
|
|
14
|
-
@dc.dataclass(frozen=True)
|
|
15
|
-
class Config(Session.Config, EmbeddingConfig):
|
|
16
|
-
pass
|
|
17
|
-
|
|
12
|
+
class EmbeddingSession(Session):
|
|
18
13
|
def __init__(
|
|
19
14
|
self,
|
|
20
|
-
config:
|
|
15
|
+
config: EmbeddingConfig,
|
|
21
16
|
*,
|
|
22
17
|
service_provider: EmbeddingServiceBackendProvider,
|
|
23
18
|
) -> None:
|
|
24
|
-
super().__init__(
|
|
19
|
+
super().__init__()
|
|
25
20
|
|
|
21
|
+
self._config = config
|
|
26
22
|
self._service_provider = service_provider
|
|
27
23
|
|
|
28
24
|
async def run(self) -> None:
|
ommlds/cli/sessions/inject.py
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
1
|
from omlish import inject as inj
|
|
4
2
|
from omlish import lang
|
|
5
3
|
|
|
4
|
+
from .chat.configs import ChatConfig
|
|
5
|
+
from .completion.configs import CompletionConfig
|
|
6
|
+
from .configs import SessionConfig
|
|
7
|
+
from .embedding.configs import EmbeddingConfig
|
|
8
|
+
|
|
6
9
|
|
|
7
10
|
with lang.auto_proxy_import(globals()):
|
|
8
|
-
from .chat import
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
11
|
-
from .completion import inject as _completion_inj
|
|
12
|
-
from .embedding import configs as _embedding_cfgs
|
|
13
|
-
from .embedding import inject as _embedding_inj
|
|
11
|
+
from .chat import inject as _chat
|
|
12
|
+
from .completion import inject as _completion
|
|
13
|
+
from .embedding import inject as _embedding
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
##
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def bind_sessions(cfg:
|
|
19
|
+
def bind_sessions(cfg: SessionConfig) -> inj.Elements:
|
|
20
20
|
els: list[inj.Elemental] = []
|
|
21
21
|
|
|
22
22
|
#
|
|
23
23
|
|
|
24
|
-
if isinstance(cfg,
|
|
25
|
-
els.append(
|
|
24
|
+
if isinstance(cfg, ChatConfig):
|
|
25
|
+
els.append(_chat.bind_chat(cfg))
|
|
26
26
|
|
|
27
|
-
elif isinstance(cfg,
|
|
28
|
-
els.append(
|
|
27
|
+
elif isinstance(cfg, CompletionConfig):
|
|
28
|
+
els.append(_completion.bind_completion(cfg))
|
|
29
29
|
|
|
30
|
-
elif isinstance(cfg,
|
|
31
|
-
els.append(
|
|
30
|
+
elif isinstance(cfg, EmbeddingConfig):
|
|
31
|
+
els.append(_embedding.bind_embedding(cfg))
|
|
32
32
|
|
|
33
33
|
else:
|
|
34
34
|
raise TypeError(cfg)
|
ommlds/cli/state/storage.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import abc
|
|
2
|
+
import datetime
|
|
2
3
|
import os.path
|
|
3
4
|
import typing as ta
|
|
4
5
|
|
|
@@ -52,8 +53,12 @@ STATE_VERSION = 0
|
|
|
52
53
|
@dc.dataclass(frozen=True)
|
|
53
54
|
class MarshaledState:
|
|
54
55
|
version: int
|
|
56
|
+
|
|
55
57
|
payload: ta.Any
|
|
56
58
|
|
|
59
|
+
created_at: datetime.datetime | None = dc.field(default_factory=lang.utcnow)
|
|
60
|
+
updated_at: datetime.datetime | None = dc.field(default_factory=lang.utcnow)
|
|
61
|
+
|
|
57
62
|
|
|
58
63
|
class MarshalStateStorage(StateStorage, lang.Abstract):
|
|
59
64
|
def __init__(
|
|
@@ -75,6 +80,7 @@ class MarshalStateStorage(StateStorage, lang.Abstract):
|
|
|
75
80
|
ms = MarshaledState(
|
|
76
81
|
version=self._version,
|
|
77
82
|
payload=msh.marshal(obj, ty),
|
|
83
|
+
updated_at=lang.utcnow(),
|
|
78
84
|
)
|
|
79
85
|
return msh.marshal(ms)
|
|
80
86
|
|
|
@@ -102,7 +108,7 @@ class JsonFileStateStorage(MarshalStateStorage):
|
|
|
102
108
|
return json.loads(data)
|
|
103
109
|
|
|
104
110
|
def _save_file_data(self, data: ta.Any) -> None:
|
|
105
|
-
data = json.
|
|
111
|
+
data = json.dumps_compact(data)
|
|
106
112
|
with open(self._file, 'w') as f:
|
|
107
113
|
f.write(data)
|
|
108
114
|
|