ommlds 0.0.0.dev426__py3-none-any.whl → 0.0.0.dev485__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 (295) hide show
  1. ommlds/.omlish-manifests.json +336 -39
  2. ommlds/__about__.py +16 -10
  3. ommlds/_hacks/__init__.py +4 -0
  4. ommlds/_hacks/funcs.py +110 -0
  5. ommlds/_hacks/names.py +158 -0
  6. ommlds/_hacks/params.py +73 -0
  7. ommlds/_hacks/patches.py +0 -3
  8. ommlds/backends/anthropic/protocol/__init__.py +13 -1
  9. ommlds/backends/anthropic/protocol/_dataclasses.py +1625 -0
  10. ommlds/backends/anthropic/protocol/_marshal.py +2 -2
  11. ommlds/backends/anthropic/protocol/sse/_marshal.py +1 -1
  12. ommlds/backends/anthropic/protocol/sse/assemble.py +23 -7
  13. ommlds/backends/anthropic/protocol/sse/events.py +13 -0
  14. ommlds/backends/anthropic/protocol/types.py +40 -8
  15. ommlds/backends/google/protocol/__init__.py +16 -0
  16. ommlds/backends/google/protocol/_dataclasses.py +5997 -0
  17. ommlds/backends/google/protocol/_marshal.py +16 -0
  18. ommlds/backends/google/protocol/types.py +626 -0
  19. ommlds/backends/groq/__init__.py +7 -0
  20. ommlds/backends/groq/_dataclasses.py +3901 -0
  21. ommlds/backends/groq/_marshal.py +23 -0
  22. ommlds/backends/groq/protocol.py +249 -0
  23. ommlds/backends/llamacpp/logging.py +4 -1
  24. ommlds/backends/mlx/caching.py +7 -3
  25. ommlds/backends/mlx/cli.py +10 -7
  26. ommlds/backends/mlx/generation.py +19 -17
  27. ommlds/backends/mlx/limits.py +10 -6
  28. ommlds/backends/mlx/loading.py +65 -5
  29. ommlds/backends/ollama/__init__.py +7 -0
  30. ommlds/backends/ollama/_dataclasses.py +3458 -0
  31. ommlds/backends/ollama/protocol.py +170 -0
  32. ommlds/backends/openai/protocol/__init__.py +24 -29
  33. ommlds/backends/openai/protocol/_common.py +18 -0
  34. ommlds/backends/openai/protocol/_dataclasses.py +7708 -0
  35. ommlds/backends/openai/protocol/_marshal.py +27 -0
  36. ommlds/backends/openai/protocol/chatcompletion/chunk.py +58 -31
  37. ommlds/backends/openai/protocol/chatcompletion/contentpart.py +49 -44
  38. ommlds/backends/openai/protocol/chatcompletion/message.py +55 -43
  39. ommlds/backends/openai/protocol/chatcompletion/request.py +114 -66
  40. ommlds/backends/openai/protocol/chatcompletion/response.py +71 -45
  41. ommlds/backends/openai/protocol/chatcompletion/responseformat.py +27 -20
  42. ommlds/backends/openai/protocol/chatcompletion/tokenlogprob.py +16 -7
  43. ommlds/backends/openai/protocol/completionusage.py +24 -15
  44. ommlds/backends/tavily/__init__.py +7 -0
  45. ommlds/backends/tavily/_dataclasses.py +1734 -0
  46. ommlds/backends/tavily/protocol.py +301 -0
  47. ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
  48. ommlds/backends/transformers/__init__.py +14 -0
  49. ommlds/backends/transformers/filecache.py +109 -0
  50. ommlds/backends/transformers/streamers.py +73 -0
  51. ommlds/cli/__init__.py +7 -0
  52. ommlds/cli/_dataclasses.py +2562 -0
  53. ommlds/cli/asyncs.py +30 -0
  54. ommlds/cli/backends/catalog.py +93 -0
  55. ommlds/cli/backends/configs.py +9 -0
  56. ommlds/cli/backends/inject.py +31 -36
  57. ommlds/cli/backends/injection.py +16 -0
  58. ommlds/cli/backends/types.py +46 -0
  59. ommlds/cli/content/messages.py +34 -0
  60. ommlds/cli/content/strings.py +42 -0
  61. ommlds/cli/inject.py +17 -32
  62. ommlds/cli/inputs/__init__.py +0 -0
  63. ommlds/cli/inputs/asyncs.py +32 -0
  64. ommlds/cli/inputs/sync.py +75 -0
  65. ommlds/cli/main.py +270 -110
  66. ommlds/cli/rendering/__init__.py +0 -0
  67. ommlds/cli/rendering/configs.py +9 -0
  68. ommlds/cli/rendering/inject.py +31 -0
  69. ommlds/cli/rendering/markdown.py +52 -0
  70. ommlds/cli/rendering/raw.py +73 -0
  71. ommlds/cli/rendering/types.py +21 -0
  72. ommlds/cli/secrets.py +21 -0
  73. ommlds/cli/sessions/base.py +1 -1
  74. ommlds/cli/sessions/chat/chat/__init__.py +0 -0
  75. ommlds/cli/sessions/chat/chat/ai/__init__.py +0 -0
  76. ommlds/cli/sessions/chat/chat/ai/configs.py +11 -0
  77. ommlds/cli/sessions/chat/chat/ai/inject.py +74 -0
  78. ommlds/cli/sessions/chat/chat/ai/injection.py +14 -0
  79. ommlds/cli/sessions/chat/chat/ai/rendering.py +70 -0
  80. ommlds/cli/sessions/chat/chat/ai/services.py +79 -0
  81. ommlds/cli/sessions/chat/chat/ai/tools.py +44 -0
  82. ommlds/cli/sessions/chat/chat/ai/types.py +28 -0
  83. ommlds/cli/sessions/chat/chat/state/__init__.py +0 -0
  84. ommlds/cli/sessions/chat/chat/state/configs.py +11 -0
  85. ommlds/cli/sessions/chat/chat/state/inject.py +36 -0
  86. ommlds/cli/sessions/chat/chat/state/inmemory.py +33 -0
  87. ommlds/cli/sessions/chat/chat/state/storage.py +52 -0
  88. ommlds/cli/sessions/chat/chat/state/types.py +38 -0
  89. ommlds/cli/sessions/chat/chat/user/__init__.py +0 -0
  90. ommlds/cli/sessions/chat/chat/user/configs.py +17 -0
  91. ommlds/cli/sessions/chat/chat/user/inject.py +62 -0
  92. ommlds/cli/sessions/chat/chat/user/interactive.py +31 -0
  93. ommlds/cli/sessions/chat/chat/user/oneshot.py +25 -0
  94. ommlds/cli/sessions/chat/chat/user/types.py +15 -0
  95. ommlds/cli/sessions/chat/configs.py +27 -0
  96. ommlds/cli/sessions/chat/driver.py +43 -0
  97. ommlds/cli/sessions/chat/inject.py +33 -65
  98. ommlds/cli/sessions/chat/phases/__init__.py +0 -0
  99. ommlds/cli/sessions/chat/phases/inject.py +27 -0
  100. ommlds/cli/sessions/chat/phases/injection.py +14 -0
  101. ommlds/cli/sessions/chat/phases/manager.py +29 -0
  102. ommlds/cli/sessions/chat/phases/types.py +29 -0
  103. ommlds/cli/sessions/chat/session.py +27 -0
  104. ommlds/cli/sessions/chat/tools/__init__.py +0 -0
  105. ommlds/cli/sessions/chat/tools/configs.py +22 -0
  106. ommlds/cli/sessions/chat/tools/confirmation.py +46 -0
  107. ommlds/cli/sessions/chat/tools/execution.py +66 -0
  108. ommlds/cli/sessions/chat/tools/fs/__init__.py +0 -0
  109. ommlds/cli/sessions/chat/tools/fs/configs.py +12 -0
  110. ommlds/cli/sessions/chat/tools/fs/inject.py +35 -0
  111. ommlds/cli/sessions/chat/tools/inject.py +88 -0
  112. ommlds/cli/sessions/chat/tools/injection.py +44 -0
  113. ommlds/cli/sessions/chat/tools/rendering.py +58 -0
  114. ommlds/cli/sessions/chat/tools/todo/__init__.py +0 -0
  115. ommlds/cli/sessions/chat/tools/todo/configs.py +12 -0
  116. ommlds/cli/sessions/chat/tools/todo/inject.py +31 -0
  117. ommlds/cli/sessions/chat/tools/weather/__init__.py +0 -0
  118. ommlds/cli/sessions/chat/tools/weather/configs.py +12 -0
  119. ommlds/cli/sessions/chat/tools/weather/inject.py +22 -0
  120. ommlds/cli/{tools/weather.py → sessions/chat/tools/weather/tools.py} +1 -1
  121. ommlds/cli/sessions/completion/configs.py +21 -0
  122. ommlds/cli/sessions/completion/inject.py +42 -0
  123. ommlds/cli/sessions/completion/session.py +35 -0
  124. ommlds/cli/sessions/embedding/configs.py +21 -0
  125. ommlds/cli/sessions/embedding/inject.py +42 -0
  126. ommlds/cli/sessions/embedding/session.py +33 -0
  127. ommlds/cli/sessions/inject.py +28 -11
  128. ommlds/cli/state/__init__.py +0 -0
  129. ommlds/cli/state/inject.py +28 -0
  130. ommlds/cli/{state.py → state/storage.py} +41 -24
  131. ommlds/minichain/__init__.py +84 -24
  132. ommlds/minichain/_dataclasses.py +15401 -0
  133. ommlds/minichain/_marshal.py +49 -9
  134. ommlds/minichain/_typedvalues.py +2 -4
  135. ommlds/minichain/backends/catalogs/base.py +20 -1
  136. ommlds/minichain/backends/catalogs/simple.py +2 -2
  137. ommlds/minichain/backends/catalogs/strings.py +10 -8
  138. ommlds/minichain/backends/impls/anthropic/chat.py +65 -27
  139. ommlds/minichain/backends/impls/anthropic/names.py +10 -8
  140. ommlds/minichain/backends/impls/anthropic/protocol.py +109 -0
  141. ommlds/minichain/backends/impls/anthropic/stream.py +111 -43
  142. ommlds/minichain/backends/impls/duckduckgo/search.py +6 -2
  143. ommlds/minichain/backends/impls/dummy/__init__.py +0 -0
  144. ommlds/minichain/backends/impls/dummy/chat.py +69 -0
  145. ommlds/minichain/backends/impls/google/chat.py +114 -22
  146. ommlds/minichain/backends/impls/google/search.py +7 -2
  147. ommlds/minichain/backends/impls/google/stream.py +219 -0
  148. ommlds/minichain/backends/impls/google/tools.py +149 -0
  149. ommlds/minichain/backends/impls/groq/__init__.py +0 -0
  150. ommlds/minichain/backends/impls/groq/chat.py +75 -0
  151. ommlds/minichain/backends/impls/groq/names.py +48 -0
  152. ommlds/minichain/backends/impls/groq/protocol.py +143 -0
  153. ommlds/minichain/backends/impls/groq/stream.py +125 -0
  154. ommlds/minichain/backends/impls/huggingface/repos.py +1 -5
  155. ommlds/minichain/backends/impls/llamacpp/chat.py +40 -22
  156. ommlds/minichain/backends/impls/llamacpp/completion.py +9 -5
  157. ommlds/minichain/backends/impls/llamacpp/format.py +4 -2
  158. ommlds/minichain/backends/impls/llamacpp/stream.py +43 -23
  159. ommlds/minichain/backends/impls/mistral.py +20 -5
  160. ommlds/minichain/backends/impls/mlx/chat.py +101 -24
  161. ommlds/minichain/backends/impls/ollama/__init__.py +0 -0
  162. ommlds/minichain/backends/impls/ollama/chat.py +199 -0
  163. ommlds/minichain/backends/impls/openai/chat.py +18 -8
  164. ommlds/minichain/backends/impls/openai/completion.py +10 -3
  165. ommlds/minichain/backends/impls/openai/embedding.py +10 -3
  166. ommlds/minichain/backends/impls/openai/format.py +131 -106
  167. ommlds/minichain/backends/impls/openai/names.py +31 -5
  168. ommlds/minichain/backends/impls/openai/stream.py +43 -25
  169. ommlds/minichain/backends/impls/sentencepiece/tokens.py +9 -6
  170. ommlds/minichain/backends/impls/tavily.py +66 -0
  171. ommlds/minichain/backends/impls/tinygrad/chat.py +30 -20
  172. ommlds/minichain/backends/impls/tokenizers/tokens.py +9 -6
  173. ommlds/minichain/backends/impls/transformers/sentence.py +6 -3
  174. ommlds/minichain/backends/impls/transformers/tokens.py +10 -7
  175. ommlds/minichain/backends/impls/transformers/transformers.py +160 -37
  176. ommlds/minichain/backends/strings/parsing.py +1 -1
  177. ommlds/minichain/backends/strings/resolving.py +4 -1
  178. ommlds/minichain/chat/_marshal.py +16 -9
  179. ommlds/minichain/chat/choices/adapters.py +4 -4
  180. ommlds/minichain/chat/choices/services.py +1 -1
  181. ommlds/minichain/chat/choices/stream/__init__.py +0 -0
  182. ommlds/minichain/chat/choices/stream/adapters.py +35 -0
  183. ommlds/minichain/chat/choices/stream/joining.py +31 -0
  184. ommlds/minichain/chat/choices/stream/services.py +45 -0
  185. ommlds/minichain/chat/choices/stream/types.py +43 -0
  186. ommlds/minichain/chat/choices/types.py +2 -2
  187. ommlds/minichain/chat/history.py +3 -3
  188. ommlds/minichain/chat/messages.py +55 -19
  189. ommlds/minichain/chat/services.py +3 -3
  190. ommlds/minichain/chat/stream/_marshal.py +16 -0
  191. ommlds/minichain/chat/stream/joining.py +85 -0
  192. ommlds/minichain/chat/stream/services.py +15 -21
  193. ommlds/minichain/chat/stream/types.py +32 -19
  194. ommlds/minichain/chat/tools/execution.py +8 -7
  195. ommlds/minichain/chat/tools/ids.py +9 -15
  196. ommlds/minichain/chat/tools/parsing.py +17 -26
  197. ommlds/minichain/chat/transforms/base.py +29 -38
  198. ommlds/minichain/chat/transforms/metadata.py +30 -4
  199. ommlds/minichain/chat/transforms/services.py +9 -11
  200. ommlds/minichain/content/_marshal.py +44 -20
  201. ommlds/minichain/content/json.py +13 -0
  202. ommlds/minichain/content/materialize.py +14 -21
  203. ommlds/minichain/content/prepare.py +4 -0
  204. ommlds/minichain/content/transforms/interleave.py +1 -1
  205. ommlds/minichain/content/transforms/squeeze.py +1 -1
  206. ommlds/minichain/content/transforms/stringify.py +1 -1
  207. ommlds/minichain/json.py +20 -0
  208. ommlds/minichain/lib/code/__init__.py +0 -0
  209. ommlds/minichain/lib/code/prompts.py +6 -0
  210. ommlds/minichain/lib/fs/binfiles.py +108 -0
  211. ommlds/minichain/lib/fs/context.py +126 -0
  212. ommlds/minichain/lib/fs/errors.py +101 -0
  213. ommlds/minichain/lib/fs/suggestions.py +36 -0
  214. ommlds/minichain/lib/fs/tools/__init__.py +0 -0
  215. ommlds/minichain/lib/fs/tools/edit.py +104 -0
  216. ommlds/minichain/lib/fs/tools/ls.py +38 -0
  217. ommlds/minichain/lib/fs/tools/read.py +115 -0
  218. ommlds/minichain/lib/fs/tools/recursivels/__init__.py +0 -0
  219. ommlds/minichain/lib/fs/tools/recursivels/execution.py +40 -0
  220. ommlds/minichain/lib/todo/__init__.py +0 -0
  221. ommlds/minichain/lib/todo/context.py +54 -0
  222. ommlds/minichain/lib/todo/tools/__init__.py +0 -0
  223. ommlds/minichain/lib/todo/tools/read.py +44 -0
  224. ommlds/minichain/lib/todo/tools/write.py +335 -0
  225. ommlds/minichain/lib/todo/types.py +60 -0
  226. ommlds/minichain/llms/_marshal.py +25 -17
  227. ommlds/minichain/llms/types.py +4 -0
  228. ommlds/minichain/registries/globals.py +18 -4
  229. ommlds/minichain/resources.py +68 -45
  230. ommlds/minichain/search.py +1 -1
  231. ommlds/minichain/services/_marshal.py +46 -39
  232. ommlds/minichain/services/facades.py +3 -3
  233. ommlds/minichain/services/services.py +1 -1
  234. ommlds/minichain/standard.py +8 -0
  235. ommlds/minichain/stream/services.py +152 -38
  236. ommlds/minichain/stream/wrap.py +22 -24
  237. ommlds/minichain/text/toolparsing/llamacpp/hermes2.py +3 -2
  238. ommlds/minichain/text/toolparsing/llamacpp/llama31.py +3 -2
  239. ommlds/minichain/text/toolparsing/llamacpp/utils.py +3 -2
  240. ommlds/minichain/tools/_marshal.py +1 -1
  241. ommlds/minichain/tools/execution/catalog.py +2 -1
  242. ommlds/minichain/tools/execution/context.py +34 -14
  243. ommlds/minichain/tools/execution/errors.py +15 -0
  244. ommlds/minichain/tools/execution/executors.py +8 -3
  245. ommlds/minichain/tools/execution/reflect.py +40 -5
  246. ommlds/minichain/tools/fns.py +46 -9
  247. ommlds/minichain/tools/jsonschema.py +14 -5
  248. ommlds/minichain/tools/reflect.py +54 -18
  249. ommlds/minichain/tools/types.py +33 -1
  250. ommlds/minichain/utils.py +27 -0
  251. ommlds/minichain/vectors/_marshal.py +11 -10
  252. ommlds/minichain/vectors/types.py +1 -1
  253. ommlds/nanochat/LICENSE +21 -0
  254. ommlds/nanochat/__init__.py +0 -0
  255. ommlds/nanochat/rustbpe/LICENSE +21 -0
  256. ommlds/nanochat/tokenizers.py +406 -0
  257. ommlds/server/cli.py +1 -2
  258. ommlds/server/server.py +5 -5
  259. ommlds/server/service.py +1 -1
  260. ommlds/specs/__init__.py +0 -0
  261. ommlds/specs/mcp/__init__.py +0 -0
  262. ommlds/specs/mcp/_marshal.py +23 -0
  263. ommlds/specs/mcp/clients.py +146 -0
  264. ommlds/specs/mcp/protocol.py +371 -0
  265. ommlds/tools/git.py +35 -12
  266. ommlds/tools/ocr.py +8 -9
  267. ommlds/wiki/analyze.py +6 -7
  268. ommlds/wiki/text/mfh.py +1 -5
  269. ommlds/wiki/text/wtp.py +1 -3
  270. ommlds/wiki/utils/xml.py +5 -5
  271. {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/METADATA +24 -21
  272. ommlds-0.0.0.dev485.dist-info/RECORD +436 -0
  273. ommlds/cli/backends/standard.py +0 -20
  274. ommlds/cli/sessions/chat/base.py +0 -42
  275. ommlds/cli/sessions/chat/interactive.py +0 -73
  276. ommlds/cli/sessions/chat/printing.py +0 -96
  277. ommlds/cli/sessions/chat/prompt.py +0 -143
  278. ommlds/cli/sessions/chat/state.py +0 -109
  279. ommlds/cli/sessions/chat/tools.py +0 -91
  280. ommlds/cli/sessions/completion/completion.py +0 -44
  281. ommlds/cli/sessions/embedding/embedding.py +0 -42
  282. ommlds/cli/tools/config.py +0 -13
  283. ommlds/cli/tools/inject.py +0 -64
  284. ommlds/minichain/chat/stream/adapters.py +0 -69
  285. ommlds/minichain/lib/fs/ls/execution.py +0 -32
  286. ommlds-0.0.0.dev426.dist-info/RECORD +0 -303
  287. /ommlds/{cli/tools → backends/google}/__init__.py +0 -0
  288. /ommlds/{huggingface.py → backends/huggingface.py} +0 -0
  289. /ommlds/{minichain/lib/fs/ls → cli/content}/__init__.py +0 -0
  290. /ommlds/minichain/lib/fs/{ls → tools/recursivels}/rendering.py +0 -0
  291. /ommlds/minichain/lib/fs/{ls → tools/recursivels}/running.py +0 -0
  292. {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/WHEEL +0 -0
  293. {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/entry_points.txt +0 -0
  294. {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/licenses/LICENSE +0 -0
  295. {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,31 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+
5
+ from ...messages import AiChat
6
+ from ...stream.joining import AiDeltaJoiner
7
+ from .types import AiChoiceDeltas
8
+
9
+
10
+ ##
11
+
12
+
13
+ class AiChoicesDeltaJoiner:
14
+ def __init__(self) -> None:
15
+ super().__init__()
16
+
17
+ self._seq = 0
18
+ self._channels: list[AiDeltaJoiner] = []
19
+
20
+ def add(self, choices: ta.Sequence[AiChoiceDeltas]) -> None:
21
+ if not self._seq:
22
+ check.empty(self._channels)
23
+ self._channels.extend(AiDeltaJoiner() for _ in range(len(choices)))
24
+
25
+ for chan, c in zip(self._channels, choices, strict=True):
26
+ chan.add(c.deltas)
27
+
28
+ self._seq += 1
29
+
30
+ def build(self) -> list[AiChat]:
31
+ return [list(chan.build()) for chan in self._channels]
@@ -0,0 +1,45 @@
1
+ import abc
2
+ import typing as ta
3
+
4
+ from omlish import lang
5
+
6
+ from ....registries.globals import register_type
7
+ from ....services import Request
8
+ from ....services import Service
9
+ from ....stream.services import StreamResponse
10
+ from ...messages import Chat
11
+ from ..types import ChatChoicesOutputs
12
+ from .types import AiChoicesDeltas
13
+ from .types import ChatChoicesStreamOptions
14
+ from .types import ChatChoicesStreamOutputs
15
+
16
+
17
+ ##
18
+
19
+
20
+ ChatChoicesStreamRequest: ta.TypeAlias = Request[Chat, ChatChoicesStreamOptions]
21
+
22
+ ChatChoicesStreamResponse: ta.TypeAlias = StreamResponse[
23
+ AiChoicesDeltas,
24
+ ChatChoicesOutputs,
25
+ ChatChoicesStreamOutputs,
26
+ ]
27
+
28
+ # @omlish-manifest $.minichain.registries.manifests.RegistryTypeManifest
29
+ ChatChoicesStreamService: ta.TypeAlias = Service[ChatChoicesStreamRequest, ChatChoicesStreamResponse]
30
+
31
+ register_type(ChatChoicesStreamService, module=__name__)
32
+
33
+
34
+ def static_check_is_chat_choices_stream_service[T: ChatChoicesStreamService](t: type[T]) -> type[T]:
35
+ return t
36
+
37
+
38
+ ##
39
+
40
+
41
+ @static_check_is_chat_choices_stream_service
42
+ class AbstractChatChoicesStreamService(lang.Abstract):
43
+ @abc.abstractmethod
44
+ def invoke(self, request: ChatChoicesStreamRequest) -> ta.Awaitable[ChatChoicesStreamResponse]:
45
+ raise NotImplementedError
@@ -0,0 +1,43 @@
1
+ import typing as ta
2
+
3
+ from omlish import dataclasses as dc
4
+ from omlish import lang
5
+
6
+ from ....stream.services import StreamOptions
7
+ from ....types import Option
8
+ from ....types import Output
9
+ from ...stream.types import AiDeltas
10
+ from ..types import ChatChoicesOptions
11
+
12
+
13
+ ##
14
+
15
+
16
+ class ChatChoicesStreamOption(Option, lang.Abstract, lang.PackageSealed):
17
+ pass
18
+
19
+
20
+ ChatChoicesStreamOptions: ta.TypeAlias = ChatChoicesStreamOption | StreamOptions | ChatChoicesOptions
21
+
22
+
23
+ ##
24
+
25
+
26
+ class ChatChoicesStreamOutput(Output, lang.Abstract, lang.PackageSealed):
27
+ pass
28
+
29
+
30
+ ChatChoicesStreamOutputs: ta.TypeAlias = ChatChoicesStreamOutput
31
+
32
+
33
+ ##
34
+
35
+
36
+ @dc.dataclass(frozen=True)
37
+ class AiChoiceDeltas(lang.Final):
38
+ deltas: AiDeltas
39
+
40
+
41
+ @dc.dataclass(frozen=True)
42
+ class AiChoicesDeltas(lang.Final):
43
+ choices: ta.Sequence[AiChoiceDeltas]
@@ -9,7 +9,7 @@ from omlish import lang
9
9
 
10
10
  from ...types import Option
11
11
  from ...types import Output
12
- from ..messages import AiMessage
12
+ from ..messages import AiChat
13
13
  from ..types import ChatOptions
14
14
  from ..types import ChatOutputs
15
15
 
@@ -39,7 +39,7 @@ ChatChoicesOutputs: ta.TypeAlias = ChatChoicesOutput | ChatOutputs
39
39
 
40
40
  @dc.dataclass(frozen=True)
41
41
  class AiChoice(lang.Final):
42
- m: AiMessage
42
+ ms: AiChat
43
43
 
44
44
 
45
45
  AiChoices: ta.TypeAlias = ta.Sequence[AiChoice]
@@ -63,11 +63,11 @@ class HistoryAddingChatService:
63
63
  self._inner = inner
64
64
  self._history = history
65
65
 
66
- def invoke(self, request: ChatRequest) -> ChatResponse:
66
+ async def invoke(self, request: ChatRequest) -> ChatResponse:
67
67
  new_req = dc.replace(request, v=[*self._history.get(), *request.v])
68
- response = self._inner.invoke(new_req)
68
+ response = await self._inner.invoke(new_req)
69
69
  self._history.add(
70
70
  *request.v,
71
- response.v,
71
+ *response.v,
72
72
  )
73
73
  return response
@@ -13,7 +13,8 @@ from ..content.materialize import CanContent
13
13
  from ..content.transforms.base import ContentTransform
14
14
  from ..content.types import Content
15
15
  from ..metadata import MetadataContainer
16
- from ..tools.types import ToolExecRequest
16
+ from ..tools.types import ToolUse
17
+ from ..tools.types import ToolUseResult
17
18
  from .metadata import MessageMetadatas
18
19
 
19
20
 
@@ -47,11 +48,48 @@ class Message( # noqa
47
48
  return dc.replace(self, _metadata=tv.TypedValues(*self._metadata, *mds, override=override))
48
49
 
49
50
 
51
+ Chat: ta.TypeAlias = ta.Sequence[Message]
52
+
53
+
54
+ ##
55
+
56
+
57
+ @dc.dataclass(frozen=True)
58
+ class AnyUserMessage(Message, lang.Abstract):
59
+ pass
60
+
61
+
62
+ UserChat: ta.TypeAlias = ta.Sequence[AnyUserMessage]
63
+
64
+
65
+ def check_user_chat(chat: Chat) -> UserChat:
66
+ for m in chat:
67
+ check.isinstance(m, AnyUserMessage)
68
+ return ta.cast(UserChat, chat)
69
+
70
+
50
71
  #
51
72
 
52
73
 
53
74
  @dc.dataclass(frozen=True)
54
- class SystemMessage(Message, lang.Final):
75
+ class AnyAiMessage(Message, lang.Abstract):
76
+ pass
77
+
78
+
79
+ AiChat: ta.TypeAlias = ta.Sequence[AnyAiMessage]
80
+
81
+
82
+ def check_ai_chat(chat: Chat) -> AiChat:
83
+ for m in chat:
84
+ check.isinstance(m, AnyAiMessage)
85
+ return ta.cast(AiChat, chat)
86
+
87
+
88
+ ##
89
+
90
+
91
+ @dc.dataclass(frozen=True)
92
+ class SystemMessage(AnyUserMessage, lang.Final):
55
93
  c: CanContent
56
94
 
57
95
 
@@ -60,7 +98,7 @@ class SystemMessage(Message, lang.Final):
60
98
 
61
99
  @dc.dataclass(frozen=True)
62
100
  @msh.update_fields_metadata(['name'], omit_if=operator.not_)
63
- class UserMessage(Message, lang.Final):
101
+ class UserMessage(AnyUserMessage, lang.Final):
64
102
  c: CanContent
65
103
 
66
104
  name: str | None = dc.xfield(None, repr_fn=dc.opt_repr)
@@ -70,27 +108,21 @@ class UserMessage(Message, lang.Final):
70
108
 
71
109
 
72
110
  @dc.dataclass(frozen=True)
73
- @msh.update_fields_metadata(['tool_exec_requests'], omit_if=operator.not_)
74
- class AiMessage(Message, lang.Final):
75
- c: Content | None = dc.xfield(None, repr_fn=dc.opt_repr)
76
-
77
- tool_exec_requests: ta.Sequence[ToolExecRequest] | None = dc.xfield(None, repr_fn=dc.opt_repr)
111
+ class AiMessage(AnyAiMessage, lang.Final):
112
+ c: Content = dc.xfield(None, repr_fn=dc.opt_repr) # TODO: non-null?
78
113
 
79
114
 
80
115
  #
81
116
 
82
117
 
83
- @dc.dataclass(frozen=True, kw_only=True)
84
- class ToolExecResultMessage(Message, lang.Final):
85
- id: str | None = None
86
- name: str
87
- c: Content
88
-
89
-
90
- ##
118
+ @dc.dataclass(frozen=True)
119
+ class ToolUseMessage(AnyAiMessage, lang.Final):
120
+ tu: ToolUse
91
121
 
92
122
 
93
- Chat: ta.TypeAlias = ta.Sequence[Message]
123
+ @dc.dataclass(frozen=True)
124
+ class ToolUseResultMessage(AnyUserMessage, lang.Final):
125
+ tur: ToolUseResult
94
126
 
95
127
 
96
128
  ##
@@ -110,5 +142,9 @@ class _MessageContentTransform(ContentTransform, lang.Final, lang.NotInstantiabl
110
142
  return dc.replace(m, c=self.apply(m.c))
111
143
 
112
144
  @dispatch.install_method(ContentTransform.apply)
113
- def apply_tool_exec_result_message(self, m: ToolExecResultMessage) -> ToolExecResultMessage:
114
- return m
145
+ def apply_tool_use_message(self, m: ToolUseMessage) -> ToolUseMessage:
146
+ return dc.replace(m, tu=self.apply(m.tu))
147
+
148
+ @dispatch.install_method(ContentTransform.apply)
149
+ def apply_tool_use_result_message(self, m: ToolUseResultMessage) -> ToolUseResultMessage:
150
+ return dc.replace(m, tur=self.apply(m.tur))
@@ -7,7 +7,7 @@ from ..registries.globals import register_type
7
7
  from ..services import Request
8
8
  from ..services import Response
9
9
  from ..services import Service
10
- from .messages import AiMessage
10
+ from .messages import AiChat
11
11
  from .messages import Chat
12
12
  from .types import ChatOptions
13
13
  from .types import ChatOutputs
@@ -18,7 +18,7 @@ from .types import ChatOutputs
18
18
 
19
19
  ChatRequest: ta.TypeAlias = Request[Chat, ChatOptions]
20
20
 
21
- ChatResponse: ta.TypeAlias = Response[AiMessage, ChatOutputs]
21
+ ChatResponse: ta.TypeAlias = Response[AiChat, ChatOutputs]
22
22
 
23
23
  # @omlish-manifest $.minichain.registries.manifests.RegistryTypeManifest
24
24
  ChatService: ta.TypeAlias = Service[ChatRequest, ChatResponse]
@@ -36,5 +36,5 @@ def static_check_is_chat_service[T: ChatService](t: type[T]) -> type[T]:
36
36
  @static_check_is_chat_service
37
37
  class AbstractChatService(lang.Abstract):
38
38
  @abc.abstractmethod
39
- def invoke(self, request: ChatRequest) -> ChatResponse:
39
+ def invoke(self, request: ChatRequest) -> ta.Awaitable[ChatResponse]:
40
40
  raise NotImplementedError
@@ -0,0 +1,16 @@
1
+ from omlish import lang
2
+ from omlish import marshal as msh
3
+
4
+ from .types import AiDelta
5
+
6
+
7
+ ##
8
+
9
+
10
+ @lang.static_init
11
+ def _install_standard_marshaling() -> None:
12
+ ad_poly = msh.polymorphism_from_subclasses(AiDelta, naming=msh.Naming.SNAKE)
13
+ msh.install_standard_factories(
14
+ msh.PolymorphismMarshalerFactory(ad_poly),
15
+ msh.PolymorphismUnmarshalerFactory(ad_poly),
16
+ )
@@ -0,0 +1,85 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+ from omlish.formats import json
5
+
6
+ from ...tools.types import ToolUse
7
+ from ..messages import AiChat
8
+ from ..messages import AiMessage
9
+ from ..messages import AnyAiMessage
10
+ from ..messages import ToolUseMessage
11
+ from .types import AiDelta
12
+ from .types import AiDeltas
13
+ from .types import ContentAiDelta
14
+ from .types import PartialToolUseAiDelta
15
+ from .types import ToolUseAiDelta
16
+
17
+
18
+ ##
19
+
20
+
21
+ class AiDeltaJoiner:
22
+ def __init__(self) -> None:
23
+ super().__init__()
24
+
25
+ self._deltas: list[AiDelta] = []
26
+ self._messages: list[AnyAiMessage] = []
27
+
28
+ def _build_joined(self, deltas: ta.Sequence[AiDelta]) -> AnyAiMessage:
29
+ dty = check.single(set(map(type, check.not_empty(deltas))))
30
+
31
+ if dty is ContentAiDelta:
32
+ cds = ta.cast(ta.Sequence[ContentAiDelta], deltas)
33
+ return AiMessage(''.join(check.isinstance(cd.c, str) for cd in cds))
34
+
35
+ elif dty is ToolUseAiDelta:
36
+ raise TypeError(dty)
37
+
38
+ elif dty is PartialToolUseAiDelta:
39
+ tds = ta.cast(ta.Sequence[PartialToolUseAiDelta], deltas)
40
+ for td in ta.cast(ta.Sequence[PartialToolUseAiDelta], deltas)[1:]:
41
+ check.none(td.id)
42
+ check.none(td.name)
43
+
44
+ ra = ''.join(filter(None, (td.raw_args for td in tds)))
45
+
46
+ return ToolUseMessage(ToolUse(
47
+ id=tds[0].id,
48
+ name=check.non_empty_str(tds[0].name),
49
+ args=json.loads(ra),
50
+ raw_args=ra,
51
+ ))
52
+
53
+ else:
54
+ raise TypeError(dty)
55
+
56
+ def _maybe_join(self) -> None:
57
+ if not self._deltas:
58
+ return
59
+
60
+ self._messages.append(self._build_joined(self._deltas))
61
+ self._deltas.clear()
62
+
63
+ def _add_one(self, d: AiDelta) -> None:
64
+ if self._deltas and type(self._deltas[0]) is not type(d):
65
+ self._maybe_join()
66
+
67
+ if isinstance(d, ToolUseAiDelta):
68
+ self._messages.append(ToolUseMessage(ToolUse(
69
+ id=d.id,
70
+ name=check.not_none(d.name),
71
+ args=d.args or {},
72
+ raw_args=json.dumps_compact(d.args),
73
+ )))
74
+
75
+ else:
76
+ self._deltas.append(d)
77
+
78
+ def add(self, deltas: AiDeltas) -> None:
79
+ for d in deltas:
80
+ self._add_one(d)
81
+
82
+ def build(self) -> AiChat:
83
+ self._maybe_join()
84
+
85
+ return list(self._messages)
@@ -7,45 +7,39 @@ from ...registries.globals import register_type
7
7
  from ...services import Request
8
8
  from ...services import Service
9
9
  from ...stream.services import StreamResponse
10
- from ..choices.types import ChatChoicesOutputs
11
10
  from ..messages import Chat
12
- from .types import AiChoiceDeltas
13
- from .types import ChatChoicesStreamOptions
14
- from .types import ChatChoicesStreamOutputs
11
+ from ..types import ChatOutputs
12
+ from .types import AiDeltas
13
+ from .types import ChatStreamOptions
14
+ from .types import ChatStreamOutputs
15
15
 
16
16
 
17
17
  ##
18
18
 
19
19
 
20
- ChatChoicesStreamRequest: ta.TypeAlias = Request[Chat, ChatChoicesStreamOptions]
20
+ ChatStreamRequest: ta.TypeAlias = Request[Chat, ChatStreamOptions]
21
21
 
22
- ChatChoicesStreamResponse: ta.TypeAlias = StreamResponse[
23
- AiChoiceDeltas,
24
- ChatChoicesOutputs,
25
- ChatChoicesStreamOutputs,
22
+ ChatStreamResponse: ta.TypeAlias = StreamResponse[
23
+ AiDeltas,
24
+ ChatOutputs,
25
+ ChatStreamOutputs,
26
26
  ]
27
27
 
28
28
  # @omlish-manifest $.minichain.registries.manifests.RegistryTypeManifest
29
- ChatChoicesStreamService: ta.TypeAlias = Service[ChatChoicesStreamRequest, ChatChoicesStreamResponse]
29
+ ChatStreamService: ta.TypeAlias = Service[ChatStreamRequest, ChatStreamResponse]
30
30
 
31
- register_type(ChatChoicesStreamService, module=__name__)
31
+ register_type(ChatStreamService, module=__name__)
32
32
 
33
33
 
34
- def static_check_is_chat_choices_stream_service[T: ChatChoicesStreamService](t: type[T]) -> type[T]:
34
+ def static_check_is_chat_stream_service[T: ChatStreamService](t: type[T]) -> type[T]:
35
35
  return t
36
36
 
37
37
 
38
38
  ##
39
39
 
40
40
 
41
- @static_check_is_chat_choices_stream_service
42
- class AbstractChatChoicesStreamService(lang.Abstract):
41
+ @static_check_is_chat_stream_service
42
+ class AbstractChatStreamService(lang.Abstract):
43
43
  @abc.abstractmethod
44
- def invoke(self, request: ChatChoicesStreamRequest) -> ChatChoicesStreamResponse:
44
+ def invoke(self, request: ChatStreamRequest) -> ta.Awaitable[ChatStreamResponse]:
45
45
  raise NotImplementedError
46
-
47
-
48
- ##
49
-
50
-
51
- ChatChoicesStreamGenerator: ta.TypeAlias = ta.Generator[AiChoiceDeltas, None, ta.Sequence[ChatChoicesOutputs] | None]
@@ -1,4 +1,3 @@
1
- import operator
2
1
  import typing as ta
3
2
 
4
3
  from omlish import dataclasses as dc
@@ -9,51 +8,65 @@ from ...content.types import Content
9
8
  from ...stream.services import StreamOptions
10
9
  from ...types import Option
11
10
  from ...types import Output
12
- from ..choices.types import ChatChoicesOptions
11
+ from ..types import ChatOptions
12
+
13
+
14
+ msh.register_global_module_import('._marshal', __package__)
13
15
 
14
16
 
15
17
  ##
16
18
 
17
19
 
18
- class ChatChoicesStreamOption(Option, lang.Abstract, lang.PackageSealed):
20
+ class ChatStreamOption(Option, lang.Abstract, lang.PackageSealed):
19
21
  pass
20
22
 
21
23
 
22
- ChatChoicesStreamOptions: ta.TypeAlias = ChatChoicesStreamOption | StreamOptions | ChatChoicesOptions
24
+ ChatStreamOptions: ta.TypeAlias = ChatStreamOption | StreamOptions | ChatOptions
23
25
 
24
26
 
25
27
  ##
26
28
 
27
29
 
28
- class ChatChoicesStreamOutput(Output, lang.Abstract, lang.PackageSealed):
30
+ class ChatStreamOutput(Output, lang.Abstract, lang.PackageSealed):
29
31
  pass
30
32
 
31
33
 
32
- ChatChoicesStreamOutputs: ta.TypeAlias = ChatChoicesStreamOutput
34
+ ChatStreamOutputs: ta.TypeAlias = ChatStreamOutput
33
35
 
34
36
 
35
37
  ##
36
38
 
37
39
 
38
40
  @dc.dataclass(frozen=True)
39
- class ToolExecRequestDelta(lang.Final):
40
- index: int | None = None
41
- id: str | None = None
42
- name: str | None = None
43
- args: str | None = None
41
+ class AiDelta(lang.Sealed, lang.Abstract):
42
+ pass
44
43
 
45
44
 
46
- @dc.dataclass(frozen=True)
47
- @msh.update_fields_metadata(['tool_exec_requests'], omit_if=operator.not_)
48
- class AiMessageDelta(lang.Final):
49
- c: Content | None = dc.xfield(None, repr_fn=dc.opt_repr)
45
+ AiDeltas: ta.TypeAlias = ta.Sequence[AiDelta]
50
46
 
51
- tool_exec_requests: ta.Sequence[ToolExecRequestDelta] | None = dc.xfield(None, repr_fn=dc.opt_repr)
47
+
48
+ #
52
49
 
53
50
 
54
51
  @dc.dataclass(frozen=True)
55
- class AiChoiceDelta(lang.Final):
56
- m: AiMessageDelta
52
+ class ContentAiDelta(AiDelta, lang.Final):
53
+ c: Content
54
+
55
+
56
+ #
57
+
58
+
59
+ @dc.dataclass(frozen=True, kw_only=True)
60
+ class AnyToolUseAiDelta(AiDelta, lang.Abstract):
61
+ id: str | None = None
62
+ name: str | None = None
63
+
64
+
65
+ @dc.dataclass(frozen=True, kw_only=True)
66
+ class ToolUseAiDelta(AnyToolUseAiDelta, lang.Final):
67
+ args: ta.Mapping[str, ta.Any] | None = None
57
68
 
58
69
 
59
- AiChoiceDeltas: ta.TypeAlias = ta.Sequence[AiChoiceDelta]
70
+ @dc.dataclass(frozen=True, kw_only=True)
71
+ class PartialToolUseAiDelta(AnyToolUseAiDelta, lang.Final):
72
+ raw_args: ta.Any | None = None
@@ -1,25 +1,26 @@
1
1
  from ...tools.execution.context import ToolContext
2
2
  from ...tools.execution.executors import ToolExecutor
3
- from ..messages import ToolExecRequest
4
- from ..messages import ToolExecResultMessage
3
+ from ...tools.types import ToolUseResult
4
+ from ..messages import ToolUse
5
+ from ..messages import ToolUseResultMessage
5
6
 
6
7
 
7
8
  ##
8
9
 
9
10
 
10
- async def execute_tool_request(
11
+ async def execute_tool_use(
11
12
  ctx: ToolContext,
12
13
  tex: ToolExecutor,
13
- ter: ToolExecRequest,
14
- ) -> ToolExecResultMessage:
14
+ ter: ToolUse,
15
+ ) -> ToolUseResultMessage:
15
16
  result_str = await tex.execute_tool(
16
17
  ctx,
17
18
  ter.name,
18
19
  ter.args,
19
20
  )
20
21
 
21
- return ToolExecResultMessage(
22
+ return ToolUseResultMessage(ToolUseResult(
22
23
  id=ter.id,
23
24
  name=ter.name,
24
25
  c=result_str,
25
- )
26
+ ))
@@ -3,31 +3,25 @@ import uuid
3
3
 
4
4
  from omlish import dataclasses as dc
5
5
 
6
- from ..messages import AiMessage
6
+ from ..messages import Chat
7
7
  from ..messages import Message
8
- from ..messages import ToolExecRequest
8
+ from ..messages import ToolUseMessage
9
9
  from ..transforms.base import MessageTransform
10
10
 
11
11
 
12
12
  ##
13
13
 
14
14
 
15
- def simple_uuid_tool_exec_request_id_factory(m: AiMessage, ter: ToolExecRequest) -> str: # noqa
15
+ def simple_uuid_tool_exec_request_id_factory(m: ToolUseMessage) -> str: # noqa
16
16
  return str(uuid.uuid4())
17
17
 
18
18
 
19
19
  @dc.dataclass(frozen=True)
20
- class ToolExecRequestIdAddingMessageTransform(MessageTransform):
21
- id_factory: ta.Callable[[AiMessage, ToolExecRequest], str] = dc.field(default=simple_uuid_tool_exec_request_id_factory) # noqa
20
+ class ToolUseIdAddingMessageTransform(MessageTransform):
21
+ id_factory: ta.Callable[[ToolUseMessage], str] = dc.field(default=simple_uuid_tool_exec_request_id_factory) # noqa
22
22
 
23
- def transform_message(self, m: Message) -> Message:
24
- if not isinstance(m, AiMessage) or not m.tool_exec_requests:
25
- return m
23
+ def transform_message(self, m: Message) -> Chat:
24
+ if not isinstance(m, ToolUseMessage) or m.tu.id is not None:
25
+ return [m]
26
26
 
27
- lst: list[ToolExecRequest] = []
28
- for ter in m.tool_exec_requests:
29
- if ter.id is None:
30
- ter = dc.replace(ter, id=self.id_factory(m, ter))
31
- lst.append(ter)
32
-
33
- return dc.replace(m, tool_exec_requests=lst)
27
+ return [dc.replace(m, tu=dc.replace(m.tu, id=self.id_factory(m)))]