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,62 +0,0 @@
|
|
|
1
|
-
from omlish import inject as inj
|
|
2
|
-
from omlish import lang
|
|
3
|
-
|
|
4
|
-
from ...... import minichain as mc
|
|
5
|
-
from ...phases.injection import phase_callbacks
|
|
6
|
-
from ...phases.types import ChatPhase
|
|
7
|
-
from ...phases.types import ChatPhaseCallback
|
|
8
|
-
from .configs import UserConfig
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
with lang.auto_proxy_import(globals()):
|
|
12
|
-
from .....inputs import asyncs as _inputs_asyncs
|
|
13
|
-
from .....inputs import sync as _inputs_sync
|
|
14
|
-
from ..state import types as _state
|
|
15
|
-
from . import interactive as _interactive
|
|
16
|
-
from . import oneshot as _oneshot
|
|
17
|
-
from . import types as _types
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def bind_user(cfg: UserConfig = UserConfig()) -> inj.Elements:
|
|
24
|
-
els: list[inj.Elemental] = []
|
|
25
|
-
|
|
26
|
-
# FIXME: barf
|
|
27
|
-
if cfg.initial_system_content is not None:
|
|
28
|
-
async def add_initial_system_content(cm: '_state.ChatStateManager') -> None:
|
|
29
|
-
await cm.extend_chat([mc.SystemMessage(cfg.initial_system_content)])
|
|
30
|
-
|
|
31
|
-
els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_state.ChatStateManager)(
|
|
32
|
-
lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_system_content(cm)),
|
|
33
|
-
)))
|
|
34
|
-
|
|
35
|
-
if cfg.interactive:
|
|
36
|
-
if cfg.initial_user_content is not None:
|
|
37
|
-
async def add_initial_user_content(cm: '_state.ChatStateManager') -> None:
|
|
38
|
-
await cm.extend_chat([mc.UserMessage(cfg.initial_user_content)])
|
|
39
|
-
|
|
40
|
-
els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_state.ChatStateManager)(
|
|
41
|
-
lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_user_content(cm)),
|
|
42
|
-
)))
|
|
43
|
-
|
|
44
|
-
raise NotImplementedError
|
|
45
|
-
|
|
46
|
-
els.append(inj.bind(_types.UserChatInput, to_ctor=_interactive.InteractiveUserChatInput, singleton=True))
|
|
47
|
-
|
|
48
|
-
els.extend([
|
|
49
|
-
inj.bind(_inputs_sync.SyncStringInput, to_const=_inputs_sync.InputSyncStringInput(use_readline=cfg.use_readline)), # noqa
|
|
50
|
-
inj.bind(_inputs_asyncs.AsyncStringInput, to_ctor=_inputs_asyncs.ThreadAsyncStringInput, singleton=True),
|
|
51
|
-
])
|
|
52
|
-
|
|
53
|
-
else:
|
|
54
|
-
if cfg.initial_user_content is None:
|
|
55
|
-
raise ValueError('Initial user content is required for non-interactive chat')
|
|
56
|
-
|
|
57
|
-
els.extend([
|
|
58
|
-
inj.bind(_oneshot.OneshotUserChatInputInitialChat, to_const=[mc.UserMessage(cfg.initial_user_content)]),
|
|
59
|
-
inj.bind(_types.UserChatInput, to_ctor=_oneshot.OneshotUserChatInput, singleton=True),
|
|
60
|
-
])
|
|
61
|
-
|
|
62
|
-
return inj.as_elements(*els)
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from ...... import minichain as mc
|
|
4
|
-
from .....inputs.asyncs import AsyncStringInput
|
|
5
|
-
from .....inputs.asyncs import SyncAsyncStringInput
|
|
6
|
-
from .....inputs.sync import InputSyncStringInput
|
|
7
|
-
from .types import UserChatInput
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class InteractiveUserChatInput(UserChatInput):
|
|
14
|
-
DEFAULT_STRING_INPUT: ta.ClassVar[AsyncStringInput] = SyncAsyncStringInput(InputSyncStringInput())
|
|
15
|
-
|
|
16
|
-
def __init__(
|
|
17
|
-
self,
|
|
18
|
-
string_input: AsyncStringInput | None = None,
|
|
19
|
-
) -> None:
|
|
20
|
-
super().__init__()
|
|
21
|
-
|
|
22
|
-
if string_input is None:
|
|
23
|
-
string_input = self.DEFAULT_STRING_INPUT
|
|
24
|
-
self._string_input = string_input
|
|
25
|
-
|
|
26
|
-
async def get_next_user_messages(self) -> 'mc.UserChat':
|
|
27
|
-
try:
|
|
28
|
-
s = await self._string_input()
|
|
29
|
-
except EOFError:
|
|
30
|
-
return []
|
|
31
|
-
return [mc.UserMessage(s)]
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from ...... import minichain as mc
|
|
4
|
-
from .types import UserChatInput
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
OneshotUserChatInputInitialChat = ta.NewType('OneshotUserChatInputInitialChat', mc.UserChat)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class OneshotUserChatInput(UserChatInput):
|
|
14
|
-
def __init__(
|
|
15
|
-
self,
|
|
16
|
-
initial_chat: OneshotUserChatInputInitialChat,
|
|
17
|
-
) -> None:
|
|
18
|
-
super().__init__()
|
|
19
|
-
|
|
20
|
-
self._pending_chat: mc.UserChat | None = initial_chat
|
|
21
|
-
|
|
22
|
-
async def get_next_user_messages(self) -> 'mc.UserChat':
|
|
23
|
-
ret = self._pending_chat
|
|
24
|
-
self._pending_chat = None
|
|
25
|
-
return ret or []
|
|
@@ -1,15 +0,0 @@
|
|
|
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 UserChatInput(lang.Abstract):
|
|
13
|
-
@abc.abstractmethod
|
|
14
|
-
def get_next_user_messages(self) -> ta.Awaitable['mc.UserChat']:
|
|
15
|
-
raise NotImplementedError
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
from .chat.ai.types import AiChatGenerator
|
|
2
|
-
from .chat.state.types import ChatStateManager
|
|
3
|
-
from .chat.user.types import UserChatInput
|
|
4
|
-
from .phases.manager import ChatPhaseManager
|
|
5
|
-
from .phases.types import ChatPhase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ChatDriver:
|
|
12
|
-
def __init__(
|
|
13
|
-
self,
|
|
14
|
-
*,
|
|
15
|
-
phases: ChatPhaseManager,
|
|
16
|
-
ai_chat_generator: AiChatGenerator,
|
|
17
|
-
user_chat_input: UserChatInput,
|
|
18
|
-
chat_state_manager: ChatStateManager,
|
|
19
|
-
):
|
|
20
|
-
super().__init__()
|
|
21
|
-
|
|
22
|
-
self._phases = phases
|
|
23
|
-
self._ai_chat_generator = ai_chat_generator
|
|
24
|
-
self._user_chat_input = user_chat_input
|
|
25
|
-
self._chat_state_manager = chat_state_manager
|
|
26
|
-
|
|
27
|
-
async def run(self) -> None:
|
|
28
|
-
await self._phases.set_phase(ChatPhase.STARTING)
|
|
29
|
-
await self._phases.set_phase(ChatPhase.STARTED)
|
|
30
|
-
|
|
31
|
-
while True:
|
|
32
|
-
next_user_chat = await self._user_chat_input.get_next_user_messages()
|
|
33
|
-
if not next_user_chat:
|
|
34
|
-
break
|
|
35
|
-
|
|
36
|
-
prev_user_chat = (await self._chat_state_manager.get_state()).chat
|
|
37
|
-
|
|
38
|
-
next_ai_chat = await self._ai_chat_generator.get_next_ai_messages([*prev_user_chat, *next_user_chat])
|
|
39
|
-
|
|
40
|
-
await self._chat_state_manager.extend_chat([*next_user_chat, *next_ai_chat])
|
|
41
|
-
|
|
42
|
-
await self._phases.set_phase(ChatPhase.STOPPING)
|
|
43
|
-
await self._phases.set_phase(ChatPhase.STOPPED)
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TODO:
|
|
3
|
-
- ExtendedCanContent
|
|
4
|
-
"""
|
|
5
|
-
import dataclasses as dc
|
|
6
|
-
import typing as ta
|
|
7
|
-
|
|
8
|
-
from omlish import check
|
|
9
|
-
from omlish import dispatch
|
|
10
|
-
from omlish.text import templating as tpl
|
|
11
|
-
|
|
12
|
-
from .namespaces import ContentNamespace
|
|
13
|
-
from .placeholders import ContentPlaceholder
|
|
14
|
-
from .placeholders import ContentPlaceholderMarker
|
|
15
|
-
from .types import Content
|
|
16
|
-
from .types import ExtendedContent
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
_InnerCanContent: ta.TypeAlias = ta.Union[ # noqa
|
|
23
|
-
str,
|
|
24
|
-
ExtendedContent,
|
|
25
|
-
|
|
26
|
-
ContentPlaceholder,
|
|
27
|
-
type[ContentPlaceholderMarker],
|
|
28
|
-
|
|
29
|
-
type[ContentNamespace],
|
|
30
|
-
|
|
31
|
-
tpl.Templater,
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
CanContent: ta.TypeAlias = ta.Union[ # noqa
|
|
35
|
-
ta.Iterable['CanContent'],
|
|
36
|
-
|
|
37
|
-
None,
|
|
38
|
-
|
|
39
|
-
_InnerCanContent,
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
##
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
ContentPlaceholderKey: ta.TypeAlias = ContentPlaceholder | type[ContentPlaceholderMarker]
|
|
47
|
-
ContentPlaceholderMap: ta.TypeAlias = ta.Mapping[ContentPlaceholderKey, CanContent]
|
|
48
|
-
ContentPlaceholderFn: ta.TypeAlias = ta.Callable[[ContentPlaceholderKey], CanContent]
|
|
49
|
-
ContentPlaceholders: ta.TypeAlias = ContentPlaceholderMap | ContentPlaceholderFn
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@dc.dataclass()
|
|
53
|
-
class ContentPlaceholderMissingError(Exception):
|
|
54
|
-
key: ContentPlaceholderKey
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def _make_content_placeholder_fn(cps: ContentPlaceholders | None = None) -> ContentPlaceholderFn:
|
|
58
|
-
if cps is None:
|
|
59
|
-
def none_fn(cpk: ContentPlaceholderKey) -> CanContent:
|
|
60
|
-
raise ContentPlaceholderMissingError(cpk)
|
|
61
|
-
|
|
62
|
-
return none_fn
|
|
63
|
-
|
|
64
|
-
elif isinstance(cps, ta.Mapping):
|
|
65
|
-
def mapping_fn(cpk: ContentPlaceholderKey) -> CanContent:
|
|
66
|
-
try:
|
|
67
|
-
return cps[cpk]
|
|
68
|
-
except KeyError:
|
|
69
|
-
raise ContentPlaceholderMissingError(cpk) from None
|
|
70
|
-
|
|
71
|
-
return mapping_fn
|
|
72
|
-
|
|
73
|
-
elif callable(cps):
|
|
74
|
-
return cps
|
|
75
|
-
|
|
76
|
-
else:
|
|
77
|
-
raise TypeError(cps)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
##
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class ContentDepthExceededError(Exception):
|
|
84
|
-
pass
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
class ContentMaterializer:
|
|
88
|
-
DEFAULT_MAX_DEPTH: int = 100
|
|
89
|
-
|
|
90
|
-
def __init__(
|
|
91
|
-
self,
|
|
92
|
-
*,
|
|
93
|
-
content_placeholders: ContentPlaceholders | None = None,
|
|
94
|
-
templater_context: tpl.Templater.Context | None = None,
|
|
95
|
-
max_depth: int = DEFAULT_MAX_DEPTH,
|
|
96
|
-
) -> None:
|
|
97
|
-
super().__init__()
|
|
98
|
-
|
|
99
|
-
self._templater_context = templater_context
|
|
100
|
-
self._content_placeholders_fn = _make_content_placeholder_fn(content_placeholders)
|
|
101
|
-
self._max_depth = max_depth
|
|
102
|
-
|
|
103
|
-
self._cur_depth = 0
|
|
104
|
-
|
|
105
|
-
def materialize(self, o: CanContent) -> Content:
|
|
106
|
-
if self._cur_depth >= self._max_depth:
|
|
107
|
-
raise ContentDepthExceededError
|
|
108
|
-
|
|
109
|
-
self._cur_depth += 1
|
|
110
|
-
try:
|
|
111
|
-
return self._materialize(o)
|
|
112
|
-
finally:
|
|
113
|
-
self._cur_depth -= 1
|
|
114
|
-
|
|
115
|
-
@dispatch.method()
|
|
116
|
-
def _materialize(self, o: CanContent) -> Content:
|
|
117
|
-
raise TypeError(o)
|
|
118
|
-
|
|
119
|
-
#
|
|
120
|
-
|
|
121
|
-
@_materialize.register
|
|
122
|
-
def _materialize_str(self, o: str) -> Content:
|
|
123
|
-
return o
|
|
124
|
-
|
|
125
|
-
@_materialize.register
|
|
126
|
-
def _materialize_extended_content(self, o: ExtendedContent) -> Content:
|
|
127
|
-
return o
|
|
128
|
-
|
|
129
|
-
#
|
|
130
|
-
|
|
131
|
-
@_materialize.register
|
|
132
|
-
def _materialize_iterable(self, o: ta.Iterable) -> Content:
|
|
133
|
-
# `collections.abc.Iterable` appears as a virtual base in the dispatch c3.mro for ContentNamespace before `type`
|
|
134
|
-
# does (due to NamespaceMeta having `__iter__`), so handle that here too.
|
|
135
|
-
if isinstance(o, type) and issubclass(o, ContentNamespace):
|
|
136
|
-
return self._materialize_namespace_type(o)
|
|
137
|
-
|
|
138
|
-
else:
|
|
139
|
-
return [self.materialize(e) for e in o]
|
|
140
|
-
|
|
141
|
-
@_materialize.register
|
|
142
|
-
def _materialize_none(self, o: None) -> Content:
|
|
143
|
-
return []
|
|
144
|
-
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
@_materialize.register
|
|
148
|
-
def _materialize_placeholder(self, o: ContentPlaceholder) -> Content:
|
|
149
|
-
return self.materialize(self._content_placeholders_fn(o))
|
|
150
|
-
|
|
151
|
-
def _materialize_placeholder_marker_type(self, o: type[ContentPlaceholderMarker]) -> Content:
|
|
152
|
-
check.issubclass(o, ContentPlaceholderMarker)
|
|
153
|
-
return self.materialize(self._content_placeholders_fn(o))
|
|
154
|
-
|
|
155
|
-
#
|
|
156
|
-
|
|
157
|
-
def _materialize_namespace_type(self, o: type[ContentNamespace]) -> Content:
|
|
158
|
-
check.issubclass(o, ContentNamespace)
|
|
159
|
-
|
|
160
|
-
out: list[Content] = []
|
|
161
|
-
for n, e in o:
|
|
162
|
-
if n.startswith('_'):
|
|
163
|
-
continue
|
|
164
|
-
out.append(self.materialize(e))
|
|
165
|
-
return out
|
|
166
|
-
|
|
167
|
-
#
|
|
168
|
-
|
|
169
|
-
@_materialize.register
|
|
170
|
-
def _materialize_type(self, o: type) -> Content:
|
|
171
|
-
if issubclass(o, ContentPlaceholderMarker):
|
|
172
|
-
return self._materialize_placeholder_marker_type(o)
|
|
173
|
-
|
|
174
|
-
elif issubclass(o, ContentNamespace):
|
|
175
|
-
return self._materialize_namespace_type(o)
|
|
176
|
-
|
|
177
|
-
else:
|
|
178
|
-
raise TypeError(o)
|
|
179
|
-
|
|
180
|
-
#
|
|
181
|
-
|
|
182
|
-
@_materialize.register
|
|
183
|
-
def _materialize_templater(self, o: tpl.Templater) -> Content:
|
|
184
|
-
return o.render(check.not_none(self._templater_context))
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def materialize_content(
|
|
188
|
-
o: CanContent,
|
|
189
|
-
*,
|
|
190
|
-
content_placeholders: ContentPlaceholders | None = None,
|
|
191
|
-
templater_context: tpl.Templater.Context | None = None,
|
|
192
|
-
) -> Content:
|
|
193
|
-
return ContentMaterializer(
|
|
194
|
-
content_placeholders=content_placeholders,
|
|
195
|
-
templater_context=templater_context,
|
|
196
|
-
).materialize(o)
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import check
|
|
4
|
-
from omlish import dataclasses as dc
|
|
5
|
-
from omlish import lang
|
|
6
|
-
from omlish import typedvalues as tv
|
|
7
|
-
|
|
8
|
-
from .._typedvalues import _tv_field_metadata
|
|
9
|
-
from ..metadata import MetadataContainer
|
|
10
|
-
from .metadata import ContentMetadatas
|
|
11
|
-
from .types import ExtendedContent
|
|
12
|
-
from .types import SingleExtendedContent
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@dc.dataclass(frozen=True)
|
|
19
|
-
class SimpleExtendedContent( # noqa
|
|
20
|
-
MetadataContainer[ContentMetadatas],
|
|
21
|
-
ExtendedContent,
|
|
22
|
-
lang.Abstract,
|
|
23
|
-
):
|
|
24
|
-
_metadata: ta.Sequence[ContentMetadatas] = dc.field(
|
|
25
|
-
default=(),
|
|
26
|
-
kw_only=True,
|
|
27
|
-
metadata=_tv_field_metadata(
|
|
28
|
-
ContentMetadatas,
|
|
29
|
-
marshal_name='metadata',
|
|
30
|
-
),
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
@property
|
|
34
|
-
def metadata(self) -> tv.TypedValues[ContentMetadatas]:
|
|
35
|
-
return check.isinstance(self._metadata, tv.TypedValues)
|
|
36
|
-
|
|
37
|
-
def with_metadata(self, *mds: ContentMetadatas, override: bool = False) -> ta.Self:
|
|
38
|
-
return dc.replace(self, _metadata=tv.TypedValues(*self._metadata, *mds, override=override))
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@dc.dataclass(frozen=True)
|
|
42
|
-
class SimpleSingleExtendedContent(
|
|
43
|
-
SimpleExtendedContent,
|
|
44
|
-
SingleExtendedContent,
|
|
45
|
-
lang.Abstract,
|
|
46
|
-
):
|
|
47
|
-
pass
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import collections.abc
|
|
2
|
-
import typing as ta
|
|
3
|
-
|
|
4
|
-
from omlish import dataclasses as dc
|
|
5
|
-
from omlish import dispatch
|
|
6
|
-
from omlish import lang
|
|
7
|
-
|
|
8
|
-
from ..images import ImageContent
|
|
9
|
-
from ..sequence import SequenceContent
|
|
10
|
-
from ..text import TextContent
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
T = ta.TypeVar('T')
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ContentTransform(lang.Abstract):
|
|
20
|
-
@dispatch.method(installable=True)
|
|
21
|
-
def apply(self, o: T) -> T:
|
|
22
|
-
raise TypeError(o)
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
@apply.register # noqa
|
|
27
|
-
def apply_str(self, s: str) -> str:
|
|
28
|
-
return s
|
|
29
|
-
|
|
30
|
-
@apply.register # noqa
|
|
31
|
-
def apply_sequence(self, l: collections.abc.Sequence[T]) -> collections.abc.Sequence[T]:
|
|
32
|
-
return [self.apply(e) for e in l]
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
@apply.register
|
|
37
|
-
def apply_image_content(self, c: ImageContent) -> ImageContent:
|
|
38
|
-
return c
|
|
39
|
-
|
|
40
|
-
@apply.register
|
|
41
|
-
def apply_sequence_content(self, c: SequenceContent) -> SequenceContent:
|
|
42
|
-
return dc.replace(c, l=self.apply(c.l))
|
|
43
|
-
|
|
44
|
-
@apply.register
|
|
45
|
-
def apply_text_content(self, c: TextContent) -> TextContent:
|
|
46
|
-
return dc.replace(c, s=self.apply(c.s))
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import dataclasses as dc
|
|
4
|
-
from omlish import dispatch
|
|
5
|
-
from omlish import lang
|
|
6
|
-
|
|
7
|
-
from ..sequence import BlockContent
|
|
8
|
-
from ..sequence import InlineContent
|
|
9
|
-
from ..types import Content
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ContentInterleaver:
|
|
16
|
-
def __init__(
|
|
17
|
-
self,
|
|
18
|
-
*,
|
|
19
|
-
separator: Content | None = None,
|
|
20
|
-
sequence_separator: Content | None = None,
|
|
21
|
-
inline_separator: Content | None = None,
|
|
22
|
-
block_separator: Content | None = None,
|
|
23
|
-
) -> None:
|
|
24
|
-
super().__init__()
|
|
25
|
-
|
|
26
|
-
self._sequence_separator = sequence_separator if sequence_separator is not None else separator
|
|
27
|
-
self._inline_separator = inline_separator if inline_separator is not None else separator
|
|
28
|
-
self._block_separator = block_separator if block_separator is not None else separator
|
|
29
|
-
|
|
30
|
-
def _interleave(self, l: ta.Iterable[Content], separator: Content | None) -> ta.Sequence[Content]:
|
|
31
|
-
cs: ta.Iterable[Content] = map(self.interleave, l)
|
|
32
|
-
if separator is not None:
|
|
33
|
-
cs = lang.interleave(cs, separator)
|
|
34
|
-
return list(cs)
|
|
35
|
-
|
|
36
|
-
@dispatch.method()
|
|
37
|
-
def interleave(self, c: Content) -> Content:
|
|
38
|
-
return c
|
|
39
|
-
|
|
40
|
-
@interleave.register
|
|
41
|
-
def interleave_str(self, c: str) -> Content:
|
|
42
|
-
return c
|
|
43
|
-
|
|
44
|
-
@interleave.register
|
|
45
|
-
def interleave_sequence(self, c: ta.Sequence) -> Content:
|
|
46
|
-
return self._interleave(c, self._sequence_separator)
|
|
47
|
-
|
|
48
|
-
@interleave.register
|
|
49
|
-
def interleave_inline_content(self, c: InlineContent) -> Content:
|
|
50
|
-
return dc.replace(c, l=self._interleave(c.l, self._inline_separator))
|
|
51
|
-
|
|
52
|
-
@interleave.register
|
|
53
|
-
def interleave_block_content(self, c: BlockContent) -> Content:
|
|
54
|
-
return dc.replace(c, l=self._interleave(c.l, self._block_separator))
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def interleave_content(
|
|
58
|
-
c: Content,
|
|
59
|
-
*,
|
|
60
|
-
separator: Content | None = None,
|
|
61
|
-
sequence_separator: Content | None = None,
|
|
62
|
-
inline_separator: Content | None = None,
|
|
63
|
-
block_separator: Content | None = None,
|
|
64
|
-
) -> Content:
|
|
65
|
-
return ContentInterleaver(
|
|
66
|
-
separator=separator,
|
|
67
|
-
sequence_separator=sequence_separator,
|
|
68
|
-
inline_separator=inline_separator,
|
|
69
|
-
block_separator=block_separator,
|
|
70
|
-
).interleave(c)
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import dataclasses as dc
|
|
4
|
-
from omlish import dispatch
|
|
5
|
-
|
|
6
|
-
from ..sequence import SequenceContent
|
|
7
|
-
from ..text import TextContent
|
|
8
|
-
from ..types import Content
|
|
9
|
-
from ..types import SingleContent
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ContentSqueezer:
|
|
16
|
-
def __init__(
|
|
17
|
-
self,
|
|
18
|
-
*,
|
|
19
|
-
strip_strings: bool = False,
|
|
20
|
-
) -> None:
|
|
21
|
-
super().__init__()
|
|
22
|
-
|
|
23
|
-
self._strip_strings = strip_strings
|
|
24
|
-
|
|
25
|
-
@dispatch.method()
|
|
26
|
-
def squeeze(self, c: Content) -> ta.Iterable[SingleContent]:
|
|
27
|
-
raise TypeError(c)
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
@squeeze.register
|
|
32
|
-
def squeeze_str(self, c: str) -> ta.Iterable[SingleContent]:
|
|
33
|
-
if self._strip_strings:
|
|
34
|
-
c = c.strip()
|
|
35
|
-
|
|
36
|
-
if c:
|
|
37
|
-
yield c
|
|
38
|
-
|
|
39
|
-
@squeeze.register
|
|
40
|
-
def squeeze_sequence(self, c: ta.Sequence) -> ta.Iterable[SingleContent]:
|
|
41
|
-
for e in c:
|
|
42
|
-
yield from self.squeeze(e)
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
@squeeze.register
|
|
47
|
-
def squeeze_single_content(self, c: SingleContent) -> ta.Iterable[SingleContent]:
|
|
48
|
-
return [c]
|
|
49
|
-
|
|
50
|
-
@squeeze.register
|
|
51
|
-
def squeeze_text_content(self, c: TextContent) -> ta.Iterable[SingleContent]:
|
|
52
|
-
if self._strip_strings:
|
|
53
|
-
if (ss := c.s.strip()) != c.s:
|
|
54
|
-
c = dc.replace(c, s=ss)
|
|
55
|
-
|
|
56
|
-
if c.s:
|
|
57
|
-
yield c.s
|
|
58
|
-
|
|
59
|
-
@squeeze.register
|
|
60
|
-
def squeeze_sequence_content(self, c: SequenceContent) -> ta.Iterable[SingleContent]:
|
|
61
|
-
for e in c.l:
|
|
62
|
-
yield from self.squeeze(e)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def squeeze_content(
|
|
66
|
-
c: Content,
|
|
67
|
-
*,
|
|
68
|
-
strip_strings: bool = False,
|
|
69
|
-
) -> ta.Sequence[SingleContent]:
|
|
70
|
-
return list(ContentSqueezer(
|
|
71
|
-
strip_strings=strip_strings,
|
|
72
|
-
).squeeze(c))
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import dataclasses as dc
|
|
4
|
-
|
|
5
|
-
from .base import ContentTransform
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
T = ta.TypeVar('T')
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@dc.dataclass(frozen=True)
|
|
15
|
-
class StringFnContentTransform(ContentTransform):
|
|
16
|
-
fn: ta.Callable[[str], str]
|
|
17
|
-
|
|
18
|
-
@ContentTransform.apply.register # noqa
|
|
19
|
-
def apply_str(self, s: str) -> str:
|
|
20
|
-
return self.fn(s)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def transform_content_strings(fn: ta.Callable[[str], str], o: T) -> T:
|
|
24
|
-
return StringFnContentTransform(fn).apply(o)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import lang
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
##
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ExtendedContent(lang.Abstract, lang.PackageSealed):
|
|
10
|
-
pass
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class SingleExtendedContent(ExtendedContent, lang.Abstract):
|
|
14
|
-
pass
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Content: ta.TypeAlias = ta.Union[ # noqa
|
|
21
|
-
str,
|
|
22
|
-
ExtendedContent,
|
|
23
|
-
ta.Sequence['Content'],
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
CONTENT_RUNTIME_TYPES: tuple[type, ...] = (
|
|
28
|
-
str,
|
|
29
|
-
ta.Sequence,
|
|
30
|
-
ExtendedContent,
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
SingleContent: ta.TypeAlias = ta.Union[ # noqa
|
|
36
|
-
str,
|
|
37
|
-
SingleExtendedContent,
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
SINGLE_CONTENT_RUNTIME_TYPES: tuple[type, ...] = (
|
|
41
|
-
str,
|
|
42
|
-
SingleExtendedContent,
|
|
43
|
-
)
|