ommlds 0.0.0.dev494__py3-none-any.whl → 0.0.0.dev496__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 (85) hide show
  1. ommlds/cli/_dataclasses.py +7 -7
  2. ommlds/cli/backends/inject.py +49 -8
  3. ommlds/cli/backends/meta.py +35 -0
  4. ommlds/cli/content/messages.py +1 -1
  5. ommlds/cli/inject.py +1 -1
  6. ommlds/cli/sessions/chat/drivers/{driver.py → impl.py} +2 -9
  7. ommlds/cli/sessions/chat/drivers/inject.py +5 -3
  8. ommlds/cli/sessions/chat/drivers/state/inject.py +2 -3
  9. ommlds/cli/sessions/chat/drivers/tools/injection.py +4 -4
  10. ommlds/cli/sessions/chat/drivers/types.py +21 -0
  11. ommlds/cli/sessions/chat/drivers/user/inject.py +4 -3
  12. ommlds/cli/sessions/chat/facades/commands/inject.py +0 -2
  13. ommlds/cli/sessions/chat/facades/commands/simple.py +2 -8
  14. ommlds/cli/sessions/chat/facades/facade.py +1 -1
  15. ommlds/cli/sessions/chat/facades/inject.py +5 -0
  16. ommlds/cli/sessions/chat/facades/ui.py +11 -0
  17. ommlds/cli/sessions/chat/interfaces/bare/interactive.py +1 -1
  18. ommlds/cli/sessions/chat/interfaces/bare/oneshot.py +1 -1
  19. ommlds/cli/sessions/chat/interfaces/textual/app.py +21 -3
  20. ommlds/cli/sessions/chat/interfaces/textual/inject.py +2 -5
  21. ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +2 -0
  22. ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +12 -5
  23. ommlds/minichain/__init__.py +81 -35
  24. ommlds/minichain/_dataclasses.py +7688 -3344
  25. ommlds/minichain/backends/impls/anthropic/protocol.py +2 -2
  26. ommlds/minichain/backends/impls/cerebras/protocol.py +2 -2
  27. ommlds/minichain/backends/impls/google/tools.py +2 -2
  28. ommlds/minichain/backends/impls/groq/protocol.py +2 -2
  29. ommlds/minichain/backends/impls/ollama/protocol.py +2 -2
  30. ommlds/minichain/backends/impls/openai/format.py +2 -2
  31. ommlds/minichain/backends/strings/resolving.py +1 -1
  32. ommlds/minichain/chat/messages.py +22 -25
  33. ommlds/minichain/chat/templating.py +1 -1
  34. ommlds/minichain/content/__init__.py +9 -2
  35. ommlds/minichain/content/_marshal.py +162 -49
  36. ommlds/minichain/content/code.py +17 -0
  37. ommlds/minichain/content/dynamic.py +12 -0
  38. ommlds/minichain/content/images.py +3 -2
  39. ommlds/minichain/content/json.py +3 -2
  40. ommlds/minichain/content/namespaces.py +9 -0
  41. ommlds/minichain/content/placeholders.py +11 -9
  42. ommlds/minichain/content/quote.py +17 -0
  43. ommlds/minichain/content/raw.py +49 -0
  44. ommlds/minichain/content/section.py +14 -0
  45. ommlds/minichain/content/sequence.py +7 -2
  46. ommlds/minichain/content/{simple.py → standard.py} +3 -13
  47. ommlds/minichain/content/tag.py +19 -0
  48. ommlds/minichain/content/templates.py +14 -0
  49. ommlds/minichain/content/text.py +3 -2
  50. ommlds/minichain/content/transform/base.py +63 -0
  51. ommlds/minichain/content/transform/interleave.py +68 -0
  52. ommlds/minichain/content/transform/materialize.py +110 -0
  53. ommlds/minichain/content/{prepare.py → transform/prepare.py} +12 -13
  54. ommlds/minichain/content/transform/squeeze.py +59 -0
  55. ommlds/minichain/content/{transforms → transform}/stringify.py +0 -6
  56. ommlds/minichain/content/types.py +5 -17
  57. ommlds/minichain/lib/fs/tools/read.py +1 -1
  58. ommlds/minichain/lib/fs/tools/recursivels/rendering.py +1 -1
  59. ommlds/minichain/lib/fs/tools/recursivels/running.py +1 -1
  60. ommlds/minichain/lib/todo/tools/write.py +2 -1
  61. ommlds/minichain/lib/todo/types.py +1 -1
  62. ommlds/minichain/meta/__init__.py +0 -0
  63. ommlds/minichain/meta/firstinwins.py +131 -0
  64. ommlds/minichain/text/applypatch.py +2 -1
  65. ommlds/minichain/text/toolparsing/llamacpp/types.py +1 -1
  66. ommlds/minichain/tokens/specials.py +1 -1
  67. ommlds/minichain/tools/execution/errorhandling.py +35 -0
  68. ommlds/minichain/tools/execution/errors.py +2 -2
  69. ommlds/minichain/tools/jsonschema.py +2 -2
  70. ommlds/minichain/tools/reflect.py +3 -3
  71. ommlds/minichain/tools/types.py +11 -14
  72. ommlds/minichain/vectors/_marshal.py +1 -1
  73. {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev496.dist-info}/METADATA +4 -4
  74. {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev496.dist-info}/RECORD +80 -70
  75. ommlds/cli/sessions/chat/interfaces/bare/user.py +0 -31
  76. ommlds/minichain/content/materialize.py +0 -196
  77. ommlds/minichain/content/transforms/base.py +0 -46
  78. ommlds/minichain/content/transforms/interleave.py +0 -70
  79. ommlds/minichain/content/transforms/squeeze.py +0 -72
  80. /ommlds/minichain/content/{transforms → transform}/__init__.py +0 -0
  81. /ommlds/minichain/content/{transforms → transform}/strings.py +0 -0
  82. {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev496.dist-info}/WHEEL +0 -0
  83. {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev496.dist-info}/entry_points.txt +0 -0
  84. {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev496.dist-info}/licenses/LICENSE +0 -0
  85. {ommlds-0.0.0.dev494.dist-info → ommlds-0.0.0.dev496.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,17 @@
1
+ """
2
+ TODO:
3
+ - attribution
4
+ """
5
+ from omlish import dataclasses as dc
6
+ from omlish import lang
7
+
8
+ from .standard import StandardContent
9
+ from .types import Content
10
+
11
+
12
+ ##
13
+
14
+
15
+ @dc.dataclass(frozen=True)
16
+ class QuoteContent(StandardContent, lang.Final):
17
+ body: Content
@@ -0,0 +1,49 @@
1
+ import typing as ta
2
+
3
+ from .images import ImageContent
4
+ from .text import TextContent
5
+
6
+
7
+ ##
8
+
9
+
10
+ NonStrSingleRawContent: ta.TypeAlias = ta.Union[ # noqa
11
+ TextContent,
12
+ ImageContent,
13
+ ]
14
+
15
+
16
+ NON_STR_SINGLE_RAW_CONTENT_TYPES: tuple[type, ...] = (
17
+ TextContent,
18
+ ImageContent,
19
+ )
20
+
21
+
22
+ #
23
+
24
+
25
+ SingleRawContent: ta.TypeAlias = ta.Union[ # noqa
26
+ str,
27
+ NonStrSingleRawContent,
28
+ ]
29
+
30
+
31
+ SINGLE_RAW_CONTENT_TYPES: tuple[type, ...] = (
32
+ str,
33
+ *NON_STR_SINGLE_RAW_CONTENT_TYPES,
34
+ )
35
+
36
+
37
+ #
38
+
39
+
40
+ RawContent: ta.TypeAlias = ta.Union[ # noqa
41
+ SingleRawContent,
42
+ ta.Sequence[SingleRawContent],
43
+ ]
44
+
45
+
46
+ RAW_CONTENT_TYPES: tuple[type, ...] = (
47
+ *SINGLE_RAW_CONTENT_TYPES,
48
+ ta.Sequence,
49
+ )
@@ -0,0 +1,14 @@
1
+ from omlish import dataclasses as dc
2
+ from omlish import lang
3
+
4
+ from .standard import StandardContent
5
+ from .types import Content
6
+
7
+
8
+ ##
9
+
10
+
11
+ @dc.dataclass(frozen=True)
12
+ class SectionContent(StandardContent, lang.Final):
13
+ header: str
14
+ body: Content
@@ -8,7 +8,7 @@ import typing as ta
8
8
  from omlish import dataclasses as dc
9
9
  from omlish import lang
10
10
 
11
- from .simple import SimpleExtendedContent
11
+ from .standard import StandardContent
12
12
  from .types import Content
13
13
 
14
14
 
@@ -16,7 +16,7 @@ from .types import Content
16
16
 
17
17
 
18
18
  @dc.dataclass(frozen=True)
19
- class SequenceContent(SimpleExtendedContent, lang.Abstract):
19
+ class SequenceContent(StandardContent, lang.Abstract):
20
20
  l: ta.Sequence[Content]
21
21
 
22
22
 
@@ -28,3 +28,8 @@ class InlineContent(SequenceContent, lang.Final):
28
28
  @dc.dataclass(frozen=True)
29
29
  class BlockContent(SequenceContent, lang.Final):
30
30
  pass
31
+
32
+
33
+ @dc.dataclass(frozen=True)
34
+ class ItemListContent(SequenceContent, lang.Final):
35
+ pass
@@ -8,17 +8,16 @@ from omlish import typedvalues as tv
8
8
  from .._typedvalues import _tv_field_metadata
9
9
  from ..metadata import MetadataContainer
10
10
  from .metadata import ContentMetadatas
11
- from .types import ExtendedContent
12
- from .types import SingleExtendedContent
11
+ from .types import BaseContent
13
12
 
14
13
 
15
14
  ##
16
15
 
17
16
 
18
17
  @dc.dataclass(frozen=True)
19
- class SimpleExtendedContent( # noqa
18
+ class StandardContent( # noqa
20
19
  MetadataContainer[ContentMetadatas],
21
- ExtendedContent,
20
+ BaseContent,
22
21
  lang.Abstract,
23
22
  ):
24
23
  _metadata: ta.Sequence[ContentMetadatas] = dc.field(
@@ -36,12 +35,3 @@ class SimpleExtendedContent( # noqa
36
35
 
37
36
  def with_metadata(self, *mds: ContentMetadatas, override: bool = False) -> ta.Self:
38
37
  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
@@ -0,0 +1,19 @@
1
+ """
2
+ TODO:
3
+ - track BlockContent nesting depth?
4
+ - section names? dedicated 'section' content with header and body?
5
+ """
6
+ from omlish import dataclasses as dc
7
+ from omlish import lang
8
+
9
+ from .standard import StandardContent
10
+ from .types import Content
11
+
12
+
13
+ ##
14
+
15
+
16
+ @dc.dataclass(frozen=True)
17
+ class TagContent(StandardContent, lang.Final):
18
+ tag: str
19
+ body: Content
@@ -0,0 +1,14 @@
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
+ from .types import LeafContent
7
+
8
+
9
+ ##
10
+
11
+
12
+ @dc.dataclass(frozen=True)
13
+ class TemplateContent(DynamicContent, LeafContent, lang.Final):
14
+ t: tpl.Templater
@@ -1,12 +1,13 @@
1
1
  from omlish import dataclasses as dc
2
2
  from omlish import lang
3
3
 
4
- from .simple import SimpleSingleExtendedContent
4
+ from .standard import StandardContent
5
+ from .types import LeafContent
5
6
 
6
7
 
7
8
  ##
8
9
 
9
10
 
10
11
  @dc.dataclass(frozen=True)
11
- class TextContent(SimpleSingleExtendedContent, lang.Final):
12
+ class TextContent(StandardContent, LeafContent, lang.Final):
12
13
  s: str
@@ -0,0 +1,63 @@
1
+ import collections.abc
2
+
3
+ from omlish import dataclasses as dc
4
+ from omlish import dispatch
5
+ from omlish import lang
6
+
7
+ from ..quote import QuoteContent
8
+ from ..section import SectionContent
9
+ from ..sequence import SequenceContent
10
+ from ..tag import TagContent
11
+ from ..text import TextContent
12
+ from ..types import Content
13
+ from ..types import LeafContent
14
+
15
+
16
+ ##
17
+
18
+
19
+ class ContentTransform(lang.Abstract):
20
+ @dispatch.method()
21
+ def apply(self, o: Content) -> Content:
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) -> collections.abc.Sequence:
32
+ # FIXME: this should be `Sequence[Content] -> Sequence[Content]` but omlish.reflect can't handle recursive
33
+ # ForwardRef's yet
34
+ r = [self.apply(e) for e in l]
35
+ if len(r) == len(l) and all(le is re for le, re in zip(l, r)):
36
+ return l
37
+ return r
38
+
39
+ #
40
+
41
+ @apply.register
42
+ def apply_leaf_content(self, c: LeafContent) -> LeafContent:
43
+ return c
44
+
45
+ @apply.register
46
+ def apply_quote_content(self, c: QuoteContent) -> QuoteContent:
47
+ return dc.replace_is_not(c, l=self.apply(c.body))
48
+
49
+ @apply.register
50
+ def apply_section_content(self, c: SectionContent) -> SectionContent:
51
+ return dc.replace_is_not(c, l=self.apply(c.body))
52
+
53
+ @apply.register
54
+ def apply_sequence_content(self, c: SequenceContent) -> SequenceContent:
55
+ return dc.replace_is_not(c, l=self.apply(c.l))
56
+
57
+ @apply.register
58
+ def apply_tag_content(self, c: TagContent) -> TagContent:
59
+ return dc.replace_is_not(c, c=self.apply(c.body))
60
+
61
+ @apply.register
62
+ def apply_text_content(self, c: TextContent) -> TextContent:
63
+ return dc.replace_is_not(c, s=self.apply(c.s))
@@ -0,0 +1,68 @@
1
+ from ..types import Content
2
+ from .base import ContentTransform
3
+
4
+
5
+ ##
6
+
7
+
8
+ class ContentInterleaver(ContentTransform):
9
+ def __init__(
10
+ self,
11
+ *,
12
+ separator: Content | None = None,
13
+ sequence_separator: Content | None = None,
14
+ inline_separator: Content | None = None,
15
+ block_separator: Content | None = None,
16
+ ) -> None:
17
+ super().__init__()
18
+
19
+ self._sequence_separator = sequence_separator if sequence_separator is not None else separator
20
+ self._inline_separator = inline_separator if inline_separator is not None else separator
21
+ self._block_separator = block_separator if block_separator is not None else separator
22
+
23
+ # def _interleave(self, l: ta.Iterable[Content], separator: Content | None) -> ta.Sequence[Content]:
24
+ # cs: ta.Iterable[Content] = map(self.interleave, l)
25
+ # if separator is not None:
26
+ # cs = lang.interleave(cs, separator)
27
+ # return list(cs)
28
+
29
+ # @dispatch.method()
30
+ # def interleave(self, c: Content) -> Content:
31
+ # raise TypeError(c)
32
+
33
+ # @interleave.register
34
+ # def interleave_str(self, c: str) -> Content:
35
+ # return c
36
+
37
+ # @interleave.register
38
+ # def interleave_sequence(self, c: ta.Sequence) -> Content:
39
+ # return self._interleave(c, self._sequence_separator)
40
+
41
+ # @interleave.register
42
+ # def interleave_extended_content(self, c: BaseContent) -> Content:
43
+ # # FIXME:
44
+ # return c
45
+
46
+ # @interleave.register
47
+ # def interleave_inline_content(self, c: InlineContent) -> Content:
48
+ # return dc.replace(c, l=self._interleave(c.l, self._inline_separator))
49
+
50
+ # @interleave.register
51
+ # def interleave_block_content(self, c: BlockContent) -> Content:
52
+ # return dc.replace(c, l=self._interleave(c.l, self._block_separator))
53
+
54
+
55
+ def interleave_content(
56
+ c: Content,
57
+ *,
58
+ separator: Content | None = None,
59
+ sequence_separator: Content | None = None,
60
+ inline_separator: Content | None = None,
61
+ block_separator: Content | None = None,
62
+ ) -> Content:
63
+ return ContentInterleaver(
64
+ separator=separator,
65
+ sequence_separator=sequence_separator,
66
+ inline_separator=inline_separator,
67
+ block_separator=block_separator,
68
+ ).apply(c)
@@ -0,0 +1,110 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+ from omlish import dataclasses as dc
5
+ from omlish.text import templating as tpl
6
+
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
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 ContentDepthExceededError(Exception):
55
+ pass
56
+
57
+
58
+ class ContentMaterializer(ContentTransform):
59
+ DEFAULT_MAX_DEPTH: int = 8
60
+
61
+ def __init__(
62
+ self,
63
+ *,
64
+ placeholder_contents: PlaceholderContents | None = None,
65
+ templater_context: tpl.Templater.Context | None = None,
66
+ max_depth: int = DEFAULT_MAX_DEPTH,
67
+ ) -> None:
68
+ super().__init__()
69
+
70
+ 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
+
96
+ @ContentTransform.apply.register
97
+ def apply_placeholder_content(self, c: PlaceholderContent) -> Content:
98
+ return self.recurse(self._placeholder_content_fn(c.k))
99
+
100
+
101
+ def materialize_content(
102
+ o: Content,
103
+ *,
104
+ placeholder_contents: PlaceholderContents | None = None,
105
+ templater_context: tpl.Templater.Context | None = None,
106
+ ) -> Content:
107
+ return ContentMaterializer(
108
+ placeholder_contents=placeholder_contents,
109
+ templater_context=templater_context,
110
+ ).apply(o)
@@ -1,19 +1,18 @@
1
1
  """
2
2
  TODO:
3
- - re-softwrap
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 .materialize import CanContent
11
+ from ..types import Content
12
+ from .interleave import interleave_content
12
13
  from .materialize import materialize_content
13
- from .transforms.interleave import interleave_content
14
- from .transforms.squeeze import squeeze_content
15
- from .transforms.stringify import stringify_content
16
- from .types import Content
14
+ from .squeeze import squeeze_content
15
+ from .stringify import stringify_content
17
16
 
18
17
 
19
18
  ##
@@ -21,13 +20,13 @@ from .types import Content
21
20
 
22
21
  class ContentPreparer(lang.Abstract):
23
22
  @abc.abstractmethod
24
- def prepare(self, c: CanContent) -> Content:
23
+ def prepare(self, c: Content) -> Content:
25
24
  raise NotImplementedError
26
25
 
27
26
 
28
27
  class ContentStrPreparer(lang.Abstract):
29
28
  @abc.abstractmethod
30
- def prepare_str(self, c: CanContent) -> str:
29
+ def prepare_str(self, c: Content) -> str:
31
30
  raise NotImplementedError
32
31
 
33
32
 
@@ -44,7 +43,7 @@ class DefaultContentPreparer(ContentPreparer):
44
43
  strip_strings: bool = True
45
44
  block_separator: Content = DEFAULT_BLOCK_SEPARATOR
46
45
 
47
- def prepare(self, c: CanContent) -> Content:
46
+ def prepare(self, c: Content) -> Content:
48
47
  c = materialize_content(c)
49
48
  c = squeeze_content(c, strip_strings=self.strip_strings)
50
49
  c = interleave_content(c, block_separator=self.block_separator)
@@ -55,7 +54,7 @@ class DefaultContentPreparer(ContentPreparer):
55
54
  class DefaultContentStrPreparer(ContentStrPreparer):
56
55
  content_preparer: ContentPreparer
57
56
 
58
- def prepare_str(self, c: CanContent) -> str:
57
+ def prepare_str(self, c: Content) -> str:
59
58
  return stringify_content(self.content_preparer.prepare(c))
60
59
 
61
60
 
@@ -70,9 +69,9 @@ def default_content_str_preparer(**kwargs: ta.Any) -> ContentStrPreparer:
70
69
  return DefaultContentStrPreparer(DefaultContentPreparer(**kwargs))
71
70
 
72
71
 
73
- def prepare_content(c: CanContent, **kwargs: ta.Any) -> Content:
72
+ def prepare_content(c: Content, **kwargs: ta.Any) -> Content:
74
73
  return default_content_preparer(**kwargs).prepare(c)
75
74
 
76
75
 
77
- def prepare_content_str(c: CanContent, **kwargs: ta.Any) -> str:
76
+ def prepare_content_str(c: Content, **kwargs: ta.Any) -> str:
78
77
  return default_content_str_preparer(**kwargs).prepare_str(c)
@@ -0,0 +1,59 @@
1
+ import typing as ta
2
+
3
+ from ..types import Content
4
+ from .base import ContentTransform
5
+
6
+
7
+ ##
8
+
9
+
10
+ class ContentSqueezer(ContentTransform):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ strip_strings: bool = False,
15
+ ) -> None:
16
+ super().__init__()
17
+
18
+ self._strip_strings = strip_strings
19
+
20
+ @ContentTransform.apply.register
21
+ def squeeze_str(self, c: str) -> ta.Iterable[Content]:
22
+ if self._strip_strings:
23
+ c = c.strip()
24
+ return c
25
+
26
+ # @squeeze.register
27
+ # def squeeze_sequence(self, c: ta.Sequence) -> ta.Iterable[Content]:
28
+ # for e in c:
29
+ # yield from self.squeeze(e)
30
+
31
+ # #
32
+
33
+ # # @squeeze.register
34
+ # # def squeeze_single_content(self, c: Content) -> ta.Iterable[Content]:
35
+ # # return [c]
36
+
37
+ # @squeeze.register
38
+ # def squeeze_text_content(self, c: TextContent) -> ta.Iterable[Content]:
39
+ # if self._strip_strings:
40
+ # if (ss := c.s.strip()) != c.s:
41
+ # c = dc.replace(c, s=ss)
42
+ #
43
+ # if c.s:
44
+ # yield c.s
45
+
46
+ # @squeeze.register
47
+ # def squeeze_sequence_content(self, c: SequenceContent) -> ta.Iterable[Content]:
48
+ # for e in c.l:
49
+ # yield from self.squeeze(e)
50
+
51
+
52
+ def squeeze_content(
53
+ c: Content,
54
+ *,
55
+ strip_strings: bool = False,
56
+ ) -> Content:
57
+ return ContentSqueezer(
58
+ strip_strings=strip_strings,
59
+ ).apply(c)
@@ -3,7 +3,6 @@ import typing as ta
3
3
 
4
4
  from omlish import dispatch
5
5
 
6
- from ..sequence import SequenceContent
7
6
  from ..text import TextContent
8
7
  from ..types import Content
9
8
 
@@ -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
@@ -6,11 +6,11 @@ from omlish import lang
6
6
  ##
7
7
 
8
8
 
9
- class ExtendedContent(lang.Abstract, lang.PackageSealed):
9
+ class BaseContent(lang.Abstract, lang.PackageSealed):
10
10
  pass
11
11
 
12
12
 
13
- class SingleExtendedContent(ExtendedContent, lang.Abstract):
13
+ class LeafContent(BaseContent, lang.Abstract):
14
14
  pass
15
15
 
16
16
 
@@ -19,25 +19,13 @@ class SingleExtendedContent(ExtendedContent, lang.Abstract):
19
19
 
20
20
  Content: ta.TypeAlias = ta.Union[ # noqa
21
21
  str,
22
- ExtendedContent,
22
+ BaseContent,
23
23
  ta.Sequence['Content'],
24
24
  ]
25
25
 
26
26
 
27
- CONTENT_RUNTIME_TYPES: tuple[type, ...] = (
27
+ CONTENT_TYPES: tuple[type, ...] = (
28
28
  str,
29
+ BaseContent,
29
30
  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
31
  )
@@ -27,7 +27,7 @@ MAX_LINE_LENGTH = 2_000
27
27
 
28
28
  @tool_spec_override(
29
29
  desc=f"""
30
- Reads a file from the local filesystem. You can access any file directly by using this tool.
30
+ Reads a file from the local filesystem. You can access any file directly by using this tool.
31
31
 
32
32
  Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that
33
33
  path is valid. It is okay to read a file that does not exist; an error will be returned.
@@ -5,10 +5,10 @@ TODO:
5
5
  - any directory with unlisted children will be suffixed inline with '...'
6
6
  - absence of '...' indicates an empty directory
7
7
  """
8
- import dataclasses as dc
9
8
  import typing as ta
10
9
 
11
10
  from omlish import check
11
+ from omlish import dataclasses as dc
12
12
  from omlish import lang
13
13
 
14
14
  from .running import DirLsItem
@@ -1,8 +1,8 @@
1
- import dataclasses as dc
2
1
  import os.path
3
2
  import typing as ta
4
3
 
5
4
  from omlish import check
5
+ from omlish import dataclasses as dc
6
6
  from omlish import lang
7
7
 
8
8
 
@@ -8,6 +8,7 @@ from omlish import lang
8
8
  from omlish import marshal as msh
9
9
 
10
10
  from ....content.namespaces import ContentNamespace
11
+ from ....content.namespaces import NamespaceContent
11
12
  from ....tools.execution.catalog import ToolCatalogEntry
12
13
  from ....tools.execution.reflect import reflect_tool_catalog_entry
13
14
  from ....tools.reflect import tool_spec_override
@@ -311,7 +312,7 @@ class TodoWriteDescriptionChunks(ContentNamespace):
311
312
 
312
313
 
313
314
  @tool_spec_override(
314
- desc=TodoWriteDescriptionChunks,
315
+ desc=NamespaceContent(TodoWriteDescriptionChunks),
315
316
  )
316
317
  def execute_todo_write_tool(todo_items: ta.Sequence[TodoItem]) -> ta.Sequence[TodoItem]:
317
318
  if todo_items: