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,26 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
from omlish import dataclasses as dc
|
|
5
|
+
from omlish import lang
|
|
6
|
+
|
|
7
|
+
from .composite import CompositeContent
|
|
8
|
+
from .content import Content
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dc.dataclass(frozen=True)
|
|
15
|
+
class SectionContent(CompositeContent, lang.Final):
|
|
16
|
+
body: Content
|
|
17
|
+
|
|
18
|
+
_: dc.KW_ONLY
|
|
19
|
+
|
|
20
|
+
header: str | None
|
|
21
|
+
|
|
22
|
+
def child_content(self) -> ta.Sequence[Content]:
|
|
23
|
+
return [self.body]
|
|
24
|
+
|
|
25
|
+
def _replace_child_content(self, new_child_content: ta.Sequence[Content]) -> ta.Self:
|
|
26
|
+
return self.replace(body=check.single(new_child_content))
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
|
+
- ... does inline have *any* separator? generic whitespace when content is stripped?
|
|
3
4
|
- track BlockContent nesting depth?
|
|
4
5
|
- section names? dedicated 'section' content with header and body?
|
|
5
6
|
"""
|
|
@@ -8,17 +9,23 @@ import typing as ta
|
|
|
8
9
|
from omlish import dataclasses as dc
|
|
9
10
|
from omlish import lang
|
|
10
11
|
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
12
|
+
from .composite import CompositeContent
|
|
13
|
+
from .content import Content
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
##
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
@dc.dataclass(frozen=True)
|
|
19
|
-
class SequenceContent(
|
|
20
|
+
class SequenceContent(CompositeContent, lang.Abstract):
|
|
20
21
|
l: ta.Sequence[Content]
|
|
21
22
|
|
|
23
|
+
def child_content(self) -> ta.Sequence[Content]:
|
|
24
|
+
return self.l
|
|
25
|
+
|
|
26
|
+
def _replace_child_content(self, new_child_content: ta.Sequence[Content]) -> ta.Self:
|
|
27
|
+
return self.replace(l=new_child_content)
|
|
28
|
+
|
|
22
29
|
|
|
23
30
|
@dc.dataclass(frozen=True)
|
|
24
31
|
class InlineContent(SequenceContent, lang.Final):
|
|
@@ -28,3 +35,10 @@ class InlineContent(SequenceContent, lang.Final):
|
|
|
28
35
|
@dc.dataclass(frozen=True)
|
|
29
36
|
class BlockContent(SequenceContent, lang.Final):
|
|
30
37
|
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dc.dataclass(frozen=True)
|
|
41
|
+
class ItemListContent(SequenceContent, lang.Final):
|
|
42
|
+
_: dc.KW_ONLY
|
|
43
|
+
|
|
44
|
+
style: ta.Literal['-', '#'] = '-'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import dataclasses as dc
|
|
4
|
+
from omlish import lang
|
|
5
|
+
|
|
6
|
+
from ..metadata import MetadataContainerDataclass
|
|
7
|
+
from .content import BaseContent
|
|
8
|
+
from .metadata import ContentMetadatas
|
|
9
|
+
from .metadata import ContentOriginal
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dc.dataclass(frozen=True)
|
|
16
|
+
class StandardContent( # noqa
|
|
17
|
+
MetadataContainerDataclass[ContentMetadatas],
|
|
18
|
+
BaseContent,
|
|
19
|
+
lang.Abstract,
|
|
20
|
+
):
|
|
21
|
+
_metadata: ta.Sequence[ContentMetadatas] = dc.field(
|
|
22
|
+
default=(),
|
|
23
|
+
kw_only=True,
|
|
24
|
+
repr=False,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
MetadataContainerDataclass._configure_metadata_field(_metadata, ContentMetadatas) # noqa
|
|
28
|
+
|
|
29
|
+
def replace(self, **kwargs: ta.Any) -> ta.Self:
|
|
30
|
+
if (n := dc.replace_is_not(self, **kwargs)) is self:
|
|
31
|
+
return self
|
|
32
|
+
return n.with_metadata(ContentOriginal(self), discard=[ContentOriginal], override=True)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- track BlockContent nesting depth?
|
|
4
|
+
- section names? dedicated 'section' content with header and body?
|
|
5
|
+
"""
|
|
6
|
+
import typing as ta
|
|
7
|
+
|
|
8
|
+
from omlish import check
|
|
9
|
+
from omlish import dataclasses as dc
|
|
10
|
+
from omlish import lang
|
|
11
|
+
|
|
12
|
+
from .composite import CompositeContent
|
|
13
|
+
from .content import Content
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dc.dataclass(frozen=True)
|
|
20
|
+
class TagContent(CompositeContent, lang.Final):
|
|
21
|
+
tag: str
|
|
22
|
+
body: Content
|
|
23
|
+
|
|
24
|
+
def child_content(self) -> ta.Sequence[Content]:
|
|
25
|
+
return [self.body]
|
|
26
|
+
|
|
27
|
+
def _replace_child_content(self, new_child_content: ta.Sequence[Content]) -> ta.Self:
|
|
28
|
+
return self.replace(body=check.single(new_child_content))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from omlish import dataclasses as dc
|
|
2
|
+
from omlish import lang
|
|
3
|
+
from omlish.text import templating as tpl
|
|
4
|
+
|
|
5
|
+
from .dynamic import DynamicContent
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dc.dataclass(frozen=True)
|
|
12
|
+
class TemplateContent(DynamicContent, lang.Final):
|
|
13
|
+
t: tpl.Templater
|
ommlds/minichain/content/text.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from omlish import dataclasses as dc
|
|
2
2
|
from omlish import lang
|
|
3
3
|
|
|
4
|
-
from .
|
|
4
|
+
from .standard import StandardContent
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
##
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@dc.dataclass(frozen=True)
|
|
11
|
-
class TextContent(
|
|
11
|
+
class TextContent(StandardContent, lang.Final):
|
|
12
12
|
s: str
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish.formats import json
|
|
4
|
+
|
|
5
|
+
from ..code import BlockCodeContent
|
|
6
|
+
from ..code import InlineCodeContent
|
|
7
|
+
from ..json import JsonContent
|
|
8
|
+
from ..metadata import ContentOriginal
|
|
9
|
+
from ..standard import StandardContent
|
|
10
|
+
from ..text import TextContent
|
|
11
|
+
from ..visitors import ContentTransform
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class JsonContentRenderer(ContentTransform[None]):
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
*,
|
|
21
|
+
backend: json.Backend | None = None,
|
|
22
|
+
mode: ta.Literal['pretty', 'compact', 'normal'] = 'pretty',
|
|
23
|
+
code: ta.Literal['inline', 'block', None] = None,
|
|
24
|
+
) -> None:
|
|
25
|
+
super().__init__()
|
|
26
|
+
|
|
27
|
+
if backend is None:
|
|
28
|
+
backend = json.default_backend()
|
|
29
|
+
self._backend = backend
|
|
30
|
+
self._mode = mode
|
|
31
|
+
self._code = code
|
|
32
|
+
|
|
33
|
+
def visit_json_content(self, c: JsonContent, ctx: None) -> StandardContent:
|
|
34
|
+
match self._mode:
|
|
35
|
+
case 'pretty':
|
|
36
|
+
s = self._backend.dumps_pretty(c.v)
|
|
37
|
+
case 'compact':
|
|
38
|
+
s = self._backend.dumps_compact(c.v)
|
|
39
|
+
case 'normal':
|
|
40
|
+
s = self._backend.dumps(c.v)
|
|
41
|
+
case _:
|
|
42
|
+
raise ValueError(self._mode)
|
|
43
|
+
|
|
44
|
+
nc: StandardContent
|
|
45
|
+
match self._code:
|
|
46
|
+
case 'inline':
|
|
47
|
+
nc = InlineCodeContent(s, lang='json')
|
|
48
|
+
case 'block':
|
|
49
|
+
nc = BlockCodeContent(s, lang='json')
|
|
50
|
+
case None:
|
|
51
|
+
nc = TextContent(s)
|
|
52
|
+
case _:
|
|
53
|
+
raise ValueError(self._code)
|
|
54
|
+
|
|
55
|
+
return nc.with_metadata(ContentOriginal(c))
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
|
|
3
|
+
from omlish import lang
|
|
4
|
+
from omlish.text import templating as tpl
|
|
5
|
+
|
|
6
|
+
from ..content import Content
|
|
7
|
+
from .recursive import PlaceholderContents
|
|
8
|
+
from .recursive import RecursiveContentMaterializer
|
|
9
|
+
from .templates import TemplateContentMaterializer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ContentMaterializer(lang.Abstract):
|
|
16
|
+
@abc.abstractmethod
|
|
17
|
+
def apply(self, c: Content) -> Content:
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DefaultContentMaterializer(ContentMaterializer):
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
*,
|
|
28
|
+
placeholder_contents: PlaceholderContents | None = None,
|
|
29
|
+
templater_context: tpl.Templater.Context | None = None,
|
|
30
|
+
) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
|
|
33
|
+
self._placeholder_contents = placeholder_contents
|
|
34
|
+
self._templater_context = templater_context
|
|
35
|
+
|
|
36
|
+
def apply(self, c: Content) -> Content:
|
|
37
|
+
c = RecursiveContentMaterializer(self._placeholder_contents).visit(c, None)
|
|
38
|
+
c = TemplateContentMaterializer(self._templater_context).visit(c, None)
|
|
39
|
+
return c
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def materialize_content(
|
|
43
|
+
c: Content,
|
|
44
|
+
*,
|
|
45
|
+
placeholder_contents: PlaceholderContents | None = None,
|
|
46
|
+
templater_context: tpl.Templater.Context | None = None,
|
|
47
|
+
) -> Content:
|
|
48
|
+
return DefaultContentMaterializer(
|
|
49
|
+
placeholder_contents=placeholder_contents,
|
|
50
|
+
templater_context=templater_context,
|
|
51
|
+
).apply(c)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from ..content import Content
|
|
2
|
+
from ..metadata import ContentOriginal
|
|
3
|
+
from ..standard import StandardContent
|
|
4
|
+
from ..visitors import ContentTransform
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class OriginalMetadataStrippingContentTransform(ContentTransform[None]):
|
|
11
|
+
def visit_standard_content(self, c: StandardContent, ctx: None) -> StandardContent:
|
|
12
|
+
return c.with_metadata(discard=[ContentOriginal])
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def strip_content_original_metadata(c: Content) -> Content:
|
|
16
|
+
return OriginalMetadataStrippingContentTransform().visit(c, None)
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
|
-
- re-
|
|
3
|
+
- re-docwrap
|
|
4
4
|
"""
|
|
5
5
|
import abc
|
|
6
|
-
import dataclasses as dc
|
|
7
6
|
import typing as ta
|
|
8
7
|
|
|
8
|
+
from omlish import dataclasses as dc
|
|
9
9
|
from omlish import lang
|
|
10
10
|
|
|
11
|
-
from
|
|
11
|
+
from ..content import Content
|
|
12
12
|
from .materialize import materialize_content
|
|
13
|
-
from .
|
|
14
|
-
from .transforms.squeeze import squeeze_content
|
|
15
|
-
from .transforms.stringify import stringify_content
|
|
16
|
-
from .types import Content
|
|
13
|
+
from .stringify import stringify_content
|
|
17
14
|
|
|
18
15
|
|
|
19
16
|
##
|
|
@@ -21,13 +18,13 @@ from .types import Content
|
|
|
21
18
|
|
|
22
19
|
class ContentPreparer(lang.Abstract):
|
|
23
20
|
@abc.abstractmethod
|
|
24
|
-
def prepare(self, c:
|
|
21
|
+
def prepare(self, c: Content) -> Content:
|
|
25
22
|
raise NotImplementedError
|
|
26
23
|
|
|
27
24
|
|
|
28
25
|
class ContentStrPreparer(lang.Abstract):
|
|
29
26
|
@abc.abstractmethod
|
|
30
|
-
def prepare_str(self, c:
|
|
27
|
+
def prepare_str(self, c: Content) -> str:
|
|
31
28
|
raise NotImplementedError
|
|
32
29
|
|
|
33
30
|
|
|
@@ -44,10 +41,8 @@ class DefaultContentPreparer(ContentPreparer):
|
|
|
44
41
|
strip_strings: bool = True
|
|
45
42
|
block_separator: Content = DEFAULT_BLOCK_SEPARATOR
|
|
46
43
|
|
|
47
|
-
def prepare(self, c:
|
|
44
|
+
def prepare(self, c: Content) -> Content:
|
|
48
45
|
c = materialize_content(c)
|
|
49
|
-
c = squeeze_content(c, strip_strings=self.strip_strings)
|
|
50
|
-
c = interleave_content(c, block_separator=self.block_separator)
|
|
51
46
|
return c
|
|
52
47
|
|
|
53
48
|
|
|
@@ -55,7 +50,7 @@ class DefaultContentPreparer(ContentPreparer):
|
|
|
55
50
|
class DefaultContentStrPreparer(ContentStrPreparer):
|
|
56
51
|
content_preparer: ContentPreparer
|
|
57
52
|
|
|
58
|
-
def prepare_str(self, c:
|
|
53
|
+
def prepare_str(self, c: Content) -> str:
|
|
59
54
|
return stringify_content(self.content_preparer.prepare(c))
|
|
60
55
|
|
|
61
56
|
|
|
@@ -70,9 +65,9 @@ def default_content_str_preparer(**kwargs: ta.Any) -> ContentStrPreparer:
|
|
|
70
65
|
return DefaultContentStrPreparer(DefaultContentPreparer(**kwargs))
|
|
71
66
|
|
|
72
67
|
|
|
73
|
-
def prepare_content(c:
|
|
68
|
+
def prepare_content(c: Content, **kwargs: ta.Any) -> Content:
|
|
74
69
|
return default_content_preparer(**kwargs).prepare(c)
|
|
75
70
|
|
|
76
71
|
|
|
77
|
-
def prepare_content_str(c:
|
|
72
|
+
def prepare_content_str(c: Content, **kwargs: ta.Any) -> str:
|
|
78
73
|
return default_content_str_preparer(**kwargs).prepare_str(c)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
from omlish import dataclasses as dc
|
|
5
|
+
|
|
6
|
+
from ..content import Content
|
|
7
|
+
from ..namespaces import ContentNamespace
|
|
8
|
+
from ..namespaces import NamespaceContent
|
|
9
|
+
from ..placeholders import PlaceholderContent
|
|
10
|
+
from ..placeholders import PlaceholderContentKey
|
|
11
|
+
from ..recursive import RecursiveContent
|
|
12
|
+
from ..visitors import ContentTransform
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
PlaceholderContentMap: ta.TypeAlias = ta.Mapping[PlaceholderContentKey, Content]
|
|
19
|
+
PlaceholderContentFn: ta.TypeAlias = ta.Callable[[PlaceholderContentKey], Content]
|
|
20
|
+
PlaceholderContents: ta.TypeAlias = PlaceholderContentMap | PlaceholderContentFn
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dc.dataclass()
|
|
24
|
+
class PlaceholderContentMissingError(Exception):
|
|
25
|
+
key: PlaceholderContentKey
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _make_placeholder_content_fn(cps: PlaceholderContents | None = None) -> PlaceholderContentFn:
|
|
29
|
+
if cps is None:
|
|
30
|
+
def none_fn(cpk: PlaceholderContentKey) -> Content:
|
|
31
|
+
raise PlaceholderContentMissingError(cpk)
|
|
32
|
+
|
|
33
|
+
return none_fn
|
|
34
|
+
|
|
35
|
+
elif isinstance(cps, ta.Mapping):
|
|
36
|
+
def mapping_fn(cpk: PlaceholderContentKey) -> Content:
|
|
37
|
+
try:
|
|
38
|
+
return cps[cpk]
|
|
39
|
+
except KeyError:
|
|
40
|
+
raise PlaceholderContentMissingError(cpk) from None
|
|
41
|
+
|
|
42
|
+
return mapping_fn
|
|
43
|
+
|
|
44
|
+
elif callable(cps):
|
|
45
|
+
return cps
|
|
46
|
+
|
|
47
|
+
else:
|
|
48
|
+
raise TypeError(cps)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class RecursiveContentDepthExceededError(Exception):
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class RecursiveContentMaterializer(ContentTransform[None]):
|
|
59
|
+
DEFAULT_MAX_DEPTH: int = 8
|
|
60
|
+
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
placeholder_contents: PlaceholderContents | None = None,
|
|
64
|
+
*,
|
|
65
|
+
max_depth: int = DEFAULT_MAX_DEPTH,
|
|
66
|
+
) -> None:
|
|
67
|
+
super().__init__()
|
|
68
|
+
|
|
69
|
+
self._placeholder_content_fn = _make_placeholder_content_fn(placeholder_contents)
|
|
70
|
+
self._max_depth = max_depth
|
|
71
|
+
|
|
72
|
+
self._cur_depth = 0
|
|
73
|
+
|
|
74
|
+
def recurse(self, o: Content, ctx: None) -> Content:
|
|
75
|
+
if self._cur_depth >= self._max_depth:
|
|
76
|
+
raise RecursiveContentDepthExceededError
|
|
77
|
+
|
|
78
|
+
self._cur_depth += 1
|
|
79
|
+
try:
|
|
80
|
+
return self.visit(o, ctx)
|
|
81
|
+
finally:
|
|
82
|
+
self._cur_depth -= 1
|
|
83
|
+
|
|
84
|
+
def visit_recursive_content(self, c: RecursiveContent, ctx: None) -> Content:
|
|
85
|
+
raise TypeError(c)
|
|
86
|
+
|
|
87
|
+
def visit_namespace_content(self, c: NamespaceContent, ctx: None) -> Content:
|
|
88
|
+
check.issubclass(c.ns, ContentNamespace)
|
|
89
|
+
out: list[Content] = []
|
|
90
|
+
for n, e in c.ns:
|
|
91
|
+
if n.startswith('_'):
|
|
92
|
+
continue
|
|
93
|
+
out.append(self.recurse(e, ctx))
|
|
94
|
+
return out
|
|
95
|
+
|
|
96
|
+
def visit_placeholder_content(self, c: PlaceholderContent, ctx: None) -> Content:
|
|
97
|
+
return self.recurse(self._placeholder_content_fn(c.k), ctx)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import collections.abc
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
from omlish import check
|
|
5
|
+
|
|
6
|
+
from ..content import Content
|
|
7
|
+
from ..metadata import ContentOriginal
|
|
8
|
+
from ..sequence import BlockContent
|
|
9
|
+
from ..sequence import InlineContent
|
|
10
|
+
from ..sequence import SequenceContent
|
|
11
|
+
from ..text import TextContent
|
|
12
|
+
from ..visitors import ContentTransform
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LiftToStandardContentTransform(ContentTransform[None]):
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
*,
|
|
22
|
+
sequence_mode: ta.Literal['block', 'inline'] = 'block',
|
|
23
|
+
) -> None:
|
|
24
|
+
super().__init__()
|
|
25
|
+
|
|
26
|
+
self._sequence_mode = sequence_mode
|
|
27
|
+
|
|
28
|
+
def visit_str(self, s: str, ctx: None) -> Content:
|
|
29
|
+
return TextContent(s).with_metadata(ContentOriginal(s))
|
|
30
|
+
|
|
31
|
+
def visit_sequence(self, c: ta.Sequence[Content], ctx: None) -> Content:
|
|
32
|
+
cc = check.isinstance(super().visit_sequence(c, ctx), collections.abc.Sequence)
|
|
33
|
+
|
|
34
|
+
nc: SequenceContent
|
|
35
|
+
match self._sequence_mode:
|
|
36
|
+
case 'block':
|
|
37
|
+
nc = BlockContent(cc)
|
|
38
|
+
case 'inline':
|
|
39
|
+
nc = InlineContent(cc)
|
|
40
|
+
case _:
|
|
41
|
+
raise ValueError(self._sequence_mode)
|
|
42
|
+
|
|
43
|
+
return nc.with_metadata(ContentOriginal(c))
|
|
@@ -3,9 +3,8 @@ import typing as ta
|
|
|
3
3
|
|
|
4
4
|
from omlish import dispatch
|
|
5
5
|
|
|
6
|
-
from ..
|
|
6
|
+
from ..content import Content
|
|
7
7
|
from ..text import TextContent
|
|
8
|
-
from ..types import Content
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
##
|
|
@@ -45,11 +44,6 @@ class ContentStringWriter:
|
|
|
45
44
|
def write_text_content(self, c: TextContent) -> None:
|
|
46
45
|
self._out.write(c.s)
|
|
47
46
|
|
|
48
|
-
@write.register
|
|
49
|
-
def write_sequence_content(self, c: SequenceContent) -> None:
|
|
50
|
-
for e in c.l:
|
|
51
|
-
self.write(e)
|
|
52
|
-
|
|
53
47
|
#
|
|
54
48
|
|
|
55
49
|
@classmethod
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import dataclasses as dc
|
|
4
|
+
|
|
5
|
+
from ..content import Content
|
|
6
|
+
from ..emphasis import EmphasisContent
|
|
7
|
+
from ..metadata import ContentOriginal
|
|
8
|
+
from ..text import TextContent
|
|
9
|
+
from ..visitors import ContentTransform
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
T = ta.TypeVar('T')
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dc.dataclass(frozen=True)
|
|
19
|
+
class StringFnContentTransform(ContentTransform[None]):
|
|
20
|
+
fn: ta.Callable[[str], str]
|
|
21
|
+
|
|
22
|
+
def visit_str(self, c: str, ctx: None) -> TextContent:
|
|
23
|
+
return TextContent(self.fn(c)).with_metadata(ContentOriginal(c))
|
|
24
|
+
|
|
25
|
+
def visit_text_content(self, c: TextContent, ctx: None) -> TextContent:
|
|
26
|
+
return c.replace(s=self.fn(c.s))
|
|
27
|
+
|
|
28
|
+
def visit_emphasis_content(self, c: EmphasisContent, ctx: None) -> EmphasisContent:
|
|
29
|
+
return c.replace(s=self.fn(c.s))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def transform_content_strings(fn: ta.Callable[[str], str], o: Content) -> Content:
|
|
33
|
+
return StringFnContentTransform(fn).visit(o, None)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from omlish import check
|
|
2
|
+
from omlish.text import templating as tpl
|
|
3
|
+
|
|
4
|
+
from ..content import Content
|
|
5
|
+
from ..metadata import ContentOriginal
|
|
6
|
+
from ..templates import TemplateContent
|
|
7
|
+
from ..text import TextContent
|
|
8
|
+
from ..visitors import ContentTransform
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TemplateContentMaterializer(ContentTransform[None]):
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
templater_context: tpl.Templater.Context | None = None,
|
|
18
|
+
) -> None:
|
|
19
|
+
super().__init__()
|
|
20
|
+
|
|
21
|
+
self._templater_context = templater_context
|
|
22
|
+
|
|
23
|
+
def visit_template_content(self, c: TemplateContent, ctx: None) -> Content:
|
|
24
|
+
s = c.t.render(check.not_none(self._templater_context))
|
|
25
|
+
return TextContent(s).with_metadata(ContentOriginal(c))
|