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
ommlds/tools/git.py CHANGED
@@ -3,15 +3,13 @@ TODO:
3
3
  - move omit magic to omdev lol
4
4
  """
5
5
  import abc
6
- import concurrent.futures as cf
7
6
  import dataclasses as dc
8
- import os.path
9
7
  import re
10
8
  import typing as ta
11
9
  import urllib.request
12
10
 
13
11
  from omdev.git.magic import GIT_DIFF_OMIT_MAGIC_COMMENT
14
- from omdev.home.secrets import load_secrets
12
+ from omdev.py.srcheaders import get_py_header_lines
15
13
  from omdev.tools.git.messages import GitMessageGenerator
16
14
  from omlish import check
17
15
  from omlish import lang
@@ -20,14 +18,10 @@ from omlish.http import all as http
20
18
  from omlish.subprocesses.sync import subprocesses
21
19
 
22
20
  from .. import minichain as mc
23
- from ..minichain.backends.impls.openai.chat import OpenaiChatChoicesService
21
+ from ..cli.secrets import install_env_secrets
24
22
  from ..server.client import McServerClient
25
23
 
26
24
 
27
- with lang.auto_proxy_import(globals()):
28
- from ..minichain.backends.impls.mlx import chat as mc_mlx_chat
29
-
30
-
31
25
  GitAiBackendConfigT = ta.TypeVar('GitAiBackendConfigT', bound='GitAiBackend.Config')
32
26
 
33
27
 
@@ -35,7 +29,7 @@ GitAiBackendConfigT = ta.TypeVar('GitAiBackendConfigT', bound='GitAiBackend.Conf
35
29
 
36
30
 
37
31
  class GitAiBackend(Configurable[GitAiBackendConfigT], lang.Abstract):
38
- @dc.dataclass(frozen=True)
32
+ @dc.dataclass(frozen=True, kw_only=True)
39
33
  class Config(Configurable.Config):
40
34
  max_tokens: int | None = 128
41
35
 
@@ -63,22 +57,35 @@ def _get_single_ai_message_str(resp: mc.ChatChoicesResponse) -> str:
63
57
  #
64
58
 
65
59
 
66
- class OpenaiGitAiBackend(GitAiBackend['OpenaiGitAiBackend.Config']):
67
- @dc.dataclass(frozen=True)
60
+ class StandardGitAiBackend(GitAiBackend['StandardGitAiBackend.Config']):
61
+ @dc.dataclass(frozen=True, kw_only=True)
68
62
  class Config(GitAiBackend.Config):
69
- pass
63
+ backend: str | None = None
70
64
 
71
- def __init__(self, config: Config = Config()) -> None:
65
+ DEFAULT_BACKEND_NAME: str = 'openai'
66
+
67
+ def __init__(
68
+ self,
69
+ config: Config = Config(),
70
+ *,
71
+ backend_catalog: ta.Optional['mc.BackendCatalog'] = None,
72
+ ) -> None:
72
73
  super().__init__(config)
73
74
 
75
+ if backend_catalog is None:
76
+ backend_catalog = mc.BackendStringBackendCatalog()
77
+ self._backend_catalog = backend_catalog
78
+
74
79
  def run_prompt(self, prompt: str) -> str:
75
- # FIXME:
76
- for key in ['OPENAI_API_KEY']:
77
- if (sec := load_secrets().try_get(key.lower())) is not None:
78
- os.environ[key] = sec.reveal()
80
+ install_env_secrets() # FIXME
81
+
82
+ be = self._backend_catalog.get_backend(
83
+ mc.ChatChoicesService, # type: ignore[type-abstract]
84
+ self._config.backend or self.DEFAULT_BACKEND_NAME,
85
+ )
79
86
 
80
- llm = OpenaiChatChoicesService(
81
- http_client=http.SyncAsyncHttpClient(http.client()),
87
+ llm = be.factory(
88
+ http_client=http.SyncAsyncHttpClient(http.client()), # FIXME
82
89
  )
83
90
 
84
91
  resp = lang.sync_await(llm.invoke(mc.ChatChoicesRequest(
@@ -97,51 +104,51 @@ def _strip_markdown_code_block(text: str) -> str:
97
104
  return match.group(1)
98
105
 
99
106
 
100
- class MlxGitAiBackend(GitAiBackend['MlxGitAiBackend.Config']):
101
- @dc.dataclass(frozen=True)
102
- class Config(GitAiBackend.Config):
103
- model: str = 'mlx-community/Qwen2.5-Coder-32B-Instruct-8bit'
104
-
105
- run_in_subprocess: bool = True
106
- subprocess_timeout: float | None = 60.
107
-
108
- def __init__(self, config: Config = Config()) -> None:
109
- super().__init__(config)
110
-
111
- def _run_prompt(self, prompt: str) -> str:
112
- with mc_mlx_chat.MlxChatChoicesService(mc.ModelRepo.parse(self._config.model)) as llm:
113
- resp = lang.sync_await(llm.invoke(mc.ChatChoicesRequest(
114
- [mc.UserMessage(prompt)],
115
- # FIXME: *((MaxTokens(self._config.max_tokens),) if self._config.max_tokens is not None else ()),
116
- )))
117
- text = _get_single_ai_message_str(resp)
118
-
119
- text = _strip_markdown_code_block(text)
120
-
121
- return text
122
-
123
- def run_prompt(self, prompt: str) -> str:
124
- if self._config.run_in_subprocess:
125
- # tokenizers installs a pthread_atfork callback at *import* time:
126
- # https://github.com/huggingface/tokenizers/blob/4f1a810aa258d287e6936315e63fbf58bde2a980/bindings/python/src/lib.rs#L57
127
- # then complains about `TOKENIZERS_PARALLELISM` at the next fork (which presumably will happen immediately
128
- # after this to `git commit`, despite it being conceptually just a fork/exe).
129
- # TODO: a generic subprocessing minichain service wrapper?
130
- with cf.ProcessPoolExecutor() as exe:
131
- return exe.submit(
132
- self._run_prompt,
133
- prompt,
134
- ).result(timeout=self._config.subprocess_timeout)
135
-
136
- else:
137
- return self._run_prompt(prompt)
107
+ # class MlxGitAiBackend(GitAiBackend['MlxGitAiBackend.Config']):
108
+ # @dc.dataclass(frozen=True, kw_only=True)
109
+ # class Config(GitAiBackend.Config):
110
+ # model: str = 'mlx-community/Qwen2.5-Coder-32B-Instruct-8bit'
111
+ #
112
+ # run_in_subprocess: bool = True
113
+ # subprocess_timeout: float | None = 60.
114
+ #
115
+ # def __init__(self, config: Config = Config()) -> None:
116
+ # super().__init__(config)
117
+ #
118
+ # def _run_prompt(self, prompt: str) -> str:
119
+ # with mc_mlx_chat.MlxChatChoicesService(mc.ModelRepo.parse(self._config.model)) as llm:
120
+ # resp = lang.sync_await(llm.invoke(mc.ChatChoicesRequest(
121
+ # [mc.UserMessage(prompt)],
122
+ # # FIXME: *((MaxTokens(self._config.max_tokens),) if self._config.max_tokens is not None else ()),
123
+ # )))
124
+ # text = _get_single_ai_message_str(resp)
125
+ #
126
+ # text = _strip_markdown_code_block(text)
127
+ #
128
+ # return text
129
+ #
130
+ # def run_prompt(self, prompt: str) -> str:
131
+ # if self._config.run_in_subprocess:
132
+ # # tokenizers installs a pthread_atfork callback at *import* time:
133
+ # # https://github.com/huggingface/tokenizers/blob/4f1a810aa258d287e6936315e63fbf58bde2a980/bindings/python/src/lib.rs#L57 # noqa
134
+ # # then complains about `TOKENIZERS_PARALLELISM` at the next fork (which presumably will happen immediately
135
+ # # after this to `git commit`, despite it being conceptually just a fork/exe).
136
+ # # TODO: a generic subprocessing minichain service wrapper?
137
+ # with cf.ProcessPoolExecutor() as exe:
138
+ # return exe.submit(
139
+ # self._run_prompt,
140
+ # prompt,
141
+ # ).result(timeout=self._config.subprocess_timeout)
142
+ #
143
+ # else:
144
+ # return self._run_prompt(prompt)
138
145
 
139
146
 
140
147
  #
141
148
 
142
149
 
143
150
  class LocalhostHttpPostGitAiBackend(GitAiBackend['LocalhostHttpPostGitAiBackend.Config']):
144
- @dc.dataclass(frozen=True)
151
+ @dc.dataclass(frozen=True, kw_only=True)
145
152
  class Config(GitAiBackend.Config):
146
153
  port: int = 5067
147
154
  path: str = ''
@@ -165,7 +172,7 @@ class LocalhostHttpPostGitAiBackend(GitAiBackend['LocalhostHttpPostGitAiBackend.
165
172
 
166
173
 
167
174
  class McServerGitAiBackend(GitAiBackend['McServerGitAiBackend.Config']):
168
- @dc.dataclass(frozen=True)
175
+ @dc.dataclass(frozen=True, kw_only=True)
169
176
  class Config(GitAiBackend.Config):
170
177
  pass
171
178
 
@@ -191,18 +198,23 @@ class AiGitMessageGenerator(GitMessageGenerator):
191
198
  def __init__(
192
199
  self,
193
200
  *,
194
- backend: GitAiBackend | None = None,
201
+ backend: GitAiBackend | str | None = None,
195
202
  ) -> None:
196
203
  super().__init__()
197
204
 
198
205
  if backend is None:
199
206
  backend = self.DEFAULT_BACKEND
200
- self._backend = backend
207
+ elif isinstance(backend, str):
208
+ backend = StandardGitAiBackend(
209
+ config=StandardGitAiBackend.Config(
210
+ backend=backend,
211
+ ),
212
+ )
213
+ self._backend = check.isinstance(backend, GitAiBackend)
201
214
 
202
215
  DEFAULT_BACKEND: ta.ClassVar[GitAiBackend] = (
203
- OpenaiGitAiBackend()
216
+ StandardGitAiBackend()
204
217
  # LocalhostHttpPostGitAiBackend()
205
- # MlxGitAiBackend()
206
218
  # McServerGitAiBackend()
207
219
  )
208
220
 
@@ -216,9 +228,14 @@ class AiGitMessageGenerator(GitMessageGenerator):
216
228
  except FileNotFoundError:
217
229
  return False
218
230
 
231
+ hls = get_py_header_lines(f_src)
232
+
219
233
  return any(
220
- l.startswith(GIT_DIFF_OMIT_MAGIC_COMMENT)
221
- for l in f_src.splitlines()
234
+ hl.src.strip() in (
235
+ '# @omlish-generated',
236
+ GIT_DIFF_OMIT_MAGIC_COMMENT,
237
+ )
238
+ for hl in hls
222
239
  )
223
240
 
224
241
  # TODO: configurable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommlds
3
- Version: 0.0.0.dev480
3
+ Version: 0.0.0.dev503
4
4
  Summary: ommlds
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,39 +14,41 @@ 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: omdev==0.0.0.dev480
18
- Requires-Dist: omlish==0.0.0.dev480
17
+ Requires-Dist: omlish==0.0.0.dev503
19
18
  Provides-Extra: all
19
+ Requires-Dist: omdev==0.0.0.dev503; 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
- Requires-Dist: mlx-lm~=0.28; sys_platform == "darwin" and extra == "all"
22
+ Requires-Dist: mlx-lm~=0.29; sys_platform == "darwin" and extra == "all"
23
23
  Requires-Dist: tiktoken~=0.12; extra == "all"
24
24
  Requires-Dist: tinygrad~=0.11; extra == "all"
25
25
  Requires-Dist: tokenizers~=0.22; extra == "all"
26
26
  Requires-Dist: torch~=2.9; extra == "all"
27
27
  Requires-Dist: transformers~=4.57; extra == "all"
28
- Requires-Dist: sentence-transformers~=5.1; extra == "all"
28
+ Requires-Dist: sentence-transformers~=5.2; extra == "all"
29
29
  Requires-Dist: huggingface-hub~=0.36; extra == "all"
30
30
  Requires-Dist: datasets~=4.4; extra == "all"
31
31
  Requires-Dist: regex>=2025.0; extra == "all"
32
32
  Requires-Dist: numpy>=1.26; extra == "all"
33
33
  Requires-Dist: pytesseract~=0.3; extra == "all"
34
34
  Requires-Dist: rapidocr-onnxruntime~=1.4; extra == "all"
35
- Requires-Dist: pillow~=12.0; extra == "all"
36
- Requires-Dist: ddgs~=9.9; extra == "all"
35
+ Requires-Dist: pillow~=12.1; extra == "all"
36
+ Requires-Dist: ddgs~=9.10; extra == "all"
37
37
  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
+ Provides-Extra: omdev
41
+ Requires-Dist: omdev==0.0.0.dev503; extra == "omdev"
40
42
  Provides-Extra: backends
41
43
  Requires-Dist: llama-cpp-python~=0.3; extra == "backends"
42
44
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "backends"
43
- Requires-Dist: mlx-lm~=0.28; sys_platform == "darwin" and extra == "backends"
45
+ Requires-Dist: mlx-lm~=0.29; sys_platform == "darwin" and extra == "backends"
44
46
  Requires-Dist: tiktoken~=0.12; extra == "backends"
45
47
  Requires-Dist: tinygrad~=0.11; extra == "backends"
46
48
  Requires-Dist: tokenizers~=0.22; extra == "backends"
47
49
  Requires-Dist: torch~=2.9; extra == "backends"
48
50
  Requires-Dist: transformers~=4.57; extra == "backends"
49
- Requires-Dist: sentence-transformers~=5.1; extra == "backends"
51
+ Requires-Dist: sentence-transformers~=5.2; extra == "backends"
50
52
  Provides-Extra: huggingface
51
53
  Requires-Dist: huggingface-hub~=0.36; extra == "huggingface"
52
54
  Requires-Dist: datasets~=4.4; extra == "huggingface"
@@ -58,9 +60,9 @@ Provides-Extra: ocr
58
60
  Requires-Dist: pytesseract~=0.3; extra == "ocr"
59
61
  Requires-Dist: rapidocr-onnxruntime~=1.4; extra == "ocr"
60
62
  Provides-Extra: pillow
61
- Requires-Dist: pillow~=12.0; extra == "pillow"
63
+ Requires-Dist: pillow~=12.1; extra == "pillow"
62
64
  Provides-Extra: search
63
- Requires-Dist: ddgs~=9.9; extra == "search"
65
+ Requires-Dist: ddgs~=9.10; extra == "search"
64
66
  Provides-Extra: wiki
65
67
  Requires-Dist: mwparserfromhell~=0.7; extra == "wiki"
66
68
  Requires-Dist: wikitextparser~=0.56; extra == "wiki"