ommlds 0.0.0.dev480__py3-none-any.whl → 0.0.0.dev503__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. ommlds/.omlish-manifests.json +100 -33
  2. ommlds/README.md +11 -0
  3. ommlds/__about__.py +9 -6
  4. ommlds/backends/anthropic/protocol/__init__.py +13 -1
  5. ommlds/backends/anthropic/protocol/_dataclasses.py +1625 -0
  6. ommlds/backends/anthropic/protocol/sse/events.py +2 -0
  7. ommlds/backends/cerebras/__init__.py +7 -0
  8. ommlds/backends/cerebras/_dataclasses.py +4254 -0
  9. ommlds/backends/cerebras/_marshal.py +24 -0
  10. ommlds/backends/cerebras/protocol.py +312 -0
  11. ommlds/backends/google/protocol/__init__.py +13 -0
  12. ommlds/backends/google/protocol/_dataclasses.py +5997 -0
  13. ommlds/backends/groq/__init__.py +7 -0
  14. ommlds/backends/groq/_dataclasses.py +3901 -0
  15. ommlds/backends/groq/clients.py +9 -0
  16. ommlds/backends/llamacpp/logging.py +4 -1
  17. ommlds/backends/mlx/caching.py +7 -3
  18. ommlds/backends/mlx/cli.py +10 -7
  19. ommlds/backends/mlx/generation.py +18 -16
  20. ommlds/backends/mlx/limits.py +10 -6
  21. ommlds/backends/mlx/loading.py +7 -4
  22. ommlds/backends/ollama/__init__.py +7 -0
  23. ommlds/backends/ollama/_dataclasses.py +3488 -0
  24. ommlds/backends/ollama/protocol.py +3 -0
  25. ommlds/backends/openai/protocol/__init__.py +15 -1
  26. ommlds/backends/openai/protocol/_dataclasses.py +7708 -0
  27. ommlds/backends/tavily/__init__.py +7 -0
  28. ommlds/backends/tavily/_dataclasses.py +1734 -0
  29. ommlds/backends/transformers/__init__.py +14 -0
  30. ommlds/cli/__init__.py +7 -0
  31. ommlds/cli/_dataclasses.py +3515 -0
  32. ommlds/cli/backends/catalog.py +0 -5
  33. ommlds/cli/backends/inject.py +70 -7
  34. ommlds/cli/backends/meta.py +82 -0
  35. ommlds/cli/content/messages.py +1 -1
  36. ommlds/cli/inject.py +11 -3
  37. ommlds/cli/main.py +137 -68
  38. ommlds/cli/rendering/types.py +6 -0
  39. ommlds/cli/secrets.py +2 -1
  40. ommlds/cli/sessions/base.py +1 -10
  41. ommlds/cli/sessions/chat/configs.py +9 -17
  42. ommlds/cli/sessions/chat/{chat → drivers}/ai/configs.py +3 -1
  43. ommlds/cli/sessions/chat/drivers/ai/events.py +57 -0
  44. ommlds/cli/sessions/chat/{chat → drivers}/ai/inject.py +10 -3
  45. ommlds/cli/sessions/chat/{chat → drivers}/ai/rendering.py +1 -1
  46. ommlds/cli/sessions/chat/{chat → drivers}/ai/services.py +1 -1
  47. ommlds/cli/sessions/chat/{chat → drivers}/ai/tools.py +4 -8
  48. ommlds/cli/sessions/chat/{chat → drivers}/ai/types.py +9 -0
  49. ommlds/cli/sessions/chat/drivers/configs.py +25 -0
  50. ommlds/cli/sessions/chat/drivers/events/inject.py +27 -0
  51. ommlds/cli/sessions/chat/drivers/events/injection.py +14 -0
  52. ommlds/cli/sessions/chat/drivers/events/manager.py +16 -0
  53. ommlds/cli/sessions/chat/drivers/events/types.py +38 -0
  54. ommlds/cli/sessions/chat/drivers/impl.py +50 -0
  55. ommlds/cli/sessions/chat/drivers/inject.py +70 -0
  56. ommlds/cli/sessions/chat/{chat → drivers}/state/configs.py +2 -0
  57. ommlds/cli/sessions/chat/drivers/state/ids.py +25 -0
  58. ommlds/cli/sessions/chat/drivers/state/inject.py +83 -0
  59. ommlds/cli/sessions/chat/{chat → drivers}/state/inmemory.py +0 -4
  60. ommlds/cli/sessions/chat/{chat → drivers}/state/storage.py +17 -10
  61. ommlds/cli/sessions/chat/{chat → drivers}/state/types.py +10 -5
  62. ommlds/cli/sessions/chat/{tools → drivers/tools}/configs.py +2 -2
  63. ommlds/cli/sessions/chat/drivers/tools/confirmation.py +44 -0
  64. ommlds/cli/sessions/chat/drivers/tools/errorhandling.py +39 -0
  65. ommlds/cli/sessions/chat/{tools → drivers/tools}/execution.py +3 -4
  66. ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/inject.py +3 -3
  67. ommlds/cli/sessions/chat/{tools → drivers/tools}/inject.py +7 -12
  68. ommlds/cli/sessions/chat/{tools → drivers/tools}/injection.py +5 -5
  69. ommlds/cli/sessions/chat/{tools → drivers/tools}/rendering.py +3 -3
  70. ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/inject.py +3 -3
  71. ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/tools.py +1 -1
  72. ommlds/cli/sessions/chat/drivers/types.py +31 -0
  73. ommlds/cli/sessions/chat/{chat → drivers}/user/configs.py +0 -3
  74. ommlds/cli/sessions/chat/drivers/user/inject.py +41 -0
  75. ommlds/cli/sessions/chat/facades/__init__.py +0 -0
  76. ommlds/cli/sessions/chat/facades/commands/__init__.py +0 -0
  77. ommlds/cli/sessions/chat/facades/commands/base.py +83 -0
  78. ommlds/cli/sessions/chat/facades/commands/configs.py +9 -0
  79. ommlds/cli/sessions/chat/facades/commands/inject.py +41 -0
  80. ommlds/cli/sessions/chat/facades/commands/injection.py +15 -0
  81. ommlds/cli/sessions/chat/facades/commands/manager.py +59 -0
  82. ommlds/cli/sessions/chat/facades/commands/simple.py +34 -0
  83. ommlds/cli/sessions/chat/facades/commands/types.py +13 -0
  84. ommlds/cli/sessions/chat/facades/configs.py +11 -0
  85. ommlds/cli/sessions/chat/facades/facade.py +26 -0
  86. ommlds/cli/sessions/chat/facades/inject.py +35 -0
  87. ommlds/cli/sessions/chat/facades/ui.py +34 -0
  88. ommlds/cli/sessions/chat/inject.py +8 -31
  89. ommlds/cli/sessions/chat/interfaces/__init__.py +0 -0
  90. ommlds/cli/sessions/chat/interfaces/bare/__init__.py +0 -0
  91. ommlds/cli/sessions/chat/interfaces/bare/configs.py +15 -0
  92. ommlds/cli/sessions/chat/interfaces/bare/inject.py +69 -0
  93. ommlds/cli/sessions/chat/interfaces/bare/interactive.py +49 -0
  94. ommlds/cli/sessions/chat/interfaces/bare/oneshot.py +21 -0
  95. ommlds/cli/sessions/chat/{tools/confirmation.py → interfaces/bare/tools.py} +3 -22
  96. ommlds/cli/sessions/chat/interfaces/base.py +13 -0
  97. ommlds/cli/sessions/chat/interfaces/configs.py +11 -0
  98. ommlds/cli/sessions/chat/interfaces/inject.py +29 -0
  99. ommlds/cli/sessions/chat/interfaces/textual/__init__.py +0 -0
  100. ommlds/cli/sessions/chat/interfaces/textual/app.py +310 -0
  101. ommlds/cli/sessions/chat/interfaces/textual/configs.py +11 -0
  102. ommlds/cli/sessions/chat/interfaces/textual/facades.py +19 -0
  103. ommlds/cli/sessions/chat/interfaces/textual/inject.py +97 -0
  104. ommlds/cli/sessions/chat/interfaces/textual/interface.py +24 -0
  105. ommlds/cli/sessions/chat/interfaces/textual/styles/__init__.py +29 -0
  106. ommlds/cli/sessions/chat/interfaces/textual/styles/input.tcss +53 -0
  107. ommlds/cli/sessions/chat/interfaces/textual/styles/markdown.tcss +7 -0
  108. ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +157 -0
  109. ommlds/cli/sessions/chat/interfaces/textual/tools.py +38 -0
  110. ommlds/cli/sessions/chat/interfaces/textual/widgets/__init__.py +0 -0
  111. ommlds/cli/sessions/chat/interfaces/textual/widgets/input.py +36 -0
  112. ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +197 -0
  113. ommlds/cli/sessions/chat/session.py +8 -13
  114. ommlds/cli/sessions/completion/configs.py +3 -4
  115. ommlds/cli/sessions/completion/inject.py +1 -2
  116. ommlds/cli/sessions/completion/session.py +4 -8
  117. ommlds/cli/sessions/configs.py +10 -0
  118. ommlds/cli/sessions/embedding/configs.py +3 -4
  119. ommlds/cli/sessions/embedding/inject.py +1 -2
  120. ommlds/cli/sessions/embedding/session.py +4 -8
  121. ommlds/cli/sessions/inject.py +15 -15
  122. ommlds/cli/state/storage.py +7 -1
  123. ommlds/minichain/__init__.py +161 -38
  124. ommlds/minichain/_dataclasses.py +20452 -0
  125. ommlds/minichain/_typedvalues.py +11 -4
  126. ommlds/minichain/backends/impls/anthropic/names.py +3 -3
  127. ommlds/minichain/backends/impls/anthropic/protocol.py +2 -2
  128. ommlds/minichain/backends/impls/anthropic/stream.py +1 -1
  129. ommlds/minichain/backends/impls/cerebras/__init__.py +0 -0
  130. ommlds/minichain/backends/impls/cerebras/chat.py +80 -0
  131. ommlds/minichain/backends/impls/cerebras/names.py +45 -0
  132. ommlds/minichain/backends/impls/cerebras/protocol.py +143 -0
  133. ommlds/minichain/backends/impls/cerebras/stream.py +125 -0
  134. ommlds/minichain/backends/impls/duckduckgo/search.py +5 -1
  135. ommlds/minichain/backends/impls/google/names.py +6 -0
  136. ommlds/minichain/backends/impls/google/stream.py +1 -1
  137. ommlds/minichain/backends/impls/google/tools.py +2 -2
  138. ommlds/minichain/backends/impls/groq/chat.py +2 -0
  139. ommlds/minichain/backends/impls/groq/protocol.py +2 -2
  140. ommlds/minichain/backends/impls/groq/stream.py +3 -1
  141. ommlds/minichain/backends/impls/huggingface/repos.py +1 -5
  142. ommlds/minichain/backends/impls/llamacpp/chat.py +6 -3
  143. ommlds/minichain/backends/impls/llamacpp/completion.py +7 -3
  144. ommlds/minichain/backends/impls/llamacpp/stream.py +6 -3
  145. ommlds/minichain/backends/impls/mlx/chat.py +6 -3
  146. ommlds/minichain/backends/impls/ollama/chat.py +51 -57
  147. ommlds/minichain/backends/impls/ollama/protocol.py +144 -0
  148. ommlds/minichain/backends/impls/openai/format.py +4 -3
  149. ommlds/minichain/backends/impls/openai/names.py +3 -1
  150. ommlds/minichain/backends/impls/openai/stream.py +33 -1
  151. ommlds/minichain/backends/impls/sentencepiece/tokens.py +9 -6
  152. ommlds/minichain/backends/impls/tinygrad/chat.py +7 -4
  153. ommlds/minichain/backends/impls/tokenizers/tokens.py +9 -6
  154. ommlds/minichain/backends/impls/transformers/sentence.py +5 -2
  155. ommlds/minichain/backends/impls/transformers/tokens.py +9 -6
  156. ommlds/minichain/backends/impls/transformers/transformers.py +10 -8
  157. ommlds/minichain/backends/strings/resolving.py +1 -1
  158. ommlds/minichain/chat/content.py +42 -0
  159. ommlds/minichain/chat/messages.py +43 -39
  160. ommlds/minichain/chat/stream/joining.py +36 -12
  161. ommlds/minichain/chat/stream/types.py +1 -1
  162. ommlds/minichain/chat/templating.py +3 -3
  163. ommlds/minichain/content/__init__.py +19 -3
  164. ommlds/minichain/content/_marshal.py +181 -55
  165. ommlds/minichain/content/code.py +26 -0
  166. ommlds/minichain/content/composite.py +28 -0
  167. ommlds/minichain/content/content.py +27 -0
  168. ommlds/minichain/content/dynamic.py +12 -0
  169. ommlds/minichain/content/emphasis.py +27 -0
  170. ommlds/minichain/content/images.py +2 -2
  171. ommlds/minichain/content/json.py +2 -2
  172. ommlds/minichain/content/link.py +13 -0
  173. ommlds/minichain/content/markdown.py +12 -0
  174. ommlds/minichain/content/metadata.py +10 -0
  175. ommlds/minichain/content/namespaces.py +8 -0
  176. ommlds/minichain/content/placeholders.py +10 -9
  177. ommlds/minichain/content/quote.py +26 -0
  178. ommlds/minichain/content/raw.py +49 -0
  179. ommlds/minichain/content/recursive.py +12 -0
  180. ommlds/minichain/content/section.py +26 -0
  181. ommlds/minichain/content/sequence.py +17 -3
  182. ommlds/minichain/content/standard.py +32 -0
  183. ommlds/minichain/content/tag.py +28 -0
  184. ommlds/minichain/content/templates.py +13 -0
  185. ommlds/minichain/content/text.py +2 -2
  186. ommlds/minichain/content/transform/__init__.py +0 -0
  187. ommlds/minichain/content/transform/json.py +55 -0
  188. ommlds/minichain/content/transform/markdown.py +8 -0
  189. ommlds/minichain/content/transform/materialize.py +51 -0
  190. ommlds/minichain/content/transform/metadata.py +16 -0
  191. ommlds/minichain/content/{prepare.py → transform/prepare.py} +10 -15
  192. ommlds/minichain/content/transform/recursive.py +97 -0
  193. ommlds/minichain/content/transform/standard.py +43 -0
  194. ommlds/minichain/content/{transforms → transform}/stringify.py +1 -7
  195. ommlds/minichain/content/transform/strings.py +33 -0
  196. ommlds/minichain/content/transform/templates.py +25 -0
  197. ommlds/minichain/content/visitors.py +231 -0
  198. ommlds/minichain/lib/fs/tools/read.py +1 -1
  199. ommlds/minichain/lib/fs/tools/recursivels/rendering.py +1 -1
  200. ommlds/minichain/lib/fs/tools/recursivels/running.py +1 -1
  201. ommlds/minichain/lib/todo/tools/write.py +2 -1
  202. ommlds/minichain/lib/todo/types.py +1 -1
  203. ommlds/minichain/metadata.py +56 -2
  204. ommlds/minichain/resources.py +22 -1
  205. ommlds/minichain/services/README.md +154 -0
  206. ommlds/minichain/services/__init__.py +6 -2
  207. ommlds/minichain/services/_marshal.py +46 -10
  208. ommlds/minichain/services/_origclasses.py +11 -0
  209. ommlds/minichain/services/_typedvalues.py +8 -3
  210. ommlds/minichain/services/requests.py +73 -3
  211. ommlds/minichain/services/responses.py +73 -3
  212. ommlds/minichain/services/services.py +9 -0
  213. ommlds/minichain/stream/services.py +24 -1
  214. ommlds/minichain/text/applypatch.py +2 -1
  215. ommlds/minichain/text/toolparsing/llamacpp/types.py +1 -1
  216. ommlds/minichain/tokens/specials.py +1 -1
  217. ommlds/minichain/tools/execution/catalog.py +1 -1
  218. ommlds/minichain/tools/execution/errorhandling.py +36 -0
  219. ommlds/minichain/tools/execution/errors.py +2 -2
  220. ommlds/minichain/tools/execution/executors.py +1 -1
  221. ommlds/minichain/tools/fns.py +1 -1
  222. ommlds/minichain/tools/jsonschema.py +2 -2
  223. ommlds/minichain/tools/reflect.py +6 -6
  224. ommlds/minichain/tools/types.py +12 -15
  225. ommlds/minichain/vectors/_marshal.py +1 -1
  226. ommlds/minichain/vectors/embeddings.py +1 -1
  227. ommlds/minichain/wrappers/__init__.py +7 -0
  228. ommlds/minichain/wrappers/firstinwins.py +144 -0
  229. ommlds/minichain/wrappers/instrument.py +146 -0
  230. ommlds/minichain/wrappers/retry.py +168 -0
  231. ommlds/minichain/wrappers/services.py +98 -0
  232. ommlds/minichain/wrappers/stream.py +57 -0
  233. ommlds/nanochat/rustbpe/README.md +9 -0
  234. ommlds/nanochat/tokenizers.py +40 -6
  235. ommlds/specs/mcp/clients.py +146 -0
  236. ommlds/specs/mcp/protocol.py +123 -18
  237. ommlds/tools/git.py +82 -65
  238. {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/METADATA +13 -11
  239. ommlds-0.0.0.dev503.dist-info/RECORD +520 -0
  240. ommlds/cli/sessions/chat/chat/state/inject.py +0 -36
  241. ommlds/cli/sessions/chat/chat/user/inject.py +0 -62
  242. ommlds/cli/sessions/chat/chat/user/interactive.py +0 -31
  243. ommlds/cli/sessions/chat/chat/user/oneshot.py +0 -25
  244. ommlds/cli/sessions/chat/chat/user/types.py +0 -15
  245. ommlds/cli/sessions/chat/driver.py +0 -43
  246. ommlds/minichain/content/materialize.py +0 -196
  247. ommlds/minichain/content/simple.py +0 -47
  248. ommlds/minichain/content/transforms/base.py +0 -46
  249. ommlds/minichain/content/transforms/interleave.py +0 -70
  250. ommlds/minichain/content/transforms/squeeze.py +0 -72
  251. ommlds/minichain/content/transforms/strings.py +0 -24
  252. ommlds/minichain/content/types.py +0 -43
  253. ommlds/minichain/stream/wrap.py +0 -62
  254. ommlds-0.0.0.dev480.dist-info/RECORD +0 -427
  255. /ommlds/cli/sessions/chat/{chat → drivers}/__init__.py +0 -0
  256. /ommlds/cli/sessions/chat/{chat → drivers}/ai/__init__.py +0 -0
  257. /ommlds/cli/sessions/chat/{chat → drivers}/ai/injection.py +0 -0
  258. /ommlds/cli/sessions/chat/{chat/state → drivers/events}/__init__.py +0 -0
  259. /ommlds/cli/sessions/chat/{chat/user → drivers/phases}/__init__.py +0 -0
  260. /ommlds/cli/sessions/chat/{phases → drivers/phases}/inject.py +0 -0
  261. /ommlds/cli/sessions/chat/{phases → drivers/phases}/injection.py +0 -0
  262. /ommlds/cli/sessions/chat/{phases → drivers/phases}/manager.py +0 -0
  263. /ommlds/cli/sessions/chat/{phases → drivers/phases}/types.py +0 -0
  264. /ommlds/cli/sessions/chat/{phases → drivers/state}/__init__.py +0 -0
  265. /ommlds/cli/sessions/chat/{tools → drivers/tools}/__init__.py +0 -0
  266. /ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/__init__.py +0 -0
  267. /ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/configs.py +0 -0
  268. /ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/__init__.py +0 -0
  269. /ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/configs.py +0 -0
  270. /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/__init__.py +0 -0
  271. /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/configs.py +0 -0
  272. /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/inject.py +0 -0
  273. /ommlds/{minichain/content/transforms → cli/sessions/chat/drivers/user}/__init__.py +0 -0
  274. {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/WHEEL +0 -0
  275. {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/entry_points.txt +0 -0
  276. {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/licenses/LICENSE +0 -0
  277. {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,20 @@
1
1
  import typing as ta
2
2
 
3
- import transformers as tfm
4
-
5
3
  from omlish import check
6
4
  from omlish import collections as col
5
+ from omlish import lang
7
6
 
8
7
  from .... import tokens as tks
9
8
 
10
9
 
10
+ with lang.auto_proxy_import(globals()):
11
+ import transformers as tfm
12
+
13
+
11
14
  ##
12
15
 
13
16
 
14
- def build_vocab(tfm_tokenizer: tfm.PreTrainedTokenizerBase) -> tks.Vocab:
17
+ def build_vocab(tfm_tokenizer: 'tfm.PreTrainedTokenizerBase') -> tks.Vocab:
15
18
  return tks.Vocab([
16
19
  (ta.cast(tks.Token, i), tks.TokenStr(s))
17
20
  for s, i in tfm_tokenizer.get_vocab().items()
@@ -32,7 +35,7 @@ SPECIAL_TOKEN_ATTR_MAP: col.BiMap[type[tks.SpecialToken], str] = col.make_bi_map
32
35
  })
33
36
 
34
37
 
35
- def build_specials(tfm_tokenizer: tfm.PreTrainedTokenizerBase) -> tks.SpecialTokens:
38
+ def build_specials(tfm_tokenizer: 'tfm.PreTrainedTokenizerBase') -> tks.SpecialTokens:
36
39
  return tks.SpecialTokens.from_dict({
37
40
  st: getattr(tfm_tokenizer, a)
38
41
  for st, a in SPECIAL_TOKEN_ATTR_MAP.items()
@@ -45,7 +48,7 @@ def build_specials(tfm_tokenizer: tfm.PreTrainedTokenizerBase) -> tks.SpecialTok
45
48
  class TransformersTokenizer(tks.BaseTokenizer):
46
49
  def __init__(
47
50
  self,
48
- tfm_tokenizer: tfm.PreTrainedTokenizerBase,
51
+ tfm_tokenizer: 'tfm.PreTrainedTokenizerBase',
49
52
  ) -> None:
50
53
  self._tfm_tokenizer = check.isinstance(tfm_tokenizer, tfm.PreTrainedTokenizerBase)
51
54
 
@@ -55,7 +58,7 @@ class TransformersTokenizer(tks.BaseTokenizer):
55
58
  )
56
59
 
57
60
  @property
58
- def tfm_tokenizer(self) -> tfm.PreTrainedTokenizerBase:
61
+ def tfm_tokenizer(self) -> 'tfm.PreTrainedTokenizerBase':
59
62
  return self._tfm_tokenizer
60
63
 
61
64
  #
@@ -7,15 +7,11 @@ import sys
7
7
  import threading
8
8
  import typing as ta
9
9
 
10
- import transformers as tfm
11
-
12
10
  from omlish import check
13
11
  from omlish import lang
14
12
  from omlish import typedvalues as tv
15
13
  from omlish.asyncs.asyncio.sync import AsyncioBufferRelay
16
14
 
17
- from .....backends.transformers.filecache import file_cache_patch_context
18
- from .....backends.transformers.streamers import CancellableTextStreamer
19
15
  from ....chat.choices.services import ChatChoicesRequest
20
16
  from ....chat.choices.services import ChatChoicesResponse
21
17
  from ....chat.choices.services import static_check_is_chat_choices_service
@@ -44,6 +40,12 @@ from ....stream.services import new_stream_response
44
40
  from ...impls.huggingface.configs import HuggingfaceHubToken
45
41
 
46
42
 
43
+ with lang.auto_proxy_import(globals()):
44
+ import transformers as tfm
45
+
46
+ from .....backends import transformers as tfm_u
47
+
48
+
47
49
  ##
48
50
 
49
51
 
@@ -168,7 +170,7 @@ class BaseTransformersChatChoicesService(lang.ExitStacked):
168
170
  self._huggingface_hub_token = HuggingfaceHubToken.pop_secret(cc, env='HUGGINGFACE_HUB_TOKEN')
169
171
 
170
172
  @lang.cached_function(transient=True)
171
- def _load_pipeline(self) -> tfm.Pipeline:
173
+ def _load_pipeline(self) -> 'tfm.Pipeline':
172
174
  # FIXME: unload
173
175
  check.not_none(self._exit_stack)
174
176
 
@@ -181,7 +183,7 @@ class BaseTransformersChatChoicesService(lang.ExitStacked):
181
183
  for pkw_cfg in self._pipeline_kwargs:
182
184
  pkw.update(pkw_cfg.v)
183
185
 
184
- with file_cache_patch_context(
186
+ with tfm_u.file_cache_patch_context(
185
187
  local_first=True,
186
188
  local_config_present_is_authoritative=True,
187
189
  ):
@@ -246,7 +248,7 @@ class TransformersChatChoicesStreamService(BaseTransformersChatChoicesService):
246
248
  if text or stream_end:
247
249
  relay.push(text, *([None] if stream_end else []))
248
250
 
249
- streamer = CancellableTextStreamer(
251
+ streamer = tfm_u.CancellableTextStreamer(
250
252
  check.not_none(pipeline.tokenizer), # type: ignore[arg-type]
251
253
  streamer_callback, # noqa
252
254
  skip_prompt=True,
@@ -255,7 +257,7 @@ class TransformersChatChoicesStreamService(BaseTransformersChatChoicesService):
255
257
 
256
258
  async with UseResources.or_new(request.options) as rs:
257
259
  thread = threading.Thread(
258
- target=CancellableTextStreamer.ignoring_cancelled(pipeline),
260
+ target=tfm_u.CancellableTextStreamer.ignoring_cancelled(pipeline),
259
261
  args=(
260
262
  inputs,
261
263
  ),
@@ -4,9 +4,9 @@ TODO:
4
4
  - interop with registry somehow, probably? or is it strictly a different concern?
5
5
  """
6
6
  import abc
7
- import dataclasses as dc
8
7
  import typing as ta
9
8
 
9
+ from omlish import dataclasses as dc
10
10
  from omlish import lang
11
11
  from omlish.manifests.globals import GlobalManifestLoader
12
12
 
@@ -0,0 +1,42 @@
1
+ import typing as ta
2
+
3
+ from ..content.content import Content
4
+ from ..content.transform.strings import transform_content_strings
5
+ from .messages import AiMessage
6
+ from .messages import Message
7
+ from .messages import SystemMessage
8
+ from .messages import ToolUseMessage
9
+ from .messages import ToolUseResultMessage
10
+ from .messages import UserMessage
11
+
12
+
13
+ MessageT = ta.TypeVar('MessageT', bound=Message)
14
+
15
+
16
+ ##
17
+
18
+
19
+ def transform_message_content(fn: ta.Callable[[Content], Content], m: MessageT) -> MessageT:
20
+ if isinstance(m, UserMessage):
21
+ return m.replace(c=fn(m.c))
22
+
23
+ elif isinstance(m, AiMessage):
24
+ return m.replace(c=fn(m.c))
25
+
26
+ elif isinstance(m, SystemMessage):
27
+ return m.replace(c=fn(m.c))
28
+
29
+ elif isinstance(m, ToolUseMessage):
30
+ # TODO: m.tu.args?
31
+ return m
32
+
33
+ elif isinstance(m, ToolUseResultMessage):
34
+ # TODO: m.tur.c?
35
+ return m
36
+
37
+ else:
38
+ raise TypeError(m)
39
+
40
+
41
+ def transform_message_content_strings(fn: ta.Callable[[str], str], m: MessageT) -> MessageT:
42
+ return transform_message_content(lambda c: transform_content_strings(fn, c), m)
@@ -1,20 +1,20 @@
1
+ """
2
+ TODO:
3
+ - channel? reasoning / thinking?
4
+ """
1
5
  import operator
2
6
  import typing as ta
3
7
 
4
8
  from omlish import check
5
9
  from omlish import dataclasses as dc
6
- from omlish import dispatch
7
10
  from omlish import lang
8
11
  from omlish import marshal as msh
9
- from omlish import typedvalues as tv
10
12
 
11
- from .._typedvalues import _tv_field_metadata
12
- from ..content.materialize import CanContent
13
- from ..content.transforms.base import ContentTransform
14
- from ..content.types import Content
15
- from ..metadata import MetadataContainer
13
+ from ..content.content import Content
14
+ from ..metadata import MetadataContainerDataclass
16
15
  from ..tools.types import ToolUse
17
16
  from ..tools.types import ToolUseResult
17
+ from .metadata import MessageMetadata
18
18
  from .metadata import MessageMetadatas
19
19
 
20
20
 
@@ -26,7 +26,7 @@ msh.register_global_module_import('._marshal', __package__)
26
26
 
27
27
  @dc.dataclass(frozen=True)
28
28
  class Message( # noqa
29
- MetadataContainer[MessageMetadatas],
29
+ MetadataContainerDataclass[MessageMetadatas],
30
30
  lang.Abstract,
31
31
  lang.Sealed,
32
32
  ):
@@ -34,18 +34,14 @@ class Message( # noqa
34
34
  default=(),
35
35
  kw_only=True,
36
36
  repr=False,
37
- metadata=_tv_field_metadata(
38
- MessageMetadatas,
39
- marshal_name='metadata',
40
- ),
41
37
  )
42
38
 
43
- @property
44
- def metadata(self) -> tv.TypedValues[MessageMetadatas]:
45
- return check.isinstance(self._metadata, tv.TypedValues)
39
+ MetadataContainerDataclass._configure_metadata_field(_metadata, MessageMetadatas) # noqa
46
40
 
47
- def with_metadata(self, *mds: MessageMetadatas, override: bool = False) -> ta.Self:
48
- return dc.replace(self, _metadata=tv.TypedValues(*self._metadata, *mds, override=override))
41
+ def replace(self, **kwargs: ta.Any) -> ta.Self:
42
+ if (n := dc.replace_is_not(self, **kwargs)) is self:
43
+ return self
44
+ return n.with_metadata(MessageOriginal(self), discard=[MessageOriginal], override=True)
49
45
 
50
46
 
51
47
  Chat: ta.TypeAlias = ta.Sequence[Message]
@@ -54,6 +50,14 @@ Chat: ta.TypeAlias = ta.Sequence[Message]
54
50
  ##
55
51
 
56
52
 
53
+ @dc.dataclass(frozen=True)
54
+ class MessageOriginal(MessageMetadata, lang.Final):
55
+ c: Message
56
+
57
+
58
+ ##
59
+
60
+
57
61
  @dc.dataclass(frozen=True)
58
62
  class AnyUserMessage(Message, lang.Abstract):
59
63
  pass
@@ -90,7 +94,7 @@ def check_ai_chat(chat: Chat) -> AiChat:
90
94
 
91
95
  @dc.dataclass(frozen=True)
92
96
  class SystemMessage(AnyUserMessage, lang.Final):
93
- c: CanContent
97
+ c: Content
94
98
 
95
99
 
96
100
  #
@@ -99,7 +103,7 @@ class SystemMessage(AnyUserMessage, lang.Final):
99
103
  @dc.dataclass(frozen=True)
100
104
  @msh.update_fields_metadata(['name'], omit_if=operator.not_)
101
105
  class UserMessage(AnyUserMessage, lang.Final):
102
- c: CanContent
106
+ c: Content
103
107
 
104
108
  name: str | None = dc.xfield(None, repr_fn=dc.opt_repr)
105
109
 
@@ -128,23 +132,23 @@ class ToolUseResultMessage(AnyUserMessage, lang.Final):
128
132
  ##
129
133
 
130
134
 
131
- class _MessageContentTransform(ContentTransform, lang.Final, lang.NotInstantiable):
132
- @dispatch.install_method(ContentTransform.apply)
133
- def apply_system_message(self, m: SystemMessage) -> SystemMessage:
134
- return dc.replace(m, c=self.apply(m.c))
135
-
136
- @dispatch.install_method(ContentTransform.apply)
137
- def apply_user_message(self, m: UserMessage) -> UserMessage:
138
- return dc.replace(m, c=self.apply(m.c))
139
-
140
- @dispatch.install_method(ContentTransform.apply)
141
- def apply_ai_message(self, m: AiMessage) -> AiMessage:
142
- return dc.replace(m, c=self.apply(m.c))
143
-
144
- @dispatch.install_method(ContentTransform.apply)
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))
135
+ # class _MessageContentTransform(ContentTransform, lang.Final, lang.NotInstantiable):
136
+ # @dispatch.install_method(ContentTransform.apply)
137
+ # def apply_system_message(self, m: SystemMessage) -> SystemMessage:
138
+ # return dc.replace(m, c=self.apply(m.c))
139
+ #
140
+ # @dispatch.install_method(ContentTransform.apply)
141
+ # def apply_user_message(self, m: UserMessage) -> UserMessage:
142
+ # return dc.replace(m, c=self.apply(m.c))
143
+ #
144
+ # @dispatch.install_method(ContentTransform.apply)
145
+ # def apply_ai_message(self, m: AiMessage) -> AiMessage:
146
+ # return dc.replace(m, c=self.apply(m.c))
147
+ #
148
+ # @dispatch.install_method(ContentTransform.apply)
149
+ # def apply_tool_use_message(self, m: ToolUseMessage) -> ToolUseMessage:
150
+ # return dc.replace(m, tu=self.apply(m.tu))
151
+ #
152
+ # @dispatch.install_method(ContentTransform.apply)
153
+ # def apply_tool_use_result_message(self, m: ToolUseResultMessage) -> ToolUseResultMessage:
154
+ # return dc.replace(m, tur=self.apply(m.tur))
@@ -22,8 +22,9 @@ class AiDeltaJoiner:
22
22
  def __init__(self) -> None:
23
23
  super().__init__()
24
24
 
25
- self._deltas: list[AiDelta] = []
26
- self._messages: list[AnyAiMessage] = []
25
+ self._all: list[AiDelta] = []
26
+ self._queue: list[AiDelta] = []
27
+ self._out: list[AnyAiMessage] = []
27
28
 
28
29
  def _build_joined(self, deltas: ta.Sequence[AiDelta]) -> AnyAiMessage:
29
30
  dty = check.single(set(map(type, check.not_empty(deltas))))
@@ -43,6 +44,9 @@ class AiDeltaJoiner:
43
44
 
44
45
  ra = ''.join(filter(None, (td.raw_args for td in tds)))
45
46
 
47
+ if not ra:
48
+ ra = '{}'
49
+
46
50
  return ToolUseMessage(ToolUse(
47
51
  id=tds[0].id,
48
52
  name=check.non_empty_str(tds[0].name),
@@ -53,19 +57,39 @@ class AiDeltaJoiner:
53
57
  else:
54
58
  raise TypeError(dty)
55
59
 
56
- def _maybe_join(self) -> None:
57
- if not self._deltas:
60
+ def _join(self) -> None:
61
+ if not self._queue:
58
62
  return
59
63
 
60
- self._messages.append(self._build_joined(self._deltas))
61
- self._deltas.clear()
64
+ self._out.append(self._build_joined(self._queue))
65
+ self._queue.clear()
66
+
67
+ def _should_join(self, *, new: AiDelta | None = None) -> bool:
68
+ if not self._queue:
69
+ return False
70
+
71
+ if new is not None and type(self._queue[0]) is not type(new):
72
+ return True
73
+
74
+ if (
75
+ isinstance(d0 := self._queue[0], PartialToolUseAiDelta) and
76
+ isinstance(new, PartialToolUseAiDelta) and
77
+ d0.id is not None and
78
+ new.id is not None and
79
+ d0.id != new.id
80
+ ):
81
+ return True
82
+
83
+ return False
62
84
 
63
85
  def _add_one(self, d: AiDelta) -> None:
64
- if self._deltas and type(self._deltas[0]) is not type(d):
65
- self._maybe_join()
86
+ if self._should_join(new=d):
87
+ self._join()
88
+
89
+ self._all.append(d)
66
90
 
67
91
  if isinstance(d, ToolUseAiDelta):
68
- self._messages.append(ToolUseMessage(ToolUse(
92
+ self._out.append(ToolUseMessage(ToolUse(
69
93
  id=d.id,
70
94
  name=check.not_none(d.name),
71
95
  args=d.args or {},
@@ -73,13 +97,13 @@ class AiDeltaJoiner:
73
97
  )))
74
98
 
75
99
  else:
76
- self._deltas.append(d)
100
+ self._queue.append(d)
77
101
 
78
102
  def add(self, deltas: AiDeltas) -> None:
79
103
  for d in deltas:
80
104
  self._add_one(d)
81
105
 
82
106
  def build(self) -> AiChat:
83
- self._maybe_join()
107
+ self._join()
84
108
 
85
- return list(self._messages)
109
+ return list(self._out)
@@ -4,7 +4,7 @@ from omlish import dataclasses as dc
4
4
  from omlish import lang
5
5
  from omlish import marshal as msh
6
6
 
7
- from ...content.types import Content
7
+ from ...content.content import Content
8
8
  from ...stream.services import StreamOptions
9
9
  from ...types import Option
10
10
  from ...types import Output
@@ -10,9 +10,9 @@ from omlish import dataclasses as dc
10
10
  from omlish import lang
11
11
  from omlish.text import templating as tpl
12
12
 
13
- from ..content.transforms.strings import transform_content_strings
14
13
  from ..envs import Env
15
14
  from ..envs import EnvKey
15
+ from .content import transform_message_content_strings
16
16
  from .messages import Chat
17
17
  from .messages import Message
18
18
 
@@ -81,7 +81,7 @@ class ChatTemplater:
81
81
  t = self.d[s]
82
82
  return t.render(tpl.Templater.Context(env))
83
83
 
84
- return [transform_content_strings(render_content_str, self.m)]
84
+ return [transform_message_content_strings(render_content_str, self.m)]
85
85
 
86
86
  @dc.dataclass(frozen=True)
87
87
  class _PlaceholderStep(_Step):
@@ -110,7 +110,7 @@ class ChatTemplater:
110
110
  content_strs.add(s)
111
111
  return s
112
112
 
113
- transform_content_strings(visit_content_str, p.v)
113
+ transform_message_content_strings(visit_content_str, p.v)
114
114
 
115
115
  d: dict[str, tpl.Templater] = {
116
116
  s: self._template_factory(s)
@@ -8,11 +8,27 @@ _msh.register_global_module_import('._marshal', __package__)
8
8
  ##
9
9
 
10
10
 
11
- # This is everything _marshal.py references - it must all be imported before the conditional import.
11
+ # These are all of the Content subtypes - it must all be imported before the conditional import.
12
+
12
13
  from . import ( # noqa
14
+ code as _code,
15
+ composite as _composite,
16
+ content as _content,
17
+ dynamic as _dynamic,
18
+ emphasis as _emphasis,
13
19
  images as _images,
14
- materialize as _materialize,
20
+ json as _json,
21
+ link as _link,
22
+ markdown as _markdown,
23
+ namespaces as _namespaces,
24
+ placeholders as _placeholders,
25
+ quote as _quote,
26
+ raw as _raw,
27
+ recursive as _recursive,
28
+ section as _section,
15
29
  sequence as _sequence,
30
+ standard as _standard,
31
+ tag as _tag,
32
+ templates as _templates,
16
33
  text as _text,
17
- types as _types,
18
34
  )