ommlds 0.0.0.dev496__py3-none-any.whl → 0.0.0.dev498__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.
Files changed (62) hide show
  1. ommlds/.omlish-manifests.json +1 -1
  2. ommlds/cli/main.py +2 -2
  3. ommlds/cli/secrets.py +1 -1
  4. ommlds/minichain/__init__.py +45 -9
  5. ommlds/minichain/_dataclasses.py +1229 -1071
  6. ommlds/minichain/_typedvalues.py +11 -4
  7. ommlds/minichain/chat/content.py +42 -0
  8. ommlds/minichain/chat/messages.py +21 -14
  9. ommlds/minichain/chat/stream/types.py +1 -1
  10. ommlds/minichain/chat/templating.py +3 -3
  11. ommlds/minichain/chat/transforms/metadata.py +3 -3
  12. ommlds/minichain/content/__init__.py +10 -1
  13. ommlds/minichain/content/_marshal.py +30 -17
  14. ommlds/minichain/content/code.py +11 -2
  15. ommlds/minichain/content/composite.py +28 -0
  16. ommlds/minichain/content/{types.py → content.py} +0 -4
  17. ommlds/minichain/content/emphasis.py +27 -0
  18. ommlds/minichain/content/images.py +1 -2
  19. ommlds/minichain/content/json.py +1 -2
  20. ommlds/minichain/content/link.py +13 -0
  21. ommlds/minichain/content/markdown.py +12 -0
  22. ommlds/minichain/content/metadata.py +10 -0
  23. ommlds/minichain/content/namespaces.py +2 -3
  24. ommlds/minichain/content/placeholders.py +2 -3
  25. ommlds/minichain/content/quote.py +12 -3
  26. ommlds/minichain/content/recursive.py +12 -0
  27. ommlds/minichain/content/section.py +16 -4
  28. ommlds/minichain/content/sequence.py +13 -4
  29. ommlds/minichain/content/standard.py +10 -15
  30. ommlds/minichain/content/tag.py +12 -3
  31. ommlds/minichain/content/templates.py +1 -2
  32. ommlds/minichain/content/text.py +1 -2
  33. ommlds/minichain/content/transform/json.py +55 -0
  34. ommlds/minichain/content/transform/markdown.py +8 -0
  35. ommlds/minichain/content/transform/materialize.py +19 -78
  36. ommlds/minichain/content/transform/metadata.py +16 -0
  37. ommlds/minichain/content/transform/prepare.py +1 -5
  38. ommlds/minichain/content/transform/recursive.py +97 -0
  39. ommlds/minichain/content/transform/standard.py +43 -0
  40. ommlds/minichain/content/transform/stringify.py +1 -1
  41. ommlds/minichain/content/transform/strings.py +16 -7
  42. ommlds/minichain/content/transform/templates.py +25 -0
  43. ommlds/minichain/content/visitors.py +231 -0
  44. ommlds/minichain/metadata.py +58 -1
  45. ommlds/minichain/tools/execution/catalog.py +1 -1
  46. ommlds/minichain/tools/execution/errorhandling.py +3 -2
  47. ommlds/minichain/tools/execution/errors.py +1 -1
  48. ommlds/minichain/tools/execution/executors.py +1 -1
  49. ommlds/minichain/tools/fns.py +1 -1
  50. ommlds/minichain/tools/reflect.py +1 -1
  51. ommlds/minichain/tools/types.py +1 -1
  52. ommlds/minichain/vectors/embeddings.py +1 -1
  53. ommlds/tools/git.py +74 -63
  54. {ommlds-0.0.0.dev496.dist-info → ommlds-0.0.0.dev498.dist-info}/METADATA +4 -4
  55. {ommlds-0.0.0.dev496.dist-info → ommlds-0.0.0.dev498.dist-info}/RECORD +59 -49
  56. ommlds/minichain/content/transform/base.py +0 -63
  57. ommlds/minichain/content/transform/interleave.py +0 -68
  58. ommlds/minichain/content/transform/squeeze.py +0 -59
  59. {ommlds-0.0.0.dev496.dist-info → ommlds-0.0.0.dev498.dist-info}/WHEEL +0 -0
  60. {ommlds-0.0.0.dev496.dist-info → ommlds-0.0.0.dev498.dist-info}/entry_points.txt +0 -0
  61. {ommlds-0.0.0.dev496.dist-info → ommlds-0.0.0.dev498.dist-info}/licenses/LICENSE +0 -0
  62. {ommlds-0.0.0.dev496.dist-info → ommlds-0.0.0.dev498.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,12 @@
1
1
  import typing as ta
2
2
 
3
- from omlish import check
4
3
  from omlish import dataclasses as dc
5
4
  from omlish import lang
6
- from omlish import typedvalues as tv
7
5
 
8
- from .._typedvalues import _tv_field_metadata
9
- from ..metadata import MetadataContainer
6
+ from ..metadata import MetadataContainerDataclass
7
+ from .content import BaseContent
10
8
  from .metadata import ContentMetadatas
11
- from .types import BaseContent
9
+ from .metadata import ContentOriginal
12
10
 
13
11
 
14
12
  ##
@@ -16,22 +14,19 @@ from .types import BaseContent
16
14
 
17
15
  @dc.dataclass(frozen=True)
18
16
  class StandardContent( # noqa
19
- MetadataContainer[ContentMetadatas],
17
+ MetadataContainerDataclass[ContentMetadatas],
20
18
  BaseContent,
21
19
  lang.Abstract,
22
20
  ):
23
21
  _metadata: ta.Sequence[ContentMetadatas] = dc.field(
24
22
  default=(),
25
23
  kw_only=True,
26
- metadata=_tv_field_metadata(
27
- ContentMetadatas,
28
- marshal_name='metadata',
29
- ),
24
+ repr=False,
30
25
  )
31
26
 
32
- @property
33
- def metadata(self) -> tv.TypedValues[ContentMetadatas]:
34
- return check.isinstance(self._metadata, tv.TypedValues)
27
+ MetadataContainerDataclass._configure_metadata_field(_metadata, ContentMetadatas) # noqa
35
28
 
36
- def with_metadata(self, *mds: ContentMetadatas, override: bool = False) -> ta.Self:
37
- return dc.replace(self, _metadata=tv.TypedValues(*self._metadata, *mds, override=override))
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.update_metadata(ContentOriginal(self), discard=[ContentOriginal], override=True)
@@ -3,17 +3,26 @@ TODO:
3
3
  - track BlockContent nesting depth?
4
4
  - section names? dedicated 'section' content with header and body?
5
5
  """
6
+ import typing as ta
7
+
8
+ from omlish import check
6
9
  from omlish import dataclasses as dc
7
10
  from omlish import lang
8
11
 
9
- from .standard import StandardContent
10
- from .types import Content
12
+ from .composite import CompositeContent
13
+ from .content import Content
11
14
 
12
15
 
13
16
  ##
14
17
 
15
18
 
16
19
  @dc.dataclass(frozen=True)
17
- class TagContent(StandardContent, lang.Final):
20
+ class TagContent(CompositeContent, lang.Final):
18
21
  tag: str
19
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))
@@ -3,12 +3,11 @@ from omlish import lang
3
3
  from omlish.text import templating as tpl
4
4
 
5
5
  from .dynamic import DynamicContent
6
- from .types import LeafContent
7
6
 
8
7
 
9
8
  ##
10
9
 
11
10
 
12
11
  @dc.dataclass(frozen=True)
13
- class TemplateContent(DynamicContent, LeafContent, lang.Final):
12
+ class TemplateContent(DynamicContent, lang.Final):
14
13
  t: tpl.Templater
@@ -2,12 +2,11 @@ from omlish import dataclasses as dc
2
2
  from omlish import lang
3
3
 
4
4
  from .standard import StandardContent
5
- from .types import LeafContent
6
5
 
7
6
 
8
7
  ##
9
8
 
10
9
 
11
10
  @dc.dataclass(frozen=True)
12
- class TextContent(StandardContent, LeafContent, lang.Final):
11
+ class TextContent(StandardContent, lang.Final):
13
12
  s: str
@@ -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.update_metadata(ContentOriginal(c))
@@ -0,0 +1,8 @@
1
+ # from .base import ContentTransform
2
+ #
3
+ #
4
+ # ##
5
+ #
6
+ #
7
+ # class MarkdownContentTransform(ContentTransform):
8
+ # def apply(self, ):
@@ -1,110 +1,51 @@
1
- import typing as ta
1
+ import abc
2
2
 
3
- from omlish import check
4
- from omlish import dataclasses as dc
3
+ from omlish import lang
5
4
  from omlish.text import templating as tpl
6
5
 
7
- from ..namespaces import ContentNamespace
8
- from ..namespaces import NamespaceContent
9
- from ..placeholders import PlaceholderContent
10
- from ..placeholders import PlaceholderContentKey
11
- from ..types import Content
12
- from .base import ContentTransform
6
+ from ..content import Content
7
+ from .recursive import PlaceholderContents
8
+ from .recursive import RecursiveContentMaterializer
9
+ from .templates import TemplateContentMaterializer
13
10
 
14
11
 
15
12
  ##
16
13
 
17
14
 
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)
15
+ class ContentMaterializer(lang.Abstract):
16
+ @abc.abstractmethod
17
+ def apply(self, c: Content) -> Content:
18
+ raise NotImplementedError
49
19
 
50
20
 
51
21
  ##
52
22
 
53
23
 
54
- class ContentDepthExceededError(Exception):
55
- pass
56
-
57
-
58
- class ContentMaterializer(ContentTransform):
59
- DEFAULT_MAX_DEPTH: int = 8
60
-
24
+ class DefaultContentMaterializer(ContentMaterializer):
61
25
  def __init__(
62
26
  self,
63
27
  *,
64
28
  placeholder_contents: PlaceholderContents | None = None,
65
29
  templater_context: tpl.Templater.Context | None = None,
66
- max_depth: int = DEFAULT_MAX_DEPTH,
67
30
  ) -> None:
68
31
  super().__init__()
69
32
 
33
+ self._placeholder_contents = placeholder_contents
70
34
  self._templater_context = templater_context
71
- self._placeholder_content_fn = _make_placeholder_content_fn(placeholder_contents)
72
- self._max_depth = max_depth
73
-
74
- self._cur_depth = 0
75
-
76
- def recurse(self, o: Content) -> Content:
77
- if self._cur_depth >= self._max_depth:
78
- raise ContentDepthExceededError
79
-
80
- self._cur_depth += 1
81
- try:
82
- return self.apply(o)
83
- finally:
84
- self._cur_depth -= 1
85
-
86
- @ContentTransform.apply.register
87
- def apply_namespace_content(self, c: NamespaceContent) -> 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))
94
- return out
95
35
 
96
- @ContentTransform.apply.register
97
- def apply_placeholder_content(self, c: PlaceholderContent) -> Content:
98
- return self.recurse(self._placeholder_content_fn(c.k))
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
99
40
 
100
41
 
101
42
  def materialize_content(
102
- o: Content,
43
+ c: Content,
103
44
  *,
104
45
  placeholder_contents: PlaceholderContents | None = None,
105
46
  templater_context: tpl.Templater.Context | None = None,
106
47
  ) -> Content:
107
- return ContentMaterializer(
48
+ return DefaultContentMaterializer(
108
49
  placeholder_contents=placeholder_contents,
109
50
  templater_context=templater_context,
110
- ).apply(o)
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.discard_metadata(ContentOriginal)
13
+
14
+
15
+ def strip_content_original_metadata(c: Content) -> Content:
16
+ return OriginalMetadataStrippingContentTransform().visit(c, None)
@@ -8,10 +8,8 @@ import typing as ta
8
8
  from omlish import dataclasses as dc
9
9
  from omlish import lang
10
10
 
11
- from ..types import Content
12
- from .interleave import interleave_content
11
+ from ..content import Content
13
12
  from .materialize import materialize_content
14
- from .squeeze import squeeze_content
15
13
  from .stringify import stringify_content
16
14
 
17
15
 
@@ -45,8 +43,6 @@ class DefaultContentPreparer(ContentPreparer):
45
43
 
46
44
  def prepare(self, c: Content) -> Content:
47
45
  c = materialize_content(c)
48
- c = squeeze_content(c, strip_strings=self.strip_strings)
49
- c = interleave_content(c, block_separator=self.block_separator)
50
46
  return c
51
47
 
52
48
 
@@ -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).update_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.update_metadata(ContentOriginal(c))
@@ -3,8 +3,8 @@ import typing as ta
3
3
 
4
4
  from omlish import dispatch
5
5
 
6
+ from ..content import Content
6
7
  from ..text import TextContent
7
- from ..types import Content
8
8
 
9
9
 
10
10
  ##
@@ -2,7 +2,11 @@ import typing as ta
2
2
 
3
3
  from omlish import dataclasses as dc
4
4
 
5
- from .base import ContentTransform
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
6
10
 
7
11
 
8
12
  T = ta.TypeVar('T')
@@ -12,13 +16,18 @@ T = ta.TypeVar('T')
12
16
 
13
17
 
14
18
  @dc.dataclass(frozen=True)
15
- class StringFnContentTransform(ContentTransform):
19
+ class StringFnContentTransform(ContentTransform[None]):
16
20
  fn: ta.Callable[[str], str]
17
21
 
18
- @ContentTransform.apply.register # noqa
19
- def apply_str(self, s: str) -> str:
20
- return self.fn(s)
22
+ def visit_str(self, c: str, ctx: None) -> TextContent:
23
+ return TextContent(self.fn(c)).update_metadata(ContentOriginal(c))
21
24
 
25
+ def visit_text_content(self, c: TextContent, ctx: None) -> TextContent:
26
+ return c.replace(s=self.fn(c.s))
22
27
 
23
- def transform_content_strings(fn: ta.Callable[[str], str], o: T) -> T:
24
- return StringFnContentTransform(fn).apply(o)
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).update_metadata(ContentOriginal(c))