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
@@ -3,9 +3,9 @@ TODO:
3
3
  - enums lol
4
4
  - * with ToolParam-like desc metadata somehow *
5
5
  """
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
11
  from ...tools.reflect import tool_param_metadata
File without changes
@@ -0,0 +1,131 @@
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 ..services.requests import Request
8
+ from ..services.responses import Response
9
+ from ..services.services import Service
10
+ from ..types import Option
11
+ from ..types import Output
12
+
13
+
14
+ with lang.auto_proxy_import(globals()):
15
+ import asyncio
16
+
17
+
18
+ RequestV = ta.TypeVar('RequestV')
19
+ OptionT = ta.TypeVar('OptionT', bound=Option)
20
+
21
+ ResponseV = ta.TypeVar('ResponseV')
22
+ OutputT = ta.TypeVar('OutputT', bound=Output)
23
+
24
+
25
+ ##
26
+
27
+
28
+ @dc.dataclass(frozen=True)
29
+ class FirstInWinsServiceCancelledError(Exception):
30
+ e: BaseException
31
+
32
+
33
+ class FirstInWinsServiceExceptionGroup(ExceptionGroup):
34
+ pass
35
+
36
+
37
+ @dc.dataclass(frozen=True)
38
+ class FirstInWinsServiceOutput(Output):
39
+ first_in_wins_service: 'FirstInWinsService'
40
+ response_service: Service
41
+ service_exceptions: ta.Mapping[Service, Exception] | None = None
42
+
43
+
44
+ class FirstInWinsService(
45
+ lang.Abstract,
46
+ ta.Generic[
47
+ RequestV,
48
+ OptionT,
49
+ ResponseV,
50
+ OutputT,
51
+ ],
52
+ ):
53
+ def __init__(
54
+ self,
55
+ *services: Service[
56
+ Request[
57
+ RequestV,
58
+ OptionT,
59
+ ],
60
+ Response[
61
+ ResponseV,
62
+ OutputT,
63
+ ],
64
+ ],
65
+ ) -> None:
66
+ super().__init__()
67
+
68
+ self._services = check.not_empty(services)
69
+
70
+
71
+ ##
72
+
73
+
74
+ class AsyncioFirstInWinsService(
75
+ FirstInWinsService[
76
+ RequestV,
77
+ OptionT,
78
+ ResponseV,
79
+ OutputT,
80
+ ],
81
+ ):
82
+ async def invoke(self, request: Request[RequestV, OptionT]) -> Response[ResponseV, OutputT]:
83
+ tasks: list = []
84
+ services_by_task: dict = {}
85
+ for svc in self._services:
86
+ task: asyncio.Task = asyncio.create_task(svc.invoke(request)) # type: ignore[arg-type]
87
+ tasks.append(task)
88
+ services_by_task[task] = svc
89
+
90
+ failures_by_service: dict[Service, Exception] = {}
91
+
92
+ try:
93
+ pending = set(tasks)
94
+
95
+ while pending:
96
+ done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
97
+
98
+ for t in done:
99
+ svc = services_by_task[t]
100
+
101
+ try:
102
+ response = t.result()
103
+ except asyncio.CancelledError as exc:
104
+ failures_by_service[svc] = FirstInWinsServiceCancelledError(exc)
105
+ continue
106
+ except Exception as exc: # noqa
107
+ failures_by_service[svc] = exc
108
+ continue
109
+
110
+ for p in pending:
111
+ p.cancel()
112
+
113
+ await asyncio.gather(*pending, return_exceptions=True)
114
+
115
+ return response.with_outputs(FirstInWinsServiceOutput(
116
+ self,
117
+ svc,
118
+ failures_by_service,
119
+ ))
120
+
121
+ raise FirstInWinsServiceExceptionGroup(
122
+ 'All service calls failed',
123
+ list(failures_by_service.values()),
124
+ )
125
+
126
+ finally:
127
+ for t in tasks:
128
+ if not t.done():
129
+ t.cancel()
130
+
131
+ await asyncio.gather(*tasks, return_exceptions=True)
@@ -20,11 +20,12 @@
20
20
  A self-contained **pure-Python 3.9+** utility for applying human-readable "pseudo-diff" patch files to a collection of
21
21
  text files.
22
22
  """
23
- import dataclasses as dc
24
23
  import enum
25
24
  import pathlib
26
25
  import typing as ta
27
26
 
27
+ from omlish import dataclasses as dc
28
+
28
29
 
29
30
  ##
30
31
  # Domain objects
@@ -1,4 +1,4 @@
1
- import dataclasses as dc
1
+ from omlish import dataclasses as dc
2
2
 
3
3
 
4
4
  ##
@@ -1,7 +1,7 @@
1
- import dataclasses as dc
2
1
  import typing as ta
3
2
 
4
3
  from omlish import check
4
+ from omlish import dataclasses as dc
5
5
  from omlish import lang
6
6
 
7
7
  from .types import NonSpecialToken
@@ -0,0 +1,35 @@
1
+ import typing as ta
2
+
3
+ from ...content.transform.materialize import ContentMaterializer
4
+ from ...content.types import Content
5
+ from .context import ToolContext
6
+ from .errors import ToolExecutionError
7
+ from .executors import ToolExecutor
8
+
9
+
10
+ ##
11
+
12
+
13
+ class ErrorHandlingToolExecutor(ToolExecutor):
14
+ def __init__(
15
+ self,
16
+ *,
17
+ wrapped: ToolExecutor,
18
+ content_materializer: ContentMaterializer = ContentMaterializer(),
19
+ ) -> None:
20
+ super().__init__()
21
+
22
+ self._wrapped = wrapped
23
+ self._content_materializer = content_materializer
24
+
25
+ async def execute_tool(
26
+ self,
27
+ ctx: ToolContext,
28
+ name: str,
29
+ args: ta.Mapping[str, ta.Any],
30
+ ) -> Content:
31
+ try:
32
+ return await self._wrapped.execute_tool(ctx, name, args)
33
+
34
+ except ToolExecutionError as txe:
35
+ return self._content_materializer.apply(txe.content)
@@ -2,7 +2,7 @@ import abc
2
2
 
3
3
  from omlish import lang
4
4
 
5
- from ...content.materialize import CanContent
5
+ from ...content.types import Content
6
6
 
7
7
 
8
8
  ##
@@ -11,5 +11,5 @@ from ...content.materialize import CanContent
11
11
  class ToolExecutionError(Exception, lang.Abstract):
12
12
  @property
13
13
  @abc.abstractmethod
14
- def content(self) -> CanContent:
14
+ def content(self) -> Content:
15
15
  raise NotImplementedError
@@ -4,8 +4,8 @@ TODO:
4
4
  """
5
5
  from omlish import check
6
6
 
7
- from ..content.prepare import ContentStrPreparer
8
- from ..content.prepare import default_content_str_preparer
7
+ from ..content.transform.prepare import ContentStrPreparer
8
+ from ..content.transform.prepare import default_content_str_preparer
9
9
  from .types import EnumToolDtype
10
10
  from .types import MappingToolDtype
11
11
  from .types import NullableToolDtype
@@ -23,7 +23,7 @@ from omlish import metadata as md
23
23
  from omlish import reflect as rfl
24
24
  from omlish.lite.cached import cached_nullary
25
25
 
26
- from ..content.materialize import CanContent
26
+ from ..content.types import Content
27
27
  from .types import EnumToolDtype
28
28
  from .types import MappingToolDtype
29
29
  from .types import NullableToolDtype
@@ -159,7 +159,7 @@ class ToolReflector:
159
159
 
160
160
  #
161
161
 
162
- def _prepare_desc(self, s: CanContent) -> CanContent:
162
+ def _prepare_desc(self, s: Content | None) -> Content | None:
163
163
  if s is None:
164
164
  return None
165
165
  if not self._raw_descs and isinstance(s, str):
@@ -240,7 +240,7 @@ class ToolReflector:
240
240
  ds_p = ds_p_dct.get(pn)
241
241
  sig_p = sig_p_dct.get(pn)
242
242
 
243
- p_desc: CanContent
243
+ p_desc: Content | None
244
244
  if (p_desc := ovr_p.get('desc')) is None:
245
245
  if ds_p is not None:
246
246
  p_desc = ds_p.description
@@ -6,13 +6,10 @@ from omlish import cached
6
6
  from omlish import check
7
7
  from omlish import collections as col
8
8
  from omlish import dataclasses as dc
9
- from omlish import dispatch
10
9
  from omlish import lang
11
10
  from omlish import marshal as msh
12
11
  from omlish import reflect as rfl
13
12
 
14
- from ..content.materialize import CanContent
15
- from ..content.transforms.base import ContentTransform
16
13
  from ..content.types import Content
17
14
 
18
15
 
@@ -150,7 +147,7 @@ class ToolParam:
150
147
 
151
148
  _: dc.KW_ONLY
152
149
 
153
- desc: CanContent = None
150
+ desc: Content | None = None
154
151
 
155
152
  type: ToolDtype | None = None
156
153
 
@@ -168,12 +165,12 @@ class ToolSpec:
168
165
 
169
166
  _: dc.KW_ONLY
170
167
 
171
- desc: CanContent = None
168
+ desc: Content | None = None
172
169
 
173
170
  params: ta.Sequence[ToolParam] | None = None
174
171
  allow_additional_params: bool | None = None
175
172
 
176
- returns_desc: CanContent = None
173
+ returns_desc: Content | None = None
177
174
  returns_type: ToolDtype | None = None
178
175
 
179
176
  @cached.property
@@ -207,11 +204,11 @@ class ToolUseResult(lang.Final):
207
204
  ##
208
205
 
209
206
 
210
- class _ToolUseContentTransform(ContentTransform, lang.Final, lang.NotInstantiable):
211
- @dispatch.install_method(ContentTransform.apply)
212
- def apply_tool_use(self, tu: ToolUse) -> ToolUse:
213
- return tu # TODO: args are Content
214
-
215
- @dispatch.install_method(ContentTransform.apply)
216
- def apply_tool_use_result(self, tur: ToolUseResult) -> ToolUseResult:
217
- return dc.replace(tur, c=self.apply(tur.c)) # noqa
207
+ # class _ToolUseContentTransform(ContentTransform, lang.Final, lang.NotInstantiable):
208
+ # @dispatch.install_method(ContentTransform.apply)
209
+ # def apply_tool_use(self, tu: ToolUse) -> ToolUse:
210
+ # return tu # TODO: args are Content
211
+ #
212
+ # @dispatch.install_method(ContentTransform.apply)
213
+ # def apply_tool_use_result(self, tur: ToolUseResult) -> ToolUseResult:
214
+ # return dc.replace(tur, c=self.apply(tur.c)) # noqa
@@ -2,10 +2,10 @@
2
2
  TODO:
3
3
  - serialize as base64 bytes? at least support deserializing as it
4
4
  """
5
- import dataclasses as dc
6
5
  import typing as ta
7
6
 
8
7
  from omlish import check
8
+ from omlish import dataclasses as dc
9
9
  from omlish import lang
10
10
  from omlish import marshal as msh
11
11
  from omlish import reflect as rfl
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommlds
3
- Version: 0.0.0.dev494
3
+ Version: 0.0.0.dev496
4
4
  Summary: ommlds
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,9 +14,9 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: omlish==0.0.0.dev494
17
+ Requires-Dist: omlish==0.0.0.dev496
18
18
  Provides-Extra: all
19
- Requires-Dist: omdev==0.0.0.dev494; extra == "all"
19
+ Requires-Dist: omdev==0.0.0.dev496; extra == "all"
20
20
  Requires-Dist: llama-cpp-python~=0.3; extra == "all"
21
21
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "all"
22
22
  Requires-Dist: mlx-lm~=0.29; sys_platform == "darwin" and extra == "all"
@@ -38,7 +38,7 @@ Requires-Dist: mwparserfromhell~=0.7; extra == "all"
38
38
  Requires-Dist: wikitextparser~=0.56; extra == "all"
39
39
  Requires-Dist: lxml>=5.3; python_version < "3.13" and extra == "all"
40
40
  Provides-Extra: omdev
41
- Requires-Dist: omdev==0.0.0.dev494; extra == "omdev"
41
+ Requires-Dist: omdev==0.0.0.dev496; extra == "omdev"
42
42
  Provides-Extra: backends
43
43
  Requires-Dist: llama-cpp-python~=0.3; extra == "backends"
44
44
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "backends"