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
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import datetime
|
|
3
3
|
import typing as ta
|
|
4
|
+
import uuid
|
|
4
5
|
|
|
5
6
|
from omlish import dataclasses as dc
|
|
6
7
|
from omlish import lang
|
|
8
|
+
from omlish import typedvalues as tv
|
|
7
9
|
|
|
8
10
|
from ...... import minichain as mc
|
|
9
11
|
|
|
@@ -11,6 +13,13 @@ from ...... import minichain as mc
|
|
|
11
13
|
##
|
|
12
14
|
|
|
13
15
|
|
|
16
|
+
class ChatId(tv.UniqueScalarTypedValue[uuid.UUID]):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
|
|
22
|
+
|
|
14
23
|
@dc.dataclass(frozen=True)
|
|
15
24
|
class ChatState:
|
|
16
25
|
name: str | None = None
|
|
@@ -18,7 +27,7 @@ class ChatState:
|
|
|
18
27
|
created_at: datetime.datetime = dc.field(default_factory=lang.utcnow)
|
|
19
28
|
updated_at: datetime.datetime = dc.field(default_factory=lang.utcnow)
|
|
20
29
|
|
|
21
|
-
chat: mc.Chat = ()
|
|
30
|
+
chat: 'mc.Chat' = ()
|
|
22
31
|
|
|
23
32
|
|
|
24
33
|
##
|
|
@@ -29,10 +38,6 @@ class ChatStateManager(lang.Abstract):
|
|
|
29
38
|
def get_state(self) -> ta.Awaitable[ChatState]:
|
|
30
39
|
raise NotImplementedError
|
|
31
40
|
|
|
32
|
-
@abc.abstractmethod
|
|
33
|
-
def clear_state(self) -> ta.Awaitable[ChatState]:
|
|
34
|
-
raise NotImplementedError
|
|
35
|
-
|
|
36
41
|
@abc.abstractmethod
|
|
37
42
|
def extend_chat(self, chat_additions: 'mc.Chat') -> ta.Awaitable[ChatState]:
|
|
38
43
|
raise NotImplementedError
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from omlish import lang
|
|
5
|
+
|
|
6
|
+
from ...... import minichain as mc
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ToolExecutionRequestDeniedError(Exception):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ToolExecutionConfirmation(lang.Abstract):
|
|
17
|
+
@abc.abstractmethod
|
|
18
|
+
def confirm_tool_execution_or_raise(
|
|
19
|
+
self,
|
|
20
|
+
use: 'mc.ToolUse',
|
|
21
|
+
entry: 'mc.ToolCatalogEntry',
|
|
22
|
+
) -> ta.Awaitable[None]:
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class AlwaysDenyToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
30
|
+
async def confirm_tool_execution_or_raise(
|
|
31
|
+
self,
|
|
32
|
+
use: 'mc.ToolUse',
|
|
33
|
+
entry: 'mc.ToolCatalogEntry',
|
|
34
|
+
) -> None:
|
|
35
|
+
raise ToolExecutionRequestDeniedError
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class UnsafeAlwaysAllowToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
39
|
+
async def confirm_tool_execution_or_raise(
|
|
40
|
+
self,
|
|
41
|
+
use: 'mc.ToolUse',
|
|
42
|
+
entry: 'mc.ToolCatalogEntry',
|
|
43
|
+
) -> None:
|
|
44
|
+
pass
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
|
|
5
|
+
from ...... import minichain as mc
|
|
6
|
+
from .execution import ToolUseExecutor
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ErrorHandlingToolUseExecutor(ToolUseExecutor):
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
wrapped: ToolUseExecutor,
|
|
17
|
+
) -> None:
|
|
18
|
+
super().__init__()
|
|
19
|
+
|
|
20
|
+
self._wrapped = wrapped
|
|
21
|
+
|
|
22
|
+
async def execute_tool_use(
|
|
23
|
+
self,
|
|
24
|
+
use: 'mc.ToolUse',
|
|
25
|
+
*ctx_items: ta.Any,
|
|
26
|
+
) -> 'mc.ToolUseResultMessage':
|
|
27
|
+
try:
|
|
28
|
+
return await self._wrapped.execute_tool_use(use, *ctx_items)
|
|
29
|
+
|
|
30
|
+
except mc.ToolExecutionError as txe: # noqa
|
|
31
|
+
s = check.non_empty_str(check.isinstance(txe.content, str))
|
|
32
|
+
|
|
33
|
+
return mc.ToolUseResultMessage(
|
|
34
|
+
mc.ToolUseResult(
|
|
35
|
+
id=use.id,
|
|
36
|
+
name=use.name,
|
|
37
|
+
c=s,
|
|
38
|
+
),
|
|
39
|
+
)
|
|
@@ -4,7 +4,7 @@ import typing as ta
|
|
|
4
4
|
from omlish import check
|
|
5
5
|
from omlish import lang
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from ...... import minichain as mc
|
|
8
8
|
from .confirmation import ToolExecutionConfirmation
|
|
9
9
|
|
|
10
10
|
|
|
@@ -37,7 +37,7 @@ class ToolUseExecutorImpl(ToolUseExecutor):
|
|
|
37
37
|
*,
|
|
38
38
|
catalog: 'mc.ToolCatalog',
|
|
39
39
|
ctx_provider: ToolContextProvider,
|
|
40
|
-
confirmation: ToolExecutionConfirmation
|
|
40
|
+
confirmation: ToolExecutionConfirmation,
|
|
41
41
|
) -> None:
|
|
42
42
|
super().__init__()
|
|
43
43
|
|
|
@@ -52,8 +52,7 @@ class ToolUseExecutorImpl(ToolUseExecutor):
|
|
|
52
52
|
) -> 'mc.ToolUseResultMessage':
|
|
53
53
|
tce = self._catalog.by_name[check.non_empty_str(use.name)]
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
await self._confirmation.confirm_tool_execution_or_raise(use, tce)
|
|
55
|
+
await self._confirmation.confirm_tool_execution_or_raise(use, tce)
|
|
57
56
|
|
|
58
57
|
return await mc.execute_tool_use(
|
|
59
58
|
mc.ToolContext(
|
|
@@ -12,9 +12,9 @@ from .configs import FsToolSetConfig
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def bind_fs_tools(cfg: FsToolSetConfig) -> inj.Elements:
|
|
15
|
-
from
|
|
16
|
-
from
|
|
17
|
-
from
|
|
15
|
+
from .......minichain.lib.fs.context import FsContext
|
|
16
|
+
from .......minichain.lib.fs.tools.ls import ls_tool
|
|
17
|
+
from .......minichain.lib.fs.tools.read import read_tool
|
|
18
18
|
|
|
19
19
|
return inj.as_elements(
|
|
20
20
|
tool_catalog_entries().bind_item_consts(
|
|
@@ -2,15 +2,15 @@ from omlish import check
|
|
|
2
2
|
from omlish import inject as inj
|
|
3
3
|
from omlish import lang
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from ...... import minichain as mc
|
|
6
|
+
from ..configs import ToolsConfig
|
|
7
7
|
from .injection import ToolSetBinder
|
|
8
8
|
from .injection import tool_catalog_entries
|
|
9
9
|
from .injection import tool_context_providers
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
with lang.auto_proxy_import(globals()):
|
|
13
|
-
from . import
|
|
13
|
+
from . import errorhandling as _errorhandling
|
|
14
14
|
from . import execution as _execution
|
|
15
15
|
from . import rendering as _rendering
|
|
16
16
|
|
|
@@ -58,11 +58,11 @@ def bind_tools(cfg: ToolsConfig = ToolsConfig()) -> inj.Elements:
|
|
|
58
58
|
|
|
59
59
|
els.append(exec_stack.push_bind(to_ctor=_execution.ToolUseExecutorImpl, singleton=True))
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
els.append(exec_stack.push_bind(to_ctor=_rendering.ResultRenderingToolUseExecutor, singleton=True))
|
|
61
|
+
els.append(exec_stack.push_bind(to_ctor=_errorhandling.ErrorHandlingToolUseExecutor, singleton=True))
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if cfg.verbose:
|
|
64
|
+
els.append(exec_stack.push_bind(to_ctor=_rendering.ArgsRenderingToolUseExecutor, singleton=True))
|
|
65
|
+
els.append(exec_stack.push_bind(to_ctor=_rendering.ResultRenderingToolUseExecutor, singleton=True))
|
|
66
66
|
|
|
67
67
|
els.extend([
|
|
68
68
|
inj.bind(_execution.ToolUseExecutor, to_key=exec_stack.top),
|
|
@@ -70,11 +70,6 @@ def bind_tools(cfg: ToolsConfig = ToolsConfig()) -> inj.Elements:
|
|
|
70
70
|
|
|
71
71
|
#
|
|
72
72
|
|
|
73
|
-
if not cfg.dangerous_no_confirmation:
|
|
74
|
-
els.append(inj.bind(_confirmation.ToolExecutionConfirmation, to_ctor=_confirmation.InteractiveToolExecutionConfirmation, singleton=True)) # noqa
|
|
75
|
-
|
|
76
|
-
#
|
|
77
|
-
|
|
78
73
|
els.extend([
|
|
79
74
|
tool_context_providers().bind_items_provider(singleton=True),
|
|
80
75
|
|
|
@@ -4,7 +4,7 @@ from omlish import dataclasses as dc
|
|
|
4
4
|
from omlish import inject as inj
|
|
5
5
|
from omlish import lang
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from ...... import minichain as mc
|
|
8
8
|
from .configs import ToolSetConfig
|
|
9
9
|
|
|
10
10
|
|
|
@@ -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,8 +1,8 @@
|
|
|
1
1
|
import typing as ta
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from
|
|
5
|
-
from .execution import ToolUseExecutor
|
|
3
|
+
from ...... import minichain as mc
|
|
4
|
+
from .....rendering.types import ContentRendering
|
|
5
|
+
from ...drivers.tools.execution import ToolUseExecutor
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
##
|
|
@@ -10,9 +10,9 @@ from .configs import TodoToolSetConfig
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def bind_todo_tools(cfg: TodoToolSetConfig) -> inj.Elements:
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
13
|
+
from .......minichain.lib.todo.context import TodoContext
|
|
14
|
+
from .......minichain.lib.todo.tools.read import todo_read_tool
|
|
15
|
+
from .......minichain.lib.todo.tools.write import todo_write_tool
|
|
16
16
|
|
|
17
17
|
return inj.as_elements(
|
|
18
18
|
tool_catalog_entries().bind_item_consts(
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import typing as ta
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from omlish import lang
|
|
6
|
+
from omlish import typedvalues as tv
|
|
7
|
+
|
|
8
|
+
from ..... import minichain as mc
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ChatDriverId(tv.UniqueScalarTypedValue[uuid.UUID]):
|
|
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
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from omlish import check
|
|
2
|
+
from omlish import inject as inj
|
|
3
|
+
from omlish import lang
|
|
4
|
+
|
|
5
|
+
from ...... import minichain as mc
|
|
6
|
+
from ..phases.injection import phase_callbacks
|
|
7
|
+
from ..phases.types import ChatPhase
|
|
8
|
+
from ..phases.types import ChatPhaseCallback
|
|
9
|
+
from .configs import UserConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
with lang.auto_proxy_import(globals()):
|
|
13
|
+
from .. import types as _driver
|
|
14
|
+
from ..state import types as _state
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def bind_user(cfg: UserConfig = UserConfig()) -> inj.Elements:
|
|
21
|
+
els: list[inj.Elemental] = []
|
|
22
|
+
|
|
23
|
+
if cfg.initial_system_content is not None:
|
|
24
|
+
async def add_initial_system_content(cm: '_state.ChatStateManager') -> None:
|
|
25
|
+
await cm.extend_chat([mc.SystemMessage(check.not_none(cfg.initial_system_content))])
|
|
26
|
+
|
|
27
|
+
els.append(phase_callbacks().bind_item(to_fn=inj.KwargsTarget.of(
|
|
28
|
+
lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_system_content(cm)),
|
|
29
|
+
cm=_state.ChatStateManager,
|
|
30
|
+
)))
|
|
31
|
+
|
|
32
|
+
if cfg.initial_user_content is not None:
|
|
33
|
+
async def add_initial_user_content(cdg: '_driver.ChatDriverGetter') -> None:
|
|
34
|
+
await (await cdg()).send_user_messages([mc.UserMessage(check.not_none(cfg.initial_user_content))])
|
|
35
|
+
|
|
36
|
+
els.append(phase_callbacks().bind_item(to_fn=inj.KwargsTarget.of(
|
|
37
|
+
lambda cdg: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_user_content(cdg)),
|
|
38
|
+
cdg=_driver.ChatDriverGetter,
|
|
39
|
+
)))
|
|
40
|
+
|
|
41
|
+
return inj.as_elements(*els)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from omlish import dataclasses as dc
|
|
5
|
+
from omlish import lang
|
|
6
|
+
from omlish.argparse import all as argparse
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CommandError(Exception):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dc.dataclass()
|
|
17
|
+
class ArgsCommandError(CommandError):
|
|
18
|
+
command: 'Command'
|
|
19
|
+
argv: ta.Sequence[str]
|
|
20
|
+
help: str
|
|
21
|
+
|
|
22
|
+
arg_error: argparse.ArgumentError | None = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Command(lang.Abstract):
|
|
29
|
+
def __init__(self) -> None:
|
|
30
|
+
super().__init__()
|
|
31
|
+
|
|
32
|
+
self.__parser: argparse.ArgumentParser = argparse.NoExitArgumentParser(
|
|
33
|
+
prog=self.name,
|
|
34
|
+
description=self.description,
|
|
35
|
+
formatter_class=self._HelpFormatter,
|
|
36
|
+
)
|
|
37
|
+
self._configure_parser(self.__parser)
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def name(self) -> str:
|
|
43
|
+
return lang.camel_to_snake(type(self).__name__.removesuffix('Command'))
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def description(self) -> str | None:
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
class _HelpFormatter(argparse.HelpFormatter):
|
|
50
|
+
def start_section(self, heading):
|
|
51
|
+
return super().start_section(heading.title())
|
|
52
|
+
|
|
53
|
+
def add_usage(self, usage, actions, groups, prefix=None):
|
|
54
|
+
if prefix is None:
|
|
55
|
+
prefix = 'Usage: '
|
|
56
|
+
return super().add_usage(usage, actions, groups, prefix)
|
|
57
|
+
|
|
58
|
+
def _configure_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
|
|
63
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
64
|
+
class Context:
|
|
65
|
+
print: ta.Callable[[str], ta.Awaitable[None]]
|
|
66
|
+
|
|
67
|
+
@ta.final
|
|
68
|
+
async def run(self, ctx: Context, argv: list[str]) -> None:
|
|
69
|
+
try:
|
|
70
|
+
args = self.__parser.parse_args(argv)
|
|
71
|
+
except argparse.ArgumentError as ae:
|
|
72
|
+
raise ArgsCommandError(
|
|
73
|
+
self,
|
|
74
|
+
argv,
|
|
75
|
+
self.__parser.format_help(),
|
|
76
|
+
ae,
|
|
77
|
+
) from ae
|
|
78
|
+
|
|
79
|
+
await self._run_args(ctx, args)
|
|
80
|
+
|
|
81
|
+
@abc.abstractmethod
|
|
82
|
+
def _run_args(self, ctx: Context, args: argparse.Namespace) -> ta.Awaitable[None]:
|
|
83
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from omlish import inject as inj
|
|
2
|
+
from omlish import lang
|
|
3
|
+
|
|
4
|
+
from .configs import CommandsConfig
|
|
5
|
+
from .injection import commands
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
with lang.auto_proxy_import(globals()):
|
|
9
|
+
from . import manager as _manager
|
|
10
|
+
from . import simple as _simple
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def bind_commands(cfg: CommandsConfig = CommandsConfig()) -> inj.Elements:
|
|
17
|
+
els: list[inj.Elemental] = []
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
els.append(commands().bind_items_provider(singleton=True))
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
|
|
25
|
+
els.extend([
|
|
26
|
+
inj.bind(_manager.CommandsManager, singleton=True),
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
els.extend([
|
|
32
|
+
inj.bind(_simple.EchoCommand, singleton=True),
|
|
33
|
+
commands().bind_item(to_key=_simple.EchoCommand),
|
|
34
|
+
|
|
35
|
+
inj.bind(_simple.QuitCommand, singleton=True),
|
|
36
|
+
commands().bind_item(to_key=_simple.QuitCommand),
|
|
37
|
+
])
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
|
|
41
|
+
return inj.as_elements(*els)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from omlish import inject as inj
|
|
2
|
+
from omlish import lang
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
with lang.auto_proxy_import(globals()):
|
|
6
|
+
from . import base as _base
|
|
7
|
+
from . import types as _types
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@lang.cached_function
|
|
14
|
+
def commands() -> 'inj.ItemsBinderHelper[_base.Command]':
|
|
15
|
+
return inj.items_binder_helper[_base.Command](_types.Commands)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
import shlex
|
|
3
|
+
|
|
4
|
+
from omlish import collections as col
|
|
5
|
+
|
|
6
|
+
from ..ui import UiMessageDisplayer
|
|
7
|
+
from .base import Command
|
|
8
|
+
from .types import Commands
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RunCommandResult(enum.StrEnum):
|
|
15
|
+
SUCCESS = 'success'
|
|
16
|
+
FAILURE = 'failure'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CommandsManager:
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
commands: Commands,
|
|
24
|
+
ui_message_displayer: UiMessageDisplayer,
|
|
25
|
+
) -> None:
|
|
26
|
+
super().__init__()
|
|
27
|
+
|
|
28
|
+
self._commands = commands
|
|
29
|
+
self._ui_message_displayer = ui_message_displayer
|
|
30
|
+
|
|
31
|
+
self._commands_by_name = col.make_map((
|
|
32
|
+
(c.name, c) for c in commands
|
|
33
|
+
), strict=True)
|
|
34
|
+
|
|
35
|
+
async def run_command_text(self, text: str) -> RunCommandResult:
|
|
36
|
+
try:
|
|
37
|
+
parts = shlex.split(text)
|
|
38
|
+
except ValueError as e:
|
|
39
|
+
await self._ui_message_displayer.display_ui_message(f'Invalid command syntax: {e}')
|
|
40
|
+
return RunCommandResult.FAILURE
|
|
41
|
+
|
|
42
|
+
if not parts:
|
|
43
|
+
return RunCommandResult.FAILURE
|
|
44
|
+
|
|
45
|
+
cmd = parts[0].lstrip('/').lower()
|
|
46
|
+
argv = parts[1:]
|
|
47
|
+
|
|
48
|
+
command = self._commands_by_name.get(cmd)
|
|
49
|
+
if not command:
|
|
50
|
+
await self._ui_message_displayer.display_ui_message(f'Unknown command: {cmd}')
|
|
51
|
+
return RunCommandResult.FAILURE
|
|
52
|
+
|
|
53
|
+
ctx = Command.Context(
|
|
54
|
+
print=self._ui_message_displayer.display_ui_message,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
await command.run(ctx, argv)
|
|
58
|
+
|
|
59
|
+
return RunCommandResult.SUCCESS
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from omlish.argparse import all as argparse
|
|
2
|
+
|
|
3
|
+
from ..ui import UiQuitSignal
|
|
4
|
+
from .base import Command
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EchoCommand(Command):
|
|
11
|
+
def _configure_parser(self, parser: argparse.ArgumentParser) -> None:
|
|
12
|
+
super()._configure_parser(parser)
|
|
13
|
+
|
|
14
|
+
parser.add_argument('message', help='Message to echo')
|
|
15
|
+
|
|
16
|
+
async def _run_args(self, ctx: Command.Context, args: argparse.Namespace) -> None:
|
|
17
|
+
await ctx.print(args.message)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class QuitCommand(Command):
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
*,
|
|
27
|
+
quit_signal: UiQuitSignal,
|
|
28
|
+
) -> None:
|
|
29
|
+
super().__init__()
|
|
30
|
+
|
|
31
|
+
self._quit_signal = quit_signal
|
|
32
|
+
|
|
33
|
+
async def _run_args(self, ctx: Command.Context, args: argparse.Namespace) -> None:
|
|
34
|
+
await self._quit_signal()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from ..... import minichain as mc
|
|
2
|
+
from ..drivers.types import ChatDriver
|
|
3
|
+
from .commands.manager import CommandsManager
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ChatFacade:
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
*,
|
|
13
|
+
driver: ChatDriver,
|
|
14
|
+
commands: CommandsManager,
|
|
15
|
+
) -> None:
|
|
16
|
+
super().__init__()
|
|
17
|
+
|
|
18
|
+
self._driver = driver
|
|
19
|
+
self._commands = commands
|
|
20
|
+
|
|
21
|
+
async def handle_user_input(self, text: str) -> None:
|
|
22
|
+
if text.startswith('/'):
|
|
23
|
+
await self._commands.run_command_text(text[1:])
|
|
24
|
+
|
|
25
|
+
else:
|
|
26
|
+
await self._driver.send_user_messages([mc.UserMessage(text)])
|