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
@@ -23,14 +23,21 @@ def _tv_field_coercer(
23
23
  ) -> ta.Callable[[ta.Sequence], tv.TypedValues]:
24
24
  if isinstance(tvc, tuple):
25
25
  check.arg(all(issubclass(e, tv.TypedValue) for e in tvc))
26
+
26
27
  else:
27
28
  check.issubclass(tvc, tv.TypedValue)
28
29
 
29
30
  def inner(seq):
30
- return tv.TypedValues(*[
31
- check.isinstance(e, tvc)
32
- for e in check.isinstance(seq, ta.Sequence)
33
- ])
31
+ if isinstance(seq, tv.TypedValues):
32
+ for e in seq:
33
+ check.isinstance(e, tvc)
34
+ return seq
35
+
36
+ else:
37
+ return tv.TypedValues(*[
38
+ check.isinstance(e, tvc)
39
+ for e in check.isinstance(seq, ta.Sequence)
40
+ ])
34
41
 
35
42
  return inner
36
43
 
@@ -68,11 +75,11 @@ def _tv_field_metadata(
68
75
  repr_fn=_tv_field_repr,
69
76
  ),
70
77
 
71
- msh.FieldMetadata: msh.FieldMetadata(
78
+ msh.FieldOptions: msh.FieldOptions(
72
79
  name=marshal_name,
73
- options=msh.FieldOptions(
74
- omit_if=operator.not_,
75
- ),
80
+
81
+ omit_if=operator.not_,
82
+
76
83
  marshaler_factory=msh.FuncMarshalerFactory(
77
84
  lambda ctx, rty: _marshal._TypedValuesFieldMarshalerFactory(tvs_rty).make_marshaler(ctx, rty), # noqa
78
85
  ),
@@ -3,15 +3,34 @@ import typing as ta
3
3
 
4
4
  from omlish import lang
5
5
 
6
+ from ...configs import Config
7
+
8
+
9
+ T = ta.TypeVar('T')
10
+
6
11
 
7
12
  ##
8
13
 
9
14
 
10
15
  class BackendCatalog(lang.Abstract):
16
+ class Backend(ta.NamedTuple):
17
+ factory: ta.Callable[..., ta.Any]
18
+ configs: ta.Sequence[Config] | None
19
+
11
20
  @abc.abstractmethod
12
- def get_backend(self, service_cls: ta.Any, name: str, *args: ta.Any, **kwargs: ta.Any) -> ta.Any:
21
+ def get_backend(self, service_cls: type[T], name: str) -> Backend:
13
22
  raise NotImplementedError
14
23
 
24
+ def new_backend(
25
+ self,
26
+ service_cls: ta.Any,
27
+ name: str,
28
+ *args: ta.Any,
29
+ **kwargs: ta.Any,
30
+ ) -> ta.Any:
31
+ be = self.get_backend(service_cls, name)
32
+ return be.factory(*be.configs or [], *args, **kwargs)
33
+
15
34
  # #
16
35
  #
17
36
  # class Bound(lang.Final, ta.Generic[T]):
@@ -40,9 +40,9 @@ class SimpleBackendCatalog(BackendCatalog):
40
40
  sc_dct[e.name] = e
41
41
  self._dct = dct
42
42
 
43
- def get_backend(self, service_cls: ta.Any, name: str, *args: ta.Any, **kwargs: ta.Any) -> ta.Any:
43
+ def get_backend(self, service_cls: ta.Any, name: str, *args: ta.Any, **kwargs: ta.Any) -> BackendCatalog.Backend:
44
44
  e = self._dct[service_cls][name]
45
- return e.factory_fn(*args, **kwargs)
45
+ return BackendCatalog.Backend(e.factory_fn, None)
46
46
 
47
47
 
48
48
  ##
@@ -5,7 +5,7 @@ from omlish import check
5
5
  from ...models.configs import ModelPath
6
6
  from ...models.configs import ModelRepo
7
7
  from ...models.repos.resolving import ModelRepoResolver
8
- from ...registries.globals import registry_new
8
+ from ...registries.globals import get_registry_cls
9
9
  from ..strings.parsing import parse_backend_string
10
10
  from ..strings.resolving import BackendStringResolver
11
11
  from ..strings.resolving import ResolveBackendStringArgs
@@ -30,26 +30,29 @@ class BackendStringBackendCatalog(BackendCatalog):
30
30
  self._string_resolver = string_resolver
31
31
  self._model_repo_resolver = model_repo_resolver
32
32
 
33
- def get_backend(self, service_cls: ta.Any, name: str, *args: ta.Any, **kwargs: ta.Any) -> ta.Any:
33
+ def get_backend(self, service_cls: ta.Any, name: str, *args: ta.Any, **kwargs: ta.Any) -> BackendCatalog.Backend:
34
34
  ps = parse_backend_string(name)
35
- rs = check.not_none(self._string_resolver.resolve_backend_string(ResolveBackendStringArgs(
35
+ rba = ResolveBackendStringArgs(
36
36
  service_cls,
37
37
  ps,
38
- )))
38
+ )
39
+ rs = check.not_none(self._string_resolver.resolve_backend_string(rba))
39
40
 
40
- al = list(rs.args or [])
41
+ al: list = list(rs.args or [])
41
42
 
42
- # FIXME: lol
43
+ # FIXME: lol - move *into* local model classes as an injected dep?
43
44
  if al and isinstance(al[0], ModelRepo):
44
45
  [mr] = al
45
46
  mrr = check.not_none(self._model_repo_resolver)
46
47
  mrp = check.not_none(mrr.resolve(mr))
47
48
  al = [ModelPath(mrp.path), *al[1:]]
48
49
 
49
- return registry_new(
50
+ cls = get_registry_cls(
50
51
  service_cls,
51
52
  rs.name,
52
- *al,
53
- *args,
54
- **kwargs,
53
+ )
54
+
55
+ return BackendCatalog.Backend(
56
+ cls,
57
+ al,
55
58
  )
@@ -17,6 +17,7 @@ from ....chat.choices.services import ChatChoicesRequest
17
17
  from ....chat.choices.services import ChatChoicesResponse
18
18
  from ....chat.choices.services import static_check_is_chat_choices_service
19
19
  from ....chat.choices.types import AiChoice
20
+ from ....chat.choices.types import ChatChoicesOptions
20
21
  from ....chat.messages import AiMessage
21
22
  from ....chat.messages import AnyAiMessage
22
23
  from ....chat.messages import Message
@@ -24,9 +25,12 @@ from ....chat.messages import SystemMessage
24
25
  from ....chat.messages import ToolUseMessage
25
26
  from ....chat.messages import UserMessage
26
27
  from ....chat.tools.types import Tool
28
+ from ....llms.types import MaxTokens
29
+ from ....llms.types import Temperature
27
30
  from ....models.configs import ModelName
28
31
  from ....standard import ApiKey
29
32
  from ....tools.types import ToolUse
33
+ from ....types import Option
30
34
  from .names import MODEL_NAMES
31
35
  from .protocol import build_protocol_chat_messages
32
36
  from .protocol import build_protocol_tool
@@ -46,9 +50,12 @@ class AnthropicChatChoicesService:
46
50
  def __init__(
47
51
  self,
48
52
  *configs: ApiKey | ModelName,
53
+ http_client: http.AsyncHttpClient | None = None,
49
54
  ) -> None:
50
55
  super().__init__()
51
56
 
57
+ self._http_client = http_client
58
+
52
59
  with tv.consume(*configs) as cc:
53
60
  self._api_key = check.not_none(ApiKey.pop_secret(cc, env='ANTHROPIC_API_KEY'))
54
61
  self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
@@ -64,16 +71,31 @@ class AnthropicChatChoicesService:
64
71
  else:
65
72
  raise TypeError(m)
66
73
 
74
+ DEFAULT_OPTIONS: ta.ClassVar[tv.TypedValues[Option]] = tv.TypedValues[Option](
75
+ MaxTokens(4096),
76
+ )
77
+
78
+ _OPTION_KWARG_NAMES_MAP: ta.ClassVar[ta.Mapping[str, type[ChatChoicesOptions]]] = dict(
79
+ temperature=Temperature,
80
+ max_tokens=MaxTokens,
81
+ )
82
+
67
83
  async def invoke(
68
84
  self,
69
85
  request: ChatChoicesRequest,
70
- *,
71
- max_tokens: int = 4096, # FIXME: ChatOption
72
86
  ) -> ChatChoicesResponse:
73
87
  messages, system = build_protocol_chat_messages(request.v)
74
88
 
89
+ kwargs: dict = dict()
90
+
75
91
  tools: list[pt.ToolSpec] = []
76
- with tv.TypedValues(*request.options).consume() as oc:
92
+ with tv.TypedValues(
93
+ *self.DEFAULT_OPTIONS,
94
+ *request.options,
95
+ override=True,
96
+ ).consume() as oc:
97
+ kwargs.update(oc.pop_scalar_kwargs(**self._OPTION_KWARG_NAMES_MAP))
98
+
77
99
  t: Tool
78
100
  for t in oc.pop(Tool, []):
79
101
  tools.append(build_protocol_tool(t))
@@ -83,12 +105,12 @@ class AnthropicChatChoicesService:
83
105
  system=system,
84
106
  messages=messages,
85
107
  tools=tools or None,
86
- max_tokens=max_tokens,
108
+ **kwargs,
87
109
  )
88
110
 
89
111
  raw_request = msh.marshal(a_req)
90
112
 
91
- raw_response = http.request(
113
+ raw_response = await http.async_request(
92
114
  'https://api.anthropic.com/v1/messages',
93
115
  headers={
94
116
  http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_JSON,
@@ -96,6 +118,7 @@ class AnthropicChatChoicesService:
96
118
  b'anthropic-version': b'2023-06-01',
97
119
  },
98
120
  data=json.dumps(raw_request).encode('utf-8'),
121
+ client=self._http_client,
99
122
  )
100
123
 
101
124
  response = json.loads(check.not_none(raw_response.data).decode('utf-8'))
@@ -14,9 +14,9 @@ from ...strings.manifests import BackendStringsManifest
14
14
  MODEL_NAMES = ModelNameCollection(
15
15
  default='claude',
16
16
  aliases={
17
- 'claude-opus-4-1-20250805': None,
18
- 'claude-opus-4-1': 'claude-opus-4-1-20250805',
19
- 'claude-opus': 'claude-opus-4-1',
17
+ 'claude-opus-4-5-20251101': None,
18
+ 'claude-opus-4-5': 'claude-opus-4-5-20251101',
19
+ 'claude-opus': 'claude-opus-4-5',
20
20
 
21
21
  'claude-sonnet-4-5-20250929': None,
22
22
  'claude-sonnet-4-5': 'claude-sonnet-4-5-20250929',
@@ -12,7 +12,7 @@ from ....chat.messages import ToolUseMessage
12
12
  from ....chat.messages import ToolUseResultMessage
13
13
  from ....chat.messages import UserMessage
14
14
  from ....chat.tools.types import Tool
15
- from ....content.prepare import prepare_content_str
15
+ from ....content.transform.prepare import prepare_content_str
16
16
  from ....tools.jsonschema import build_tool_spec_params_json_schema
17
17
 
18
18
 
@@ -104,6 +104,6 @@ def build_protocol_chat_messages(msgs: ta.Iterable[Message]) -> BuiltChatMessage
104
104
  def build_protocol_tool(t: Tool) -> pt.ToolSpec:
105
105
  return pt.ToolSpec(
106
106
  name=check.not_none(t.spec.name),
107
- description=prepare_content_str(t.spec.desc),
107
+ description=prepare_content_str(t.spec.desc) if t.spec.desc is not None else '',
108
108
  input_schema=build_tool_spec_params_json_schema(t.spec),
109
109
  )
@@ -11,13 +11,13 @@ from omlish.io.buffers import DelimitingBuffer
11
11
  from .....backends.anthropic.protocol import types as pt
12
12
  from .....backends.anthropic.protocol.sse.events import AnthropicSseDecoderEvents
13
13
  from ....chat.choices.services import ChatChoicesOutputs
14
- from ....chat.stream.services import ChatChoicesStreamRequest
15
- from ....chat.stream.services import ChatChoicesStreamResponse
16
- from ....chat.stream.services import static_check_is_chat_choices_stream_service
17
- from ....chat.stream.types import AiChoiceDeltas
18
- from ....chat.stream.types import AiChoicesDeltas
19
- from ....chat.stream.types import ContentAiChoiceDelta
20
- from ....chat.stream.types import PartialToolUseAiChoiceDelta
14
+ from ....chat.choices.stream.services import ChatChoicesStreamRequest
15
+ from ....chat.choices.stream.services import ChatChoicesStreamResponse
16
+ from ....chat.choices.stream.services import static_check_is_chat_choices_stream_service
17
+ from ....chat.choices.stream.types import AiChoiceDeltas
18
+ from ....chat.choices.stream.types import AiChoicesDeltas
19
+ from ....chat.stream.types import ContentAiDelta
20
+ from ....chat.stream.types import PartialToolUseAiDelta
21
21
  from ....chat.tools.types import Tool
22
22
  from ....configs import Config
23
23
  from ....resources import UseResources
@@ -39,14 +39,20 @@ from .protocol import build_protocol_tool
39
39
  # )
40
40
  @static_check_is_chat_choices_stream_service
41
41
  class AnthropicChatChoicesStreamService:
42
- def __init__(self, *configs: Config) -> None:
42
+ def __init__(
43
+ self,
44
+ *configs: Config,
45
+ http_client: http.AsyncHttpClient | None = None,
46
+ ) -> None:
43
47
  super().__init__()
44
48
 
49
+ self._http_client = http_client
50
+
45
51
  with tv.consume(*configs) as cc:
46
52
  self._model_name = cc.pop(AnthropicChatChoicesService.DEFAULT_MODEL_NAME)
47
53
  self._api_key = check.not_none(ApiKey.pop_secret(cc, env='ANTHROPIC_API_KEY'))
48
54
 
49
- READ_CHUNK_SIZE = 64 * 1024
55
+ READ_CHUNK_SIZE: ta.ClassVar[int] = -1
50
56
 
51
57
  async def invoke(
52
58
  self,
@@ -84,8 +90,8 @@ class AnthropicChatChoicesStreamService:
84
90
  )
85
91
 
86
92
  async with UseResources.or_new(request.options) as rs:
87
- http_client = rs.enter_context(http.client())
88
- http_response = rs.enter_context(http_client.stream_request(http_request))
93
+ http_client = await rs.enter_async_context(http.manage_async_client(self._http_client))
94
+ http_response = await rs.enter_async_context(await http_client.stream_request(http_request))
89
95
 
90
96
  async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs] | None:
91
97
  msg_start: AnthropicSseDecoderEvents.MessageStart | None = None
@@ -95,12 +101,11 @@ class AnthropicChatChoicesStreamService:
95
101
  db = DelimitingBuffer([b'\r', b'\n', b'\r\n'])
96
102
  sd = sse.SseDecoder()
97
103
  while True:
98
- # FIXME: read1 not on response stream protocol
99
- b = http_response.stream.read1(self.READ_CHUNK_SIZE) # type: ignore[attr-defined]
104
+ b = await http_response.stream.read1(self.READ_CHUNK_SIZE)
100
105
  for l in db.feed(b):
101
106
  if isinstance(l, DelimitingBuffer.Incomplete):
102
107
  # FIXME: handle
103
- return []
108
+ raise TypeError(l)
104
109
 
105
110
  # FIXME: https://docs.anthropic.com/en/docs/build-with-claude/streaming
106
111
  for so in sd.process_line(l):
@@ -126,12 +131,12 @@ class AnthropicChatChoicesStreamService:
126
131
  cbk_start = ae
127
132
 
128
133
  if isinstance(ae.content_block, AnthropicSseDecoderEvents.ContentBlockStart.Text): # noqa
129
- await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiChoiceDelta(
134
+ await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiDelta(
130
135
  ae.content_block.text,
131
136
  )])]))
132
137
 
133
138
  elif isinstance(ae.content_block, AnthropicSseDecoderEvents.ContentBlockStart.ToolUse): # noqa
134
- await sink.emit(AiChoicesDeltas([AiChoiceDeltas([PartialToolUseAiChoiceDelta( # noqa
139
+ await sink.emit(AiChoicesDeltas([AiChoiceDeltas([PartialToolUseAiDelta( # noqa
135
140
  id=ae.content_block.id,
136
141
  name=ae.content_block.name,
137
142
  raw_args=ae.content_block.input,
@@ -144,12 +149,12 @@ class AnthropicChatChoicesStreamService:
144
149
  check.not_none(cbk_start)
145
150
 
146
151
  if isinstance(ae.delta, AnthropicSseDecoderEvents.ContentBlockDelta.TextDelta):
147
- await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiChoiceDelta(
152
+ await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiDelta(
148
153
  ae.delta.text,
149
154
  )])]))
150
155
 
151
156
  elif isinstance(ae.delta, AnthropicSseDecoderEvents.ContentBlockDelta.InputJsonDelta): # noqa
152
- await sink.emit(AiChoicesDeltas([AiChoiceDeltas([PartialToolUseAiChoiceDelta( # noqa
157
+ await sink.emit(AiChoicesDeltas([AiChoiceDeltas([PartialToolUseAiDelta( # noqa
153
158
  raw_args=ae.delta.partial_json,
154
159
  )])]))
155
160
 
File without changes
@@ -0,0 +1,82 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+ from omlish import marshal as msh
5
+ from omlish import typedvalues as tv
6
+ from omlish.formats import json
7
+ from omlish.http import all as http
8
+
9
+ from .....backends.cerebras import protocol as pt
10
+ from .....backends.cerebras.clients import REQUIRED_HTTP_HEADERS
11
+ from ....chat.choices.services import ChatChoicesRequest
12
+ from ....chat.choices.services import ChatChoicesResponse
13
+ from ....chat.choices.services import static_check_is_chat_choices_service
14
+ from ....chat.tools.types import Tool
15
+ from ....models.configs import ModelName
16
+ from ....standard import ApiKey
17
+ from ....standard import DefaultOptions
18
+ from .names import MODEL_NAMES
19
+ from .protocol import build_cer_request_messages
20
+ from .protocol import build_cer_request_tool
21
+ from .protocol import build_mc_choices_response
22
+
23
+
24
+ ##
25
+
26
+
27
+ # @omlish-manifest $.minichain.registries.manifests.RegistryManifest(
28
+ # name='cerebras',
29
+ # type='ChatChoicesService',
30
+ # )
31
+ @static_check_is_chat_choices_service
32
+ class CerebrasChatChoicesService:
33
+ DEFAULT_MODEL_NAME: ta.ClassVar[ModelName] = ModelName(check.not_none(MODEL_NAMES.default))
34
+
35
+ def __init__(
36
+ self,
37
+ *configs: ApiKey | ModelName | DefaultOptions,
38
+ http_client: http.AsyncHttpClient | None = None,
39
+ ) -> None:
40
+ super().__init__()
41
+
42
+ self._http_client = http_client
43
+
44
+ with tv.consume(*configs) as cc:
45
+ self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
46
+ self._api_key = ApiKey.pop_secret(cc, env='CEREBRAS_API_KEY')
47
+ self._default_options: tv.TypedValues = DefaultOptions.pop(cc)
48
+
49
+ async def invoke(self, request: ChatChoicesRequest) -> ChatChoicesResponse:
50
+ tools: list[pt.ChatCompletionRequest.Tool] = []
51
+ with tv.TypedValues(*request.options).consume() as oc:
52
+ t: Tool
53
+ for t in oc.pop(Tool, []):
54
+ tools.append(build_cer_request_tool(t))
55
+
56
+ cer_request = pt.ChatCompletionRequest(
57
+ messages=build_cer_request_messages(request.v),
58
+ model=MODEL_NAMES.resolve(self._model_name.v),
59
+ tools=tools or None,
60
+ )
61
+
62
+ raw_request = msh.marshal(cer_request)
63
+
64
+ # TODO: headers:
65
+ # - CF-RAY
66
+ # - X-Amz-Cf-Id
67
+ # - X-delay-time
68
+
69
+ http_response = await http.async_request(
70
+ 'https://api.cerebras.ai/v1/chat/completions',
71
+ headers={
72
+ http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_JSON,
73
+ http.consts.HEADER_AUTH: http.consts.format_bearer_auth_header(check.not_none(self._api_key).reveal()),
74
+ **REQUIRED_HTTP_HEADERS,
75
+ },
76
+ data=json.dumps(raw_request).encode('utf-8'),
77
+ client=self._http_client,
78
+ )
79
+
80
+ raw_response = json.loads(check.not_none(http_response.data).decode('utf-8'))
81
+
82
+ return build_mc_choices_response(msh.unmarshal(raw_response, pt.ChatCompletionResponse))
@@ -0,0 +1,45 @@
1
+ """
2
+ https://inference-docs.cerebras.ai/models/overview
3
+ """
4
+ from ....models.names import ModelNameCollection
5
+ from ...strings.manifests import BackendStringsManifest
6
+
7
+
8
+ ##
9
+
10
+
11
+ MODEL_NAMES = ModelNameCollection(
12
+ default='gpt-oss-120b',
13
+ aliases={
14
+ 'llama3.1-8b': None,
15
+
16
+ 'llama-3.3-70b': None,
17
+ 'llama3': 'llama-3.3-70b',
18
+
19
+ 'gpt-oss-120b': None,
20
+ 'gpt-oss': 'gpt-oss-120b',
21
+
22
+ 'qwen-3-32b': None,
23
+ 'qwen3': 'qwen-3-32b',
24
+
25
+ ##
26
+ # preview
27
+
28
+ 'qwen-3-235b-a22b-instruct-2507': None,
29
+ 'qwen-3-235b': 'qwen-3-235b-a22b-instruct-2507',
30
+
31
+ 'zai-glm-4.7': None,
32
+ 'glm': 'zai-glm-4.7',
33
+ },
34
+ )
35
+
36
+
37
+ # @omlish-manifest
38
+ _BACKEND_STRINGS_MANIFEST = BackendStringsManifest(
39
+ [
40
+ 'ChatChoicesService',
41
+ 'ChatChoicesStreamService',
42
+ ],
43
+ 'cerebras',
44
+ model_names=MODEL_NAMES,
45
+ )
@@ -0,0 +1,143 @@
1
+ import itertools
2
+
3
+ from omlish import check
4
+ from omlish.formats import json
5
+
6
+ from .....backends.cerebras import protocol as pt
7
+ from ....chat.choices.services import ChatChoicesResponse
8
+ from ....chat.choices.stream.types import AiChoiceDeltas
9
+ from ....chat.choices.types import AiChoice
10
+ from ....chat.messages import AiMessage
11
+ from ....chat.messages import AnyAiMessage
12
+ from ....chat.messages import Chat
13
+ from ....chat.messages import SystemMessage
14
+ from ....chat.messages import ToolUseMessage
15
+ from ....chat.messages import ToolUseResultMessage
16
+ from ....chat.messages import UserMessage
17
+ from ....chat.stream.types import AiDelta
18
+ from ....chat.stream.types import ContentAiDelta
19
+ from ....chat.stream.types import PartialToolUseAiDelta
20
+ from ....chat.tools.types import Tool
21
+ from ....content.transform.prepare import prepare_content_str
22
+ from ....tools.jsonschema import build_tool_spec_params_json_schema
23
+ from ....tools.types import ToolUse
24
+
25
+
26
+ ##
27
+
28
+
29
+ def build_cer_request_messages(chat: Chat) -> list[pt.ChatCompletionRequest.Message]:
30
+ cer_msgs: list[pt.ChatCompletionRequest.Message] = []
31
+
32
+ for _, g in itertools.groupby(chat, lambda mc_m: isinstance(mc_m, AnyAiMessage)):
33
+ mc_msgs = list(g)
34
+
35
+ if isinstance(mc_msgs[0], AnyAiMessage):
36
+ tups: list[tuple[AiMessage | None, list[ToolUseMessage]]] = []
37
+ for mc_msg in mc_msgs:
38
+ if isinstance(mc_msg, AiMessage):
39
+ tups.append((mc_msg, []))
40
+
41
+ elif isinstance(mc_msg, ToolUseMessage):
42
+ if not tups:
43
+ tups.append((None, []))
44
+ tups[-1][1].append(mc_msg)
45
+
46
+ else:
47
+ raise TypeError(mc_msg)
48
+
49
+ for mc_ai_msg, mc_tu_msgs in tups:
50
+ cer_msgs.append(pt.ChatCompletionRequest.AssistantMessage(
51
+ content=check.isinstance(mc_ai_msg.c, str) if mc_ai_msg is not None else None,
52
+ tool_calls=[
53
+ pt.ChatCompletionRequest.AssistantMessage.ToolCall(
54
+ function=pt.ChatCompletionRequest.AssistantMessage.ToolCall.Function(
55
+ name=mc_tu_msg.tu.name,
56
+ arguments=check.not_none(mc_tu_msg.tu.raw_args),
57
+ ),
58
+ id=check.not_none(mc_tu_msg.tu.id),
59
+ )
60
+ for mc_tu_msg in mc_tu_msgs
61
+ ] if mc_tu_msgs else None,
62
+ ))
63
+
64
+ else:
65
+ for mc_msg in mc_msgs:
66
+ if isinstance(mc_msg, SystemMessage):
67
+ cer_msgs.append(pt.ChatCompletionRequest.SystemMessage(
68
+ content=check.isinstance(mc_msg.c, str),
69
+ ))
70
+
71
+ elif isinstance(mc_msg, UserMessage):
72
+ cer_msgs.append(pt.ChatCompletionRequest.UserMessage(
73
+ content=check.isinstance(mc_msg.c, str),
74
+ ))
75
+
76
+ elif isinstance(mc_msg, ToolUseResultMessage):
77
+ cer_msgs.append(pt.ChatCompletionRequest.ToolMessage(
78
+ tool_call_id=check.not_none(mc_msg.tur.id),
79
+ content=check.isinstance(mc_msg.tur.c, str),
80
+ ))
81
+
82
+ else:
83
+ raise TypeError(mc_msg)
84
+
85
+ return cer_msgs
86
+
87
+
88
+ def build_cer_request_tool(t: Tool) -> pt.ChatCompletionRequest.Tool:
89
+ return pt.ChatCompletionRequest.Tool(
90
+ function=pt.ChatCompletionRequest.Tool.Function(
91
+ name=check.not_none(t.spec.name),
92
+ description=prepare_content_str(t.spec.desc) if t.spec.desc is not None else None,
93
+ parameters=build_tool_spec_params_json_schema(t.spec),
94
+ ),
95
+ )
96
+
97
+
98
+ def build_mc_choices_response(cer_resp: pt.ChatCompletionResponse) -> ChatChoicesResponse:
99
+ def build_choice(cer_choice: pt.ChatCompletionResponse.Choice) -> AiChoice:
100
+ cer_msg = cer_choice.message
101
+
102
+ lst: list[AnyAiMessage] = []
103
+
104
+ if cer_msg.content is not None:
105
+ lst.append(AiMessage(
106
+ check.isinstance(cer_msg.content, str),
107
+ ))
108
+
109
+ for cer_tc in cer_msg.tool_calls or []:
110
+ lst.append(ToolUseMessage(ToolUse(
111
+ id=cer_tc.id,
112
+ name=cer_tc.function.name,
113
+ args=json.loads(cer_tc.function.arguments or '{}'),
114
+ raw_args=cer_tc.function.arguments,
115
+ )))
116
+
117
+ return AiChoice(lst)
118
+
119
+ return ChatChoicesResponse(list(map(build_choice, cer_resp.choices)))
120
+
121
+
122
+ def build_mc_ai_choice_deltas(delta: pt.ChatCompletionChunk.Choice.Delta) -> AiChoiceDeltas:
123
+ if delta.role in (None, 'assistant'):
124
+ lst: list[AiDelta] = []
125
+
126
+ if delta.content is not None:
127
+ lst.append(ContentAiDelta(delta.content))
128
+
129
+ for tc in delta.tool_calls or []:
130
+ tc_fn = check.not_none(tc.function)
131
+ lst.append(PartialToolUseAiDelta(
132
+ id=tc.id,
133
+ name=tc_fn.name,
134
+ raw_args=tc_fn.arguments,
135
+ ))
136
+
137
+ return AiChoiceDeltas(lst)
138
+
139
+ elif delta.channel in ('analysis', 'commentary'):
140
+ return AiChoiceDeltas([])
141
+
142
+ else:
143
+ raise ValueError(delta)