ommlds 0.0.0.dev466__py3-none-any.whl → 0.0.0.dev512__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 (367) hide show
  1. ommlds/.omlish-manifests.json +404 -31
  2. ommlds/README.md +11 -0
  3. ommlds/__about__.py +21 -12
  4. ommlds/_hacks/__init__.py +4 -0
  5. ommlds/_hacks/funcs.py +110 -0
  6. ommlds/_hacks/names.py +158 -0
  7. ommlds/_hacks/params.py +73 -0
  8. ommlds/_hacks/patches.py +0 -3
  9. ommlds/backends/anthropic/protocol/__init__.py +13 -1
  10. ommlds/backends/anthropic/protocol/_dataclasses.py +1625 -0
  11. ommlds/backends/anthropic/protocol/sse/events.py +2 -0
  12. ommlds/backends/anthropic/protocol/types.py +5 -7
  13. ommlds/backends/cerebras/__init__.py +7 -0
  14. ommlds/backends/cerebras/_dataclasses.py +4254 -0
  15. ommlds/backends/cerebras/_marshal.py +24 -0
  16. ommlds/backends/cerebras/clients.py +9 -0
  17. ommlds/backends/cerebras/protocol.py +310 -0
  18. ommlds/backends/google/protocol/__init__.py +13 -0
  19. ommlds/backends/google/protocol/_dataclasses.py +5997 -0
  20. ommlds/backends/google/protocol/types.py +6 -8
  21. ommlds/backends/groq/__init__.py +7 -0
  22. ommlds/backends/groq/_dataclasses.py +3901 -0
  23. ommlds/backends/groq/_marshal.py +23 -0
  24. ommlds/backends/groq/clients.py +9 -0
  25. ommlds/backends/groq/protocol.py +247 -0
  26. ommlds/{huggingface.py → backends/huggingface/cache.py} +1 -6
  27. ommlds/backends/huggingface/cli.py +208 -0
  28. ommlds/backends/llamacpp/logging.py +4 -1
  29. ommlds/backends/mlx/caching.py +7 -3
  30. ommlds/backends/mlx/cli.py +10 -7
  31. ommlds/backends/mlx/generation.py +18 -16
  32. ommlds/backends/mlx/limits.py +10 -6
  33. ommlds/backends/mlx/loading.py +7 -4
  34. ommlds/backends/ollama/__init__.py +7 -0
  35. ommlds/backends/ollama/_dataclasses.py +3940 -0
  36. ommlds/backends/ollama/cli.py +36 -0
  37. ommlds/backends/ollama/protocol.py +201 -0
  38. ommlds/backends/openai/protocol/__init__.py +15 -1
  39. ommlds/backends/openai/protocol/_common.py +3 -5
  40. ommlds/backends/openai/protocol/_dataclasses.py +7708 -0
  41. ommlds/backends/tavily/__init__.py +7 -0
  42. ommlds/backends/tavily/_dataclasses.py +1734 -0
  43. ommlds/backends/tavily/protocol.py +299 -0
  44. ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
  45. ommlds/backends/torch/backends.py +1 -1
  46. ommlds/backends/transformers/__init__.py +14 -0
  47. ommlds/backends/transformers/filecache.py +109 -0
  48. ommlds/backends/transformers/streamers.py +73 -0
  49. ommlds/cli/__init__.py +7 -0
  50. ommlds/cli/_dataclasses.py +3835 -0
  51. ommlds/cli/asyncs.py +30 -0
  52. ommlds/cli/backends/catalog.py +88 -0
  53. ommlds/cli/backends/configs.py +9 -0
  54. ommlds/cli/backends/inject.py +100 -42
  55. ommlds/cli/{sessions/chat/backends → backends}/injection.py +1 -1
  56. ommlds/cli/backends/meta.py +82 -0
  57. ommlds/cli/{sessions/chat/backends → backends}/types.py +11 -1
  58. ommlds/cli/{sessions/chat/content → content}/messages.py +2 -2
  59. ommlds/cli/{sessions/chat/content → content}/strings.py +1 -1
  60. ommlds/cli/inject.py +17 -8
  61. ommlds/cli/inputs/asyncs.py +32 -0
  62. ommlds/cli/inputs/sync.py +75 -0
  63. ommlds/cli/main.py +346 -114
  64. ommlds/cli/rendering/configs.py +9 -0
  65. ommlds/cli/{sessions/chat/rendering → rendering}/inject.py +4 -5
  66. ommlds/cli/{sessions/chat/rendering → rendering}/markdown.py +1 -1
  67. ommlds/cli/{sessions/chat/rendering → rendering}/raw.py +1 -1
  68. ommlds/cli/{sessions/chat/rendering → rendering}/types.py +7 -1
  69. ommlds/cli/secrets.py +22 -0
  70. ommlds/cli/sessions/base.py +1 -10
  71. ommlds/cli/sessions/chat/configs.py +13 -30
  72. ommlds/cli/sessions/chat/drivers/ai/configs.py +13 -0
  73. ommlds/cli/sessions/chat/drivers/ai/events.py +57 -0
  74. ommlds/cli/sessions/chat/{chat → drivers}/ai/inject.py +15 -12
  75. ommlds/cli/sessions/chat/{chat → drivers}/ai/rendering.py +8 -8
  76. ommlds/cli/sessions/chat/{chat → drivers}/ai/services.py +5 -5
  77. ommlds/cli/sessions/chat/{chat → drivers}/ai/tools.py +4 -8
  78. ommlds/cli/sessions/chat/{chat → drivers}/ai/types.py +10 -1
  79. ommlds/cli/sessions/chat/drivers/configs.py +25 -0
  80. ommlds/cli/sessions/chat/drivers/events/inject.py +27 -0
  81. ommlds/cli/sessions/chat/drivers/events/injection.py +14 -0
  82. ommlds/cli/sessions/chat/drivers/events/manager.py +16 -0
  83. ommlds/cli/sessions/chat/drivers/events/types.py +44 -0
  84. ommlds/cli/sessions/chat/drivers/impl.py +50 -0
  85. ommlds/cli/sessions/chat/drivers/inject.py +70 -0
  86. ommlds/cli/sessions/chat/drivers/state/configs.py +13 -0
  87. ommlds/cli/sessions/chat/drivers/state/ids.py +25 -0
  88. ommlds/cli/sessions/chat/drivers/state/inject.py +83 -0
  89. ommlds/cli/sessions/chat/{chat → drivers}/state/inmemory.py +1 -6
  90. ommlds/cli/sessions/chat/{chat → drivers}/state/storage.py +18 -12
  91. ommlds/cli/sessions/chat/{chat → drivers}/state/types.py +11 -6
  92. ommlds/cli/sessions/chat/drivers/tools/configs.py +22 -0
  93. ommlds/cli/sessions/chat/drivers/tools/confirmation.py +44 -0
  94. ommlds/cli/sessions/chat/drivers/tools/errorhandling.py +39 -0
  95. ommlds/cli/sessions/chat/{tools → drivers/tools}/execution.py +3 -4
  96. ommlds/cli/sessions/chat/drivers/tools/fs/__init__.py +0 -0
  97. ommlds/cli/sessions/chat/drivers/tools/fs/configs.py +12 -0
  98. ommlds/cli/sessions/chat/drivers/tools/fs/inject.py +35 -0
  99. ommlds/cli/sessions/chat/drivers/tools/inject.py +83 -0
  100. ommlds/cli/sessions/chat/{tools → drivers/tools}/injection.py +20 -5
  101. ommlds/cli/sessions/chat/{tools → drivers/tools}/rendering.py +3 -3
  102. ommlds/cli/sessions/chat/drivers/tools/todo/__init__.py +0 -0
  103. ommlds/cli/sessions/chat/drivers/tools/todo/configs.py +12 -0
  104. ommlds/cli/sessions/chat/drivers/tools/todo/inject.py +31 -0
  105. ommlds/cli/sessions/chat/drivers/tools/weather/__init__.py +0 -0
  106. ommlds/cli/sessions/chat/drivers/tools/weather/configs.py +12 -0
  107. ommlds/cli/sessions/chat/drivers/tools/weather/inject.py +22 -0
  108. ommlds/cli/sessions/chat/{tools/weather.py → drivers/tools/weather/tools.py} +1 -1
  109. ommlds/cli/sessions/chat/drivers/types.py +31 -0
  110. ommlds/cli/sessions/chat/drivers/user/__init__.py +0 -0
  111. ommlds/cli/sessions/chat/drivers/user/configs.py +14 -0
  112. ommlds/cli/sessions/chat/drivers/user/inject.py +41 -0
  113. ommlds/cli/sessions/chat/facades/__init__.py +0 -0
  114. ommlds/cli/sessions/chat/facades/commands/__init__.py +0 -0
  115. ommlds/cli/sessions/chat/facades/commands/base.py +83 -0
  116. ommlds/cli/sessions/chat/facades/commands/configs.py +9 -0
  117. ommlds/cli/sessions/chat/facades/commands/inject.py +41 -0
  118. ommlds/cli/sessions/chat/facades/commands/injection.py +15 -0
  119. ommlds/cli/sessions/chat/facades/commands/manager.py +59 -0
  120. ommlds/cli/sessions/chat/facades/commands/simple.py +34 -0
  121. ommlds/cli/sessions/chat/facades/commands/types.py +13 -0
  122. ommlds/cli/sessions/chat/facades/configs.py +11 -0
  123. ommlds/cli/sessions/chat/facades/facade.py +26 -0
  124. ommlds/cli/sessions/chat/facades/inject.py +35 -0
  125. ommlds/cli/sessions/chat/facades/ui.py +34 -0
  126. ommlds/cli/sessions/chat/inject.py +10 -49
  127. ommlds/cli/sessions/chat/interfaces/__init__.py +0 -0
  128. ommlds/cli/sessions/chat/interfaces/bare/__init__.py +0 -0
  129. ommlds/cli/sessions/chat/interfaces/bare/configs.py +15 -0
  130. ommlds/cli/sessions/chat/interfaces/bare/inject.py +69 -0
  131. ommlds/cli/sessions/chat/interfaces/bare/interactive.py +49 -0
  132. ommlds/cli/sessions/chat/interfaces/bare/oneshot.py +21 -0
  133. ommlds/cli/sessions/chat/{tools/confirmation.py → interfaces/bare/tools.py} +3 -22
  134. ommlds/cli/sessions/chat/interfaces/base.py +13 -0
  135. ommlds/cli/sessions/chat/interfaces/configs.py +11 -0
  136. ommlds/cli/sessions/chat/interfaces/inject.py +29 -0
  137. ommlds/cli/sessions/chat/interfaces/textual/__init__.py +0 -0
  138. ommlds/cli/sessions/chat/interfaces/textual/app.py +429 -0
  139. ommlds/cli/sessions/chat/interfaces/textual/configs.py +11 -0
  140. ommlds/cli/sessions/chat/interfaces/textual/facades.py +19 -0
  141. ommlds/cli/sessions/chat/interfaces/textual/inject.py +111 -0
  142. ommlds/cli/sessions/chat/interfaces/textual/inputhistory.py +174 -0
  143. ommlds/cli/sessions/chat/interfaces/textual/interface.py +24 -0
  144. ommlds/cli/sessions/chat/interfaces/textual/styles/__init__.py +29 -0
  145. ommlds/cli/sessions/chat/interfaces/textual/styles/input.tcss +53 -0
  146. ommlds/cli/sessions/chat/interfaces/textual/styles/markdown.tcss +7 -0
  147. ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +167 -0
  148. ommlds/cli/sessions/chat/interfaces/textual/tools.py +38 -0
  149. ommlds/cli/sessions/chat/interfaces/textual/widgets/__init__.py +0 -0
  150. ommlds/cli/sessions/chat/interfaces/textual/widgets/input.py +70 -0
  151. ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +207 -0
  152. ommlds/cli/sessions/chat/session.py +8 -13
  153. ommlds/cli/sessions/completion/configs.py +5 -6
  154. ommlds/cli/sessions/completion/inject.py +15 -2
  155. ommlds/cli/sessions/completion/session.py +10 -18
  156. ommlds/cli/sessions/configs.py +10 -0
  157. ommlds/cli/sessions/embedding/configs.py +5 -6
  158. ommlds/cli/sessions/embedding/inject.py +15 -2
  159. ommlds/cli/sessions/embedding/session.py +10 -18
  160. ommlds/cli/sessions/inject.py +15 -15
  161. ommlds/cli/state/storage.py +8 -2
  162. ommlds/minichain/__init__.py +217 -60
  163. ommlds/minichain/_dataclasses.py +20640 -0
  164. ommlds/minichain/_typedvalues.py +15 -8
  165. ommlds/minichain/backends/catalogs/base.py +20 -1
  166. ommlds/minichain/backends/catalogs/simple.py +2 -2
  167. ommlds/minichain/backends/catalogs/strings.py +13 -10
  168. ommlds/minichain/backends/impls/anthropic/chat.py +28 -5
  169. ommlds/minichain/backends/impls/anthropic/names.py +3 -3
  170. ommlds/minichain/backends/impls/anthropic/protocol.py +2 -2
  171. ommlds/minichain/backends/impls/anthropic/stream.py +23 -18
  172. ommlds/minichain/backends/impls/cerebras/__init__.py +0 -0
  173. ommlds/minichain/backends/impls/cerebras/chat.py +82 -0
  174. ommlds/minichain/backends/impls/cerebras/names.py +45 -0
  175. ommlds/minichain/backends/impls/cerebras/protocol.py +143 -0
  176. ommlds/minichain/backends/impls/cerebras/stream.py +114 -0
  177. ommlds/minichain/backends/impls/duckduckgo/search.py +5 -1
  178. ommlds/minichain/backends/impls/dummy/__init__.py +0 -0
  179. ommlds/minichain/backends/impls/dummy/chat.py +69 -0
  180. ommlds/minichain/backends/impls/google/chat.py +20 -84
  181. ommlds/minichain/backends/impls/google/names.py +6 -0
  182. ommlds/minichain/backends/impls/google/protocol.py +105 -0
  183. ommlds/minichain/backends/impls/google/search.py +10 -5
  184. ommlds/minichain/backends/impls/google/stream.py +64 -142
  185. ommlds/minichain/backends/impls/google/tools.py +2 -2
  186. ommlds/minichain/backends/impls/groq/__init__.py +0 -0
  187. ommlds/minichain/backends/impls/groq/chat.py +77 -0
  188. ommlds/minichain/backends/impls/groq/names.py +48 -0
  189. ommlds/minichain/backends/impls/groq/protocol.py +143 -0
  190. ommlds/minichain/backends/impls/groq/stream.py +114 -0
  191. ommlds/minichain/backends/impls/huggingface/repos.py +1 -5
  192. ommlds/minichain/backends/impls/llamacpp/chat.py +15 -3
  193. ommlds/minichain/backends/impls/llamacpp/completion.py +7 -3
  194. ommlds/minichain/backends/impls/llamacpp/stream.py +38 -19
  195. ommlds/minichain/backends/impls/mistral.py +9 -2
  196. ommlds/minichain/backends/impls/mlx/chat.py +100 -23
  197. ommlds/minichain/backends/impls/ollama/__init__.py +0 -0
  198. ommlds/minichain/backends/impls/ollama/chat.py +193 -0
  199. ommlds/minichain/backends/impls/ollama/protocol.py +144 -0
  200. ommlds/minichain/backends/impls/openai/chat.py +14 -7
  201. ommlds/minichain/backends/impls/openai/completion.py +9 -2
  202. ommlds/minichain/backends/impls/openai/embedding.py +9 -2
  203. ommlds/minichain/backends/impls/openai/format.py +117 -115
  204. ommlds/minichain/backends/impls/openai/names.py +33 -5
  205. ommlds/minichain/backends/impls/openai/stream.py +61 -70
  206. ommlds/minichain/backends/impls/sentencepiece/tokens.py +9 -6
  207. ommlds/minichain/backends/impls/tavily.py +66 -0
  208. ommlds/minichain/backends/impls/tinygrad/chat.py +17 -14
  209. ommlds/minichain/backends/impls/tokenizers/tokens.py +9 -6
  210. ommlds/minichain/backends/impls/transformers/sentence.py +5 -2
  211. ommlds/minichain/backends/impls/transformers/tokens.py +9 -6
  212. ommlds/minichain/backends/impls/transformers/transformers.py +139 -20
  213. ommlds/minichain/backends/strings/parsing.py +2 -2
  214. ommlds/minichain/backends/strings/resolving.py +7 -2
  215. ommlds/minichain/chat/choices/stream/__init__.py +0 -0
  216. ommlds/minichain/chat/{stream → choices/stream}/adapters.py +7 -7
  217. ommlds/minichain/chat/choices/stream/joining.py +31 -0
  218. ommlds/minichain/chat/choices/stream/services.py +45 -0
  219. ommlds/minichain/chat/choices/stream/types.py +43 -0
  220. ommlds/minichain/chat/content.py +42 -0
  221. ommlds/minichain/chat/messages.py +46 -42
  222. ommlds/minichain/chat/stream/_marshal.py +4 -4
  223. ommlds/minichain/chat/stream/joining.py +56 -43
  224. ommlds/minichain/chat/stream/services.py +15 -15
  225. ommlds/minichain/chat/stream/types.py +17 -24
  226. ommlds/minichain/chat/templating.py +3 -3
  227. ommlds/minichain/content/__init__.py +20 -3
  228. ommlds/minichain/content/_marshal.py +181 -55
  229. ommlds/minichain/content/code.py +26 -0
  230. ommlds/minichain/content/composite.py +28 -0
  231. ommlds/minichain/content/content.py +27 -0
  232. ommlds/minichain/content/dynamic.py +12 -0
  233. ommlds/minichain/content/emphasis.py +27 -0
  234. ommlds/minichain/content/images.py +2 -2
  235. ommlds/minichain/content/json.py +2 -2
  236. ommlds/minichain/content/link.py +13 -0
  237. ommlds/minichain/content/markdown.py +12 -0
  238. ommlds/minichain/content/metadata.py +10 -0
  239. ommlds/minichain/content/namespaces.py +8 -0
  240. ommlds/minichain/content/placeholders.py +10 -9
  241. ommlds/minichain/content/quote.py +26 -0
  242. ommlds/minichain/content/raw.py +49 -0
  243. ommlds/minichain/content/recursive.py +12 -0
  244. ommlds/minichain/content/resources.py +22 -0
  245. ommlds/minichain/content/section.py +26 -0
  246. ommlds/minichain/content/sequence.py +17 -3
  247. ommlds/minichain/content/standard.py +32 -0
  248. ommlds/minichain/content/tag.py +28 -0
  249. ommlds/minichain/content/templates.py +13 -0
  250. ommlds/minichain/content/text.py +2 -2
  251. ommlds/minichain/content/transform/__init__.py +0 -0
  252. ommlds/minichain/content/transform/json.py +55 -0
  253. ommlds/minichain/content/transform/markdown.py +8 -0
  254. ommlds/minichain/content/transform/materialize.py +59 -0
  255. ommlds/minichain/content/transform/metadata.py +16 -0
  256. ommlds/minichain/content/transform/namespaces.py +20 -0
  257. ommlds/minichain/content/transform/placeholders.py +60 -0
  258. ommlds/minichain/content/{prepare.py → transform/prepare.py} +10 -15
  259. ommlds/minichain/content/transform/recursive.py +54 -0
  260. ommlds/minichain/content/transform/resources.py +58 -0
  261. ommlds/minichain/content/transform/standard.py +43 -0
  262. ommlds/minichain/content/{transforms → transform}/stringify.py +1 -7
  263. ommlds/minichain/content/transform/strings.py +33 -0
  264. ommlds/minichain/content/transform/templates.py +25 -0
  265. ommlds/minichain/content/transform/types.py +18 -0
  266. ommlds/minichain/content/transform/visitors.py +38 -0
  267. ommlds/minichain/content/visitors.py +218 -0
  268. ommlds/minichain/http/__init__.py +0 -0
  269. ommlds/minichain/http/stream.py +195 -0
  270. ommlds/minichain/lib/fs/tools/read.py +1 -1
  271. ommlds/minichain/lib/fs/tools/recursivels/rendering.py +1 -1
  272. ommlds/minichain/lib/fs/tools/recursivels/running.py +1 -1
  273. ommlds/minichain/lib/todo/tools/write.py +2 -1
  274. ommlds/minichain/lib/todo/types.py +1 -1
  275. ommlds/minichain/llms/types.py +4 -0
  276. ommlds/minichain/metadata.py +56 -2
  277. ommlds/minichain/models/configs.py +2 -2
  278. ommlds/minichain/models/names.py +2 -0
  279. ommlds/minichain/registries/globals.py +18 -4
  280. ommlds/minichain/resources.py +49 -3
  281. ommlds/minichain/search.py +1 -1
  282. ommlds/minichain/services/README.md +154 -0
  283. ommlds/minichain/services/__init__.py +6 -2
  284. ommlds/minichain/services/_marshal.py +46 -10
  285. ommlds/minichain/services/_origclasses.py +11 -0
  286. ommlds/minichain/services/_typedvalues.py +8 -3
  287. ommlds/minichain/services/requests.py +73 -3
  288. ommlds/minichain/services/responses.py +73 -3
  289. ommlds/minichain/services/services.py +9 -0
  290. ommlds/minichain/standard.py +8 -0
  291. ommlds/minichain/stream/services.py +43 -17
  292. ommlds/minichain/text/applypatch.py +2 -1
  293. ommlds/minichain/text/toolparsing/llamacpp/types.py +1 -1
  294. ommlds/minichain/tokens/specials.py +1 -1
  295. ommlds/minichain/tools/execution/catalog.py +2 -2
  296. ommlds/minichain/tools/execution/errorhandling.py +36 -0
  297. ommlds/minichain/tools/execution/errors.py +2 -2
  298. ommlds/minichain/tools/execution/executors.py +1 -1
  299. ommlds/minichain/tools/fns.py +1 -1
  300. ommlds/minichain/tools/jsonschema.py +2 -2
  301. ommlds/minichain/tools/reflect.py +11 -7
  302. ommlds/minichain/tools/types.py +16 -19
  303. ommlds/minichain/vectors/_marshal.py +1 -1
  304. ommlds/minichain/vectors/embeddings.py +1 -1
  305. ommlds/minichain/wrappers/__init__.py +7 -0
  306. ommlds/minichain/wrappers/firstinwins.py +144 -0
  307. ommlds/minichain/wrappers/instrument.py +146 -0
  308. ommlds/minichain/wrappers/retry.py +168 -0
  309. ommlds/minichain/wrappers/services.py +98 -0
  310. ommlds/minichain/wrappers/stream.py +57 -0
  311. ommlds/nanochat/LICENSE +21 -0
  312. ommlds/nanochat/__init__.py +0 -0
  313. ommlds/nanochat/rustbpe/LICENSE +21 -0
  314. ommlds/nanochat/rustbpe/README.md +10 -0
  315. ommlds/nanochat/tokenizers.py +440 -0
  316. ommlds/specs/__init__.py +0 -0
  317. ommlds/specs/mcp/__init__.py +0 -0
  318. ommlds/specs/mcp/_marshal.py +23 -0
  319. ommlds/specs/mcp/clients.py +146 -0
  320. ommlds/specs/mcp/protocol.py +369 -0
  321. ommlds/tools/git.py +84 -64
  322. ommlds/tools/ocr.py +1 -1
  323. ommlds/wiki/analyze.py +2 -2
  324. ommlds/wiki/models.py +4 -4
  325. ommlds/wiki/text/mfh.py +9 -9
  326. ommlds/wiki/utils/xml.py +5 -5
  327. {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/METADATA +28 -21
  328. ommlds-0.0.0.dev512.dist-info/RECORD +534 -0
  329. {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/WHEEL +1 -1
  330. ommlds/cli/backends/standard.py +0 -20
  331. ommlds/cli/sessions/chat/backends/catalog.py +0 -56
  332. ommlds/cli/sessions/chat/backends/inject.py +0 -37
  333. ommlds/cli/sessions/chat/chat/state/inject.py +0 -40
  334. ommlds/cli/sessions/chat/chat/user/inject.py +0 -61
  335. ommlds/cli/sessions/chat/chat/user/interactive.py +0 -29
  336. ommlds/cli/sessions/chat/chat/user/oneshot.py +0 -25
  337. ommlds/cli/sessions/chat/chat/user/types.py +0 -15
  338. ommlds/cli/sessions/chat/driver.py +0 -43
  339. ommlds/cli/sessions/chat/tools/inject.py +0 -145
  340. ommlds/minichain/backends/impls/openai/format2.py +0 -210
  341. ommlds/minichain/content/materialize.py +0 -196
  342. ommlds/minichain/content/simple.py +0 -47
  343. ommlds/minichain/content/transforms/base.py +0 -46
  344. ommlds/minichain/content/transforms/interleave.py +0 -70
  345. ommlds/minichain/content/transforms/squeeze.py +0 -72
  346. ommlds/minichain/content/transforms/strings.py +0 -24
  347. ommlds/minichain/content/types.py +0 -43
  348. ommlds/minichain/stream/wrap.py +0 -62
  349. ommlds-0.0.0.dev466.dist-info/RECORD +0 -376
  350. /ommlds/{cli/sessions/chat/backends → backends/huggingface}/__init__.py +0 -0
  351. /ommlds/cli/{sessions/chat/chat → content}/__init__.py +0 -0
  352. /ommlds/cli/{sessions/chat/chat/ai → inputs}/__init__.py +0 -0
  353. /ommlds/cli/{sessions/chat/chat/state → rendering}/__init__.py +0 -0
  354. /ommlds/cli/sessions/chat/{chat/user → drivers}/__init__.py +0 -0
  355. /ommlds/cli/sessions/chat/{content → drivers/ai}/__init__.py +0 -0
  356. /ommlds/cli/sessions/chat/{chat → drivers}/ai/injection.py +0 -0
  357. /ommlds/cli/sessions/chat/{phases → drivers/events}/__init__.py +0 -0
  358. /ommlds/cli/sessions/chat/{rendering → drivers/phases}/__init__.py +0 -0
  359. /ommlds/cli/sessions/chat/{phases → drivers/phases}/inject.py +0 -0
  360. /ommlds/cli/sessions/chat/{phases → drivers/phases}/injection.py +0 -0
  361. /ommlds/cli/sessions/chat/{phases → drivers/phases}/manager.py +0 -0
  362. /ommlds/cli/sessions/chat/{phases → drivers/phases}/types.py +0 -0
  363. /ommlds/cli/sessions/chat/{tools → drivers/state}/__init__.py +0 -0
  364. /ommlds/{minichain/content/transforms → cli/sessions/chat/drivers/tools}/__init__.py +0 -0
  365. {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/entry_points.txt +0 -0
  366. {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/licenses/LICENSE +0 -0
  367. {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,144 @@
1
+ """
2
+ TODO:
3
+ - stream lol
4
+ - take first open vs take first chunk
5
+ """
6
+ import typing as ta
7
+
8
+ from omlish import dataclasses as dc
9
+ from omlish import lang
10
+
11
+ from ..services.services import Service
12
+ from ..types import Output
13
+ from .services import MultiWrapperService
14
+ from .services import WrappedOptionT
15
+ from .services import WrappedOutputT
16
+ from .services import WrappedRequest
17
+ from .services import WrappedRequestV
18
+ from .services import WrappedResponse
19
+ from .services import WrappedResponseV
20
+ from .stream import WrappedStreamOutputT
21
+ from .stream import WrapperStreamService
22
+
23
+
24
+ with lang.auto_proxy_import(globals()):
25
+ import asyncio
26
+
27
+
28
+ AnyFirstInWinsService: ta.TypeAlias = ta.Union[
29
+ 'FirstInWinsService',
30
+ 'FirstInWinsStreamService',
31
+ ]
32
+
33
+
34
+ ##
35
+
36
+
37
+ @dc.dataclass()
38
+ class FirstInWinsServiceCancelledError(Exception):
39
+ e: BaseException
40
+
41
+
42
+ class FirstInWinsServiceExceptionGroup(ExceptionGroup):
43
+ pass
44
+
45
+
46
+ @dc.dataclass(frozen=True)
47
+ class FirstInWinsServiceOutput(Output):
48
+ first_in_wins_service: AnyFirstInWinsService
49
+ response_service: Service
50
+ service_exceptions: ta.Mapping[Service, Exception] | None = None
51
+
52
+
53
+ ##
54
+
55
+
56
+ class FirstInWinsService(
57
+ MultiWrapperService[
58
+ WrappedRequestV,
59
+ WrappedOptionT,
60
+ WrappedResponseV,
61
+ WrappedOutputT,
62
+ ],
63
+ lang.Abstract,
64
+ ):
65
+ pass
66
+
67
+
68
+ ##
69
+
70
+
71
+ class FirstInWinsStreamService(
72
+ WrapperStreamService[
73
+ WrappedRequestV,
74
+ WrappedOptionT,
75
+ WrappedResponseV,
76
+ WrappedOutputT,
77
+ WrappedStreamOutputT,
78
+ ],
79
+ lang.Abstract,
80
+ ):
81
+ pass
82
+
83
+
84
+ ##
85
+
86
+
87
+ class AsyncioFirstInWinsService(
88
+ FirstInWinsService[
89
+ WrappedRequestV,
90
+ WrappedOptionT,
91
+ WrappedResponseV,
92
+ WrappedOutputT,
93
+ ],
94
+ ):
95
+ async def invoke(self, request: WrappedRequest) -> WrappedResponse:
96
+ tasks: list = []
97
+ services_by_task: dict = {}
98
+ for svc in self._services:
99
+ task: asyncio.Task = asyncio.create_task(svc.invoke(request)) # type: ignore[arg-type]
100
+ tasks.append(task)
101
+ services_by_task[task] = svc
102
+
103
+ failures_by_service: dict[Service, Exception] = {}
104
+
105
+ try:
106
+ pending = set(tasks)
107
+
108
+ while pending:
109
+ done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
110
+
111
+ for t in done:
112
+ svc = services_by_task[t]
113
+
114
+ try:
115
+ response = t.result()
116
+ except asyncio.CancelledError as exc:
117
+ failures_by_service[svc] = FirstInWinsServiceCancelledError(exc)
118
+ continue
119
+ except Exception as exc: # noqa
120
+ failures_by_service[svc] = exc
121
+ continue
122
+
123
+ for p in pending:
124
+ p.cancel()
125
+
126
+ await asyncio.gather(*pending, return_exceptions=True)
127
+
128
+ return response.with_outputs(FirstInWinsServiceOutput(
129
+ self,
130
+ svc,
131
+ failures_by_service,
132
+ ))
133
+
134
+ raise FirstInWinsServiceExceptionGroup(
135
+ 'All service calls failed',
136
+ list(failures_by_service.values()),
137
+ )
138
+
139
+ finally:
140
+ for t in tasks:
141
+ if not t.done():
142
+ t.cancel()
143
+
144
+ await asyncio.gather(*tasks, return_exceptions=True)
@@ -0,0 +1,146 @@
1
+ """
2
+ TODO:
3
+ - final stream outputs
4
+ """
5
+ import datetime
6
+ import typing as ta
7
+
8
+ from omlish import dataclasses as dc
9
+ from omlish import lang
10
+
11
+ from ..services.requests import Request
12
+ from ..services.responses import Response
13
+ from .services import WrappedOptionT
14
+ from .services import WrappedOutputT
15
+ from .services import WrappedRequest
16
+ from .services import WrappedRequestV
17
+ from .services import WrappedResponse
18
+ from .services import WrappedResponseV
19
+ from .services import WrappedService
20
+ from .services import WrapperService
21
+ from .stream import WrappedStreamOutputT
22
+ from .stream import WrappedStreamResponse
23
+ from .stream import WrappedStreamService
24
+ from .stream import WrapperStreamService
25
+
26
+
27
+ ##
28
+
29
+
30
+ @dc.dataclass(frozen=True, kw_only=True)
31
+ @dc.extra_class_params(default_repr_fn=lang.opt_or_just_repr)
32
+ class InstrumentedServiceEvent:
33
+ dt: datetime.datetime = dc.field(default_factory=lang.utcnow)
34
+
35
+ req: Request | None = None
36
+
37
+ resp: Response | None = None
38
+ exc: BaseException | None = None
39
+
40
+ stream_v: lang.Maybe[ta.Any] = lang.empty()
41
+
42
+
43
+ class InstrumentedServiceEventSink(ta.Protocol):
44
+ def __call__(self, ev: InstrumentedServiceEvent) -> ta.Awaitable[None]: ...
45
+
46
+
47
+ class ListInstrumentedServiceEventSink:
48
+ def __init__(self, lst: list[InstrumentedServiceEvent] | None = None) -> None:
49
+ super().__init__()
50
+
51
+ if lst is None:
52
+ lst = []
53
+ self._lst = lst
54
+
55
+ @property
56
+ def events(self) -> ta.Sequence[InstrumentedServiceEvent]:
57
+ return self._lst
58
+
59
+ async def __call__(self, ev: InstrumentedServiceEvent) -> None:
60
+ self._lst.append(ev)
61
+
62
+
63
+ ##
64
+
65
+
66
+ class InstrumentedService(
67
+ WrapperService[
68
+ WrappedRequestV,
69
+ WrappedOptionT,
70
+ WrappedResponseV,
71
+ WrappedOutputT,
72
+ ],
73
+ ):
74
+ def __init__(
75
+ self,
76
+ service: WrappedService,
77
+ sink: InstrumentedServiceEventSink | None = None,
78
+ ) -> None:
79
+ super().__init__(service)
80
+
81
+ if sink is None:
82
+ sink = ListInstrumentedServiceEventSink()
83
+ self._sink = sink
84
+
85
+ async def invoke(self, request: WrappedRequest) -> WrappedResponse:
86
+ await self._sink(InstrumentedServiceEvent(req=request))
87
+
88
+ try:
89
+ resp = await self._service.invoke(request)
90
+
91
+ except Exception as e: # noqa
92
+ await self._sink(InstrumentedServiceEvent(req=request, exc=e))
93
+
94
+ raise
95
+
96
+ await self._sink(InstrumentedServiceEvent(req=request, resp=resp))
97
+
98
+ return resp
99
+
100
+
101
+ ##
102
+
103
+
104
+ class InstrumentedStreamService(
105
+ WrapperStreamService[
106
+ WrappedRequestV,
107
+ WrappedOptionT,
108
+ WrappedResponseV,
109
+ WrappedOutputT,
110
+ WrappedStreamOutputT,
111
+ ],
112
+ ):
113
+ def __init__(
114
+ self,
115
+ service: WrappedStreamService,
116
+ sink: InstrumentedServiceEventSink | None = None,
117
+ ) -> None:
118
+ super().__init__(service)
119
+
120
+ if sink is None:
121
+ sink = ListInstrumentedServiceEventSink()
122
+ self._sink = sink
123
+
124
+ async def invoke(self, request: WrappedRequest) -> WrappedStreamResponse:
125
+ await self._sink(InstrumentedServiceEvent(req=request))
126
+
127
+ try:
128
+ resp = await self._service.invoke(request)
129
+
130
+ except Exception as e: # noqa
131
+ await self._sink(InstrumentedServiceEvent(req=request, exc=e))
132
+
133
+ raise
134
+
135
+ await self._sink(InstrumentedServiceEvent(req=request, resp=resp))
136
+
137
+ async def inner(sink): # noqa
138
+ async with resp.v as st:
139
+ async for v in st:
140
+ await self._sink(InstrumentedServiceEvent(req=request, resp=resp, stream_v=v))
141
+
142
+ await sink(v)
143
+
144
+ # return resp.with_v(inner())
145
+
146
+ raise NotImplementedError
@@ -0,0 +1,168 @@
1
+ """
2
+ TODO:
3
+ - tenacity shit
4
+ - exception filter - retryable vs not
5
+ - explicit RetryableError wrapper?
6
+ - sleep
7
+ - jitter
8
+ - log, on retry / on except callbacks, blah blah
9
+ - stream retry:
10
+ - failed to open
11
+ - failed during stream
12
+ - buffer and replay??
13
+ - accept death mid-stream?
14
+ - ** probably **: cannot sanely impose any nontrivial stream retry strat at this layer -
15
+ """
16
+ import typing as ta
17
+
18
+ from omlish import dataclasses as dc
19
+
20
+ from ..resources import Resources
21
+ from ..stream.services import StreamResponseSink
22
+ from ..stream.services import new_stream_response
23
+ from ..types import Output
24
+ from .services import WrappedOptionT
25
+ from .services import WrappedOutputT
26
+ from .services import WrappedRequest
27
+ from .services import WrappedRequestV
28
+ from .services import WrappedResponse
29
+ from .services import WrappedResponseV
30
+ from .services import WrappedService
31
+ from .services import WrapperService
32
+ from .stream import WrappedStreamOutputT
33
+ from .stream import WrappedStreamResponse
34
+ from .stream import WrappedStreamService
35
+ from .stream import WrapperStreamService
36
+
37
+
38
+ AnyRetryService: ta.TypeAlias = ta.Union[
39
+ 'RetryService',
40
+ 'RetryStreamService',
41
+ ]
42
+
43
+
44
+ ##
45
+
46
+
47
+ @dc.dataclass()
48
+ class RetryServiceMaxRetriesExceededError(Exception):
49
+ pass
50
+
51
+
52
+ @dc.dataclass(frozen=True)
53
+ class RetryServiceOutput(Output):
54
+ retry_service: AnyRetryService
55
+ num_retries: int
56
+
57
+
58
+ ##
59
+
60
+
61
+ class RetryService(
62
+ WrapperService[
63
+ WrappedRequestV,
64
+ WrappedOptionT,
65
+ WrappedResponseV,
66
+ WrappedOutputT,
67
+ ],
68
+ ):
69
+ DEFAULT_MAX_RETRIES: ta.ClassVar[int] = 3
70
+
71
+ def __init__(
72
+ self,
73
+ service: WrappedService,
74
+ *,
75
+ max_retries: int | None = None,
76
+ ) -> None:
77
+ super().__init__(service)
78
+
79
+ if max_retries is None:
80
+ max_retries = self.DEFAULT_MAX_RETRIES
81
+ self._max_retries = max_retries
82
+
83
+ async def invoke(self, request: WrappedRequest) -> WrappedResponse:
84
+ n = 0
85
+
86
+ while True:
87
+ try:
88
+ resp = await self._service.invoke(request)
89
+
90
+ except Exception as e: # noqa
91
+ if n < self._max_retries:
92
+ n += 1
93
+ continue
94
+
95
+ raise RetryServiceMaxRetriesExceededError from e
96
+
97
+ return resp.with_outputs(RetryServiceOutput(
98
+ retry_service=self,
99
+ num_retries=n,
100
+ ))
101
+
102
+ raise RuntimeError # unreachable
103
+
104
+
105
+ ##
106
+
107
+
108
+ class RetryStreamService(
109
+ WrapperStreamService[
110
+ WrappedRequestV,
111
+ WrappedOptionT,
112
+ WrappedResponseV,
113
+ WrappedOutputT,
114
+ WrappedStreamOutputT,
115
+ ],
116
+ ):
117
+ DEFAULT_MAX_RETRIES: ta.ClassVar[int] = 3
118
+
119
+ def __init__(
120
+ self,
121
+ service: WrappedStreamService,
122
+ *,
123
+ max_retries: int | None = None,
124
+ ) -> None:
125
+ super().__init__(service)
126
+
127
+ if max_retries is None:
128
+ max_retries = self.DEFAULT_MAX_RETRIES
129
+ self._max_retries = max_retries
130
+
131
+ async def invoke(self, request: WrappedRequest) -> WrappedStreamResponse:
132
+ n = 0
133
+
134
+ while True:
135
+ try:
136
+ async with Resources.new() as rs:
137
+ in_resp = await self._service.invoke(request)
138
+ in_vs = await rs.enter_async_context(in_resp.v)
139
+
140
+ async def inner(sink: StreamResponseSink[WrappedResponseV]) -> ta.Sequence[WrappedOutputT] | None:
141
+ async for v in in_vs:
142
+ await sink.emit(v)
143
+
144
+ return in_vs.outputs
145
+
146
+ outs = [
147
+ *in_resp.outputs,
148
+ RetryServiceOutput(
149
+ retry_service=self,
150
+ num_retries=n,
151
+ ),
152
+ ]
153
+
154
+ # FIXME: ??
155
+ # if (ur := tv.as_collection(request.options).get(UseResources)) is not None:
156
+
157
+ return await new_stream_response(
158
+ rs,
159
+ inner,
160
+ outs,
161
+ )
162
+
163
+ except Exception as e: # noqa
164
+ if n < self._max_retries:
165
+ n += 1
166
+ continue
167
+
168
+ raise RetryServiceMaxRetriesExceededError from e
@@ -0,0 +1,98 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+ from omlish import lang
5
+
6
+ from ..services.requests import Request
7
+ from ..services.responses import Response
8
+ from ..services.services import Service
9
+ from ..types import Option
10
+ from ..types import Output
11
+
12
+
13
+ P = ta.ParamSpec('P')
14
+
15
+
16
+ WrappedRequestV = ta.TypeVar('WrappedRequestV')
17
+ WrappedOptionT = ta.TypeVar('WrappedOptionT', bound=Option)
18
+
19
+ WrappedResponseV = ta.TypeVar('WrappedResponseV')
20
+ WrappedOutputT = ta.TypeVar('WrappedOutputT', bound=Output)
21
+
22
+
23
+ WrappedRequest: ta.TypeAlias = Request[
24
+ WrappedRequestV,
25
+ WrappedOptionT,
26
+ ]
27
+
28
+ WrappedResponse: ta.TypeAlias = Response[
29
+ WrappedResponseV,
30
+ WrappedOutputT,
31
+ ]
32
+
33
+ WrappedService: ta.TypeAlias = Service[
34
+ WrappedRequest,
35
+ WrappedResponse,
36
+ ]
37
+
38
+
39
+ ##
40
+
41
+
42
+ class WrapperService(
43
+ lang.Abstract,
44
+ ta.Generic[
45
+ WrappedRequestV,
46
+ WrappedOptionT,
47
+ WrappedResponseV,
48
+ WrappedOutputT,
49
+ ],
50
+ ):
51
+ def __init__(
52
+ self,
53
+ service: WrappedService,
54
+ ) -> None:
55
+ super().__init__()
56
+
57
+ self._service = service
58
+
59
+
60
+ class MultiWrapperService(
61
+ lang.Abstract,
62
+ ta.Generic[
63
+ WrappedRequestV,
64
+ WrappedOptionT,
65
+ WrappedResponseV,
66
+ WrappedOutputT,
67
+ ],
68
+ ):
69
+ def __init__(
70
+ self,
71
+ *services: WrappedService,
72
+ ) -> None:
73
+ super().__init__()
74
+
75
+ self._services = check.not_empty(services)
76
+
77
+
78
+ ##
79
+
80
+
81
+ def wrap_service(
82
+ wrapped: WrappedService,
83
+ wrapper: ta.Callable[
84
+ ta.Concatenate[
85
+ WrappedService,
86
+ P,
87
+ ],
88
+ WrapperService[
89
+ WrappedRequestV,
90
+ WrappedOptionT,
91
+ WrappedResponseV,
92
+ WrappedOutputT,
93
+ ],
94
+ ],
95
+ *args: P.args,
96
+ **kwargs: P.kwargs,
97
+ ) -> WrappedService:
98
+ return ta.cast(ta.Any, wrapper(wrapped, *args, **kwargs))
@@ -0,0 +1,57 @@
1
+ import typing as ta
2
+
3
+ from omlish import lang
4
+
5
+ from ..services.requests import Request
6
+ from ..services.services import Service
7
+ from ..stream.services import StreamOptions
8
+ from ..stream.services import StreamResponse
9
+ from ..types import Output
10
+ from .services import WrappedOptionT
11
+ from .services import WrappedOutputT
12
+ from .services import WrappedRequestV
13
+ from .services import WrappedResponseV
14
+
15
+
16
+ WrappedStreamOutputT = ta.TypeVar('WrappedStreamOutputT', bound=Output)
17
+
18
+
19
+ WrappedStreamOptions: ta.TypeAlias = WrappedOptionT | StreamOptions
20
+
21
+ WrappedStreamRequest: ta.TypeAlias = Request[
22
+ WrappedRequestV,
23
+ WrappedStreamOptions,
24
+ ]
25
+
26
+ WrappedStreamResponse: ta.TypeAlias = StreamResponse[
27
+ WrappedResponseV,
28
+ WrappedOutputT,
29
+ WrappedStreamOutputT,
30
+ ]
31
+
32
+ WrappedStreamService: ta.TypeAlias = Service[
33
+ WrappedStreamRequest,
34
+ WrappedStreamResponse,
35
+ ]
36
+
37
+
38
+ ##
39
+
40
+
41
+ class WrapperStreamService(
42
+ lang.Abstract,
43
+ ta.Generic[
44
+ WrappedRequestV,
45
+ WrappedOptionT,
46
+ WrappedResponseV,
47
+ WrappedOutputT,
48
+ WrappedStreamOutputT,
49
+ ],
50
+ ):
51
+ def __init__(
52
+ self,
53
+ service: WrappedStreamService,
54
+ ) -> None:
55
+ super().__init__()
56
+
57
+ self._service = service
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Andrej Karpathy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
File without changes
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Andrej Karpathy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ # https://github.com/karpathy/rustbpe/tree/ddf848f6961a0655dc8693742fc338e5682c0d3b
2
+ # https://github.com/karpathy/nanochat/tree/9467d83cf23dcc9a9b4ca6e35103142f48a55b27
3
+
4
+ ---
5
+
6
+ # rustbpe
7
+
8
+ > The missing tiktoken training code
9
+
10
+ A very lightweight Rust library for training a GPT tokenizer. The issue is that the inference library [tiktoken](https://github.com/openai/tiktoken) is great, but only does inference. Separately, the huggingface [tokenizers](https://github.com/huggingface/tokenizers) library does training, but it is rather bloated and really hard to navigate because it has to support all the different historical baggage of how people dealt with tokenizers over the years. More recently, I also wrote the [minbpe](https://github.com/karpathy/minbpe) library which does both training and inference, but only in inefficient Python. Basically what I really want is a non-fancy, super simple, but still relatively efficient training code for GPT tokenizer (more efficient than minbpe, much cleaner/simpler than tokenizers), and then export the trained vocab for inference with tiktoken. Does that make sense? So here we are. There are more opportunities for optimization here, I just stopped a bit early because unlike minbpe before it, rustbpe is now simple and fast enough, and not a significant bottleneck for nanochat.