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.
- ommlds/.omlish-manifests.json +404 -31
- ommlds/README.md +11 -0
- ommlds/__about__.py +21 -12
- ommlds/_hacks/__init__.py +4 -0
- ommlds/_hacks/funcs.py +110 -0
- ommlds/_hacks/names.py +158 -0
- ommlds/_hacks/params.py +73 -0
- ommlds/_hacks/patches.py +0 -3
- ommlds/backends/anthropic/protocol/__init__.py +13 -1
- ommlds/backends/anthropic/protocol/_dataclasses.py +1625 -0
- ommlds/backends/anthropic/protocol/sse/events.py +2 -0
- ommlds/backends/anthropic/protocol/types.py +5 -7
- ommlds/backends/cerebras/__init__.py +7 -0
- ommlds/backends/cerebras/_dataclasses.py +4254 -0
- ommlds/backends/cerebras/_marshal.py +24 -0
- ommlds/backends/cerebras/clients.py +9 -0
- ommlds/backends/cerebras/protocol.py +310 -0
- ommlds/backends/google/protocol/__init__.py +13 -0
- ommlds/backends/google/protocol/_dataclasses.py +5997 -0
- ommlds/backends/google/protocol/types.py +6 -8
- ommlds/backends/groq/__init__.py +7 -0
- ommlds/backends/groq/_dataclasses.py +3901 -0
- ommlds/backends/groq/_marshal.py +23 -0
- ommlds/backends/groq/clients.py +9 -0
- ommlds/backends/groq/protocol.py +247 -0
- ommlds/{huggingface.py → backends/huggingface/cache.py} +1 -6
- ommlds/backends/huggingface/cli.py +208 -0
- ommlds/backends/llamacpp/logging.py +4 -1
- ommlds/backends/mlx/caching.py +7 -3
- ommlds/backends/mlx/cli.py +10 -7
- ommlds/backends/mlx/generation.py +18 -16
- ommlds/backends/mlx/limits.py +10 -6
- ommlds/backends/mlx/loading.py +7 -4
- ommlds/backends/ollama/__init__.py +7 -0
- ommlds/backends/ollama/_dataclasses.py +3940 -0
- ommlds/backends/ollama/cli.py +36 -0
- ommlds/backends/ollama/protocol.py +201 -0
- ommlds/backends/openai/protocol/__init__.py +15 -1
- ommlds/backends/openai/protocol/_common.py +3 -5
- ommlds/backends/openai/protocol/_dataclasses.py +7708 -0
- ommlds/backends/tavily/__init__.py +7 -0
- ommlds/backends/tavily/_dataclasses.py +1734 -0
- ommlds/backends/tavily/protocol.py +299 -0
- ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
- ommlds/backends/torch/backends.py +1 -1
- ommlds/backends/transformers/__init__.py +14 -0
- ommlds/backends/transformers/filecache.py +109 -0
- ommlds/backends/transformers/streamers.py +73 -0
- ommlds/cli/__init__.py +7 -0
- ommlds/cli/_dataclasses.py +3835 -0
- ommlds/cli/asyncs.py +30 -0
- ommlds/cli/backends/catalog.py +88 -0
- ommlds/cli/backends/configs.py +9 -0
- ommlds/cli/backends/inject.py +100 -42
- ommlds/cli/{sessions/chat/backends → backends}/injection.py +1 -1
- ommlds/cli/backends/meta.py +82 -0
- ommlds/cli/{sessions/chat/backends → backends}/types.py +11 -1
- ommlds/cli/{sessions/chat/content → content}/messages.py +2 -2
- ommlds/cli/{sessions/chat/content → content}/strings.py +1 -1
- ommlds/cli/inject.py +17 -8
- ommlds/cli/inputs/asyncs.py +32 -0
- ommlds/cli/inputs/sync.py +75 -0
- ommlds/cli/main.py +346 -114
- ommlds/cli/rendering/configs.py +9 -0
- ommlds/cli/{sessions/chat/rendering → rendering}/inject.py +4 -5
- ommlds/cli/{sessions/chat/rendering → rendering}/markdown.py +1 -1
- ommlds/cli/{sessions/chat/rendering → rendering}/raw.py +1 -1
- ommlds/cli/{sessions/chat/rendering → rendering}/types.py +7 -1
- ommlds/cli/secrets.py +22 -0
- ommlds/cli/sessions/base.py +1 -10
- ommlds/cli/sessions/chat/configs.py +13 -30
- ommlds/cli/sessions/chat/drivers/ai/configs.py +13 -0
- ommlds/cli/sessions/chat/drivers/ai/events.py +57 -0
- ommlds/cli/sessions/chat/{chat → drivers}/ai/inject.py +15 -12
- ommlds/cli/sessions/chat/{chat → drivers}/ai/rendering.py +8 -8
- ommlds/cli/sessions/chat/{chat → drivers}/ai/services.py +5 -5
- ommlds/cli/sessions/chat/{chat → drivers}/ai/tools.py +4 -8
- ommlds/cli/sessions/chat/{chat → drivers}/ai/types.py +10 -1
- ommlds/cli/sessions/chat/drivers/configs.py +25 -0
- ommlds/cli/sessions/chat/drivers/events/inject.py +27 -0
- ommlds/cli/sessions/chat/drivers/events/injection.py +14 -0
- ommlds/cli/sessions/chat/drivers/events/manager.py +16 -0
- ommlds/cli/sessions/chat/drivers/events/types.py +44 -0
- ommlds/cli/sessions/chat/drivers/impl.py +50 -0
- ommlds/cli/sessions/chat/drivers/inject.py +70 -0
- ommlds/cli/sessions/chat/drivers/state/configs.py +13 -0
- ommlds/cli/sessions/chat/drivers/state/ids.py +25 -0
- ommlds/cli/sessions/chat/drivers/state/inject.py +83 -0
- ommlds/cli/sessions/chat/{chat → drivers}/state/inmemory.py +1 -6
- ommlds/cli/sessions/chat/{chat → drivers}/state/storage.py +18 -12
- ommlds/cli/sessions/chat/{chat → drivers}/state/types.py +11 -6
- ommlds/cli/sessions/chat/drivers/tools/configs.py +22 -0
- ommlds/cli/sessions/chat/drivers/tools/confirmation.py +44 -0
- ommlds/cli/sessions/chat/drivers/tools/errorhandling.py +39 -0
- ommlds/cli/sessions/chat/{tools → drivers/tools}/execution.py +3 -4
- ommlds/cli/sessions/chat/drivers/tools/fs/__init__.py +0 -0
- ommlds/cli/sessions/chat/drivers/tools/fs/configs.py +12 -0
- ommlds/cli/sessions/chat/drivers/tools/fs/inject.py +35 -0
- ommlds/cli/sessions/chat/drivers/tools/inject.py +83 -0
- ommlds/cli/sessions/chat/{tools → drivers/tools}/injection.py +20 -5
- ommlds/cli/sessions/chat/{tools → drivers/tools}/rendering.py +3 -3
- ommlds/cli/sessions/chat/drivers/tools/todo/__init__.py +0 -0
- ommlds/cli/sessions/chat/drivers/tools/todo/configs.py +12 -0
- ommlds/cli/sessions/chat/drivers/tools/todo/inject.py +31 -0
- ommlds/cli/sessions/chat/drivers/tools/weather/__init__.py +0 -0
- ommlds/cli/sessions/chat/drivers/tools/weather/configs.py +12 -0
- ommlds/cli/sessions/chat/drivers/tools/weather/inject.py +22 -0
- ommlds/cli/sessions/chat/{tools/weather.py → drivers/tools/weather/tools.py} +1 -1
- ommlds/cli/sessions/chat/drivers/types.py +31 -0
- ommlds/cli/sessions/chat/drivers/user/__init__.py +0 -0
- ommlds/cli/sessions/chat/drivers/user/configs.py +14 -0
- ommlds/cli/sessions/chat/drivers/user/inject.py +41 -0
- ommlds/cli/sessions/chat/facades/__init__.py +0 -0
- ommlds/cli/sessions/chat/facades/commands/__init__.py +0 -0
- ommlds/cli/sessions/chat/facades/commands/base.py +83 -0
- ommlds/cli/sessions/chat/facades/commands/configs.py +9 -0
- ommlds/cli/sessions/chat/facades/commands/inject.py +41 -0
- ommlds/cli/sessions/chat/facades/commands/injection.py +15 -0
- ommlds/cli/sessions/chat/facades/commands/manager.py +59 -0
- ommlds/cli/sessions/chat/facades/commands/simple.py +34 -0
- ommlds/cli/sessions/chat/facades/commands/types.py +13 -0
- ommlds/cli/sessions/chat/facades/configs.py +11 -0
- ommlds/cli/sessions/chat/facades/facade.py +26 -0
- ommlds/cli/sessions/chat/facades/inject.py +35 -0
- ommlds/cli/sessions/chat/facades/ui.py +34 -0
- ommlds/cli/sessions/chat/inject.py +10 -49
- ommlds/cli/sessions/chat/interfaces/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/bare/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/bare/configs.py +15 -0
- ommlds/cli/sessions/chat/interfaces/bare/inject.py +69 -0
- ommlds/cli/sessions/chat/interfaces/bare/interactive.py +49 -0
- ommlds/cli/sessions/chat/interfaces/bare/oneshot.py +21 -0
- ommlds/cli/sessions/chat/{tools/confirmation.py → interfaces/bare/tools.py} +3 -22
- ommlds/cli/sessions/chat/interfaces/base.py +13 -0
- ommlds/cli/sessions/chat/interfaces/configs.py +11 -0
- ommlds/cli/sessions/chat/interfaces/inject.py +29 -0
- ommlds/cli/sessions/chat/interfaces/textual/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/textual/app.py +429 -0
- ommlds/cli/sessions/chat/interfaces/textual/configs.py +11 -0
- ommlds/cli/sessions/chat/interfaces/textual/facades.py +19 -0
- ommlds/cli/sessions/chat/interfaces/textual/inject.py +111 -0
- ommlds/cli/sessions/chat/interfaces/textual/inputhistory.py +174 -0
- ommlds/cli/sessions/chat/interfaces/textual/interface.py +24 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/__init__.py +29 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/input.tcss +53 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/markdown.tcss +7 -0
- ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +167 -0
- ommlds/cli/sessions/chat/interfaces/textual/tools.py +38 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/__init__.py +0 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/input.py +70 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +207 -0
- ommlds/cli/sessions/chat/session.py +8 -13
- ommlds/cli/sessions/completion/configs.py +5 -6
- ommlds/cli/sessions/completion/inject.py +15 -2
- ommlds/cli/sessions/completion/session.py +10 -18
- ommlds/cli/sessions/configs.py +10 -0
- ommlds/cli/sessions/embedding/configs.py +5 -6
- ommlds/cli/sessions/embedding/inject.py +15 -2
- ommlds/cli/sessions/embedding/session.py +10 -18
- ommlds/cli/sessions/inject.py +15 -15
- ommlds/cli/state/storage.py +8 -2
- ommlds/minichain/__init__.py +217 -60
- ommlds/minichain/_dataclasses.py +20640 -0
- ommlds/minichain/_typedvalues.py +15 -8
- ommlds/minichain/backends/catalogs/base.py +20 -1
- ommlds/minichain/backends/catalogs/simple.py +2 -2
- ommlds/minichain/backends/catalogs/strings.py +13 -10
- ommlds/minichain/backends/impls/anthropic/chat.py +28 -5
- ommlds/minichain/backends/impls/anthropic/names.py +3 -3
- ommlds/minichain/backends/impls/anthropic/protocol.py +2 -2
- ommlds/minichain/backends/impls/anthropic/stream.py +23 -18
- ommlds/minichain/backends/impls/cerebras/__init__.py +0 -0
- ommlds/minichain/backends/impls/cerebras/chat.py +82 -0
- ommlds/minichain/backends/impls/cerebras/names.py +45 -0
- ommlds/minichain/backends/impls/cerebras/protocol.py +143 -0
- ommlds/minichain/backends/impls/cerebras/stream.py +114 -0
- ommlds/minichain/backends/impls/duckduckgo/search.py +5 -1
- ommlds/minichain/backends/impls/dummy/__init__.py +0 -0
- ommlds/minichain/backends/impls/dummy/chat.py +69 -0
- ommlds/minichain/backends/impls/google/chat.py +20 -84
- ommlds/minichain/backends/impls/google/names.py +6 -0
- ommlds/minichain/backends/impls/google/protocol.py +105 -0
- ommlds/minichain/backends/impls/google/search.py +10 -5
- ommlds/minichain/backends/impls/google/stream.py +64 -142
- ommlds/minichain/backends/impls/google/tools.py +2 -2
- ommlds/minichain/backends/impls/groq/__init__.py +0 -0
- ommlds/minichain/backends/impls/groq/chat.py +77 -0
- ommlds/minichain/backends/impls/groq/names.py +48 -0
- ommlds/minichain/backends/impls/groq/protocol.py +143 -0
- ommlds/minichain/backends/impls/groq/stream.py +114 -0
- ommlds/minichain/backends/impls/huggingface/repos.py +1 -5
- ommlds/minichain/backends/impls/llamacpp/chat.py +15 -3
- ommlds/minichain/backends/impls/llamacpp/completion.py +7 -3
- ommlds/minichain/backends/impls/llamacpp/stream.py +38 -19
- ommlds/minichain/backends/impls/mistral.py +9 -2
- ommlds/minichain/backends/impls/mlx/chat.py +100 -23
- ommlds/minichain/backends/impls/ollama/__init__.py +0 -0
- ommlds/minichain/backends/impls/ollama/chat.py +193 -0
- ommlds/minichain/backends/impls/ollama/protocol.py +144 -0
- ommlds/minichain/backends/impls/openai/chat.py +14 -7
- ommlds/minichain/backends/impls/openai/completion.py +9 -2
- ommlds/minichain/backends/impls/openai/embedding.py +9 -2
- ommlds/minichain/backends/impls/openai/format.py +117 -115
- ommlds/minichain/backends/impls/openai/names.py +33 -5
- ommlds/minichain/backends/impls/openai/stream.py +61 -70
- ommlds/minichain/backends/impls/sentencepiece/tokens.py +9 -6
- ommlds/minichain/backends/impls/tavily.py +66 -0
- ommlds/minichain/backends/impls/tinygrad/chat.py +17 -14
- ommlds/minichain/backends/impls/tokenizers/tokens.py +9 -6
- ommlds/minichain/backends/impls/transformers/sentence.py +5 -2
- ommlds/minichain/backends/impls/transformers/tokens.py +9 -6
- ommlds/minichain/backends/impls/transformers/transformers.py +139 -20
- ommlds/minichain/backends/strings/parsing.py +2 -2
- ommlds/minichain/backends/strings/resolving.py +7 -2
- ommlds/minichain/chat/choices/stream/__init__.py +0 -0
- ommlds/minichain/chat/{stream → choices/stream}/adapters.py +7 -7
- ommlds/minichain/chat/choices/stream/joining.py +31 -0
- ommlds/minichain/chat/choices/stream/services.py +45 -0
- ommlds/minichain/chat/choices/stream/types.py +43 -0
- ommlds/minichain/chat/content.py +42 -0
- ommlds/minichain/chat/messages.py +46 -42
- ommlds/minichain/chat/stream/_marshal.py +4 -4
- ommlds/minichain/chat/stream/joining.py +56 -43
- ommlds/minichain/chat/stream/services.py +15 -15
- ommlds/minichain/chat/stream/types.py +17 -24
- ommlds/minichain/chat/templating.py +3 -3
- ommlds/minichain/content/__init__.py +20 -3
- ommlds/minichain/content/_marshal.py +181 -55
- ommlds/minichain/content/code.py +26 -0
- ommlds/minichain/content/composite.py +28 -0
- ommlds/minichain/content/content.py +27 -0
- ommlds/minichain/content/dynamic.py +12 -0
- ommlds/minichain/content/emphasis.py +27 -0
- ommlds/minichain/content/images.py +2 -2
- ommlds/minichain/content/json.py +2 -2
- ommlds/minichain/content/link.py +13 -0
- ommlds/minichain/content/markdown.py +12 -0
- ommlds/minichain/content/metadata.py +10 -0
- ommlds/minichain/content/namespaces.py +8 -0
- ommlds/minichain/content/placeholders.py +10 -9
- ommlds/minichain/content/quote.py +26 -0
- ommlds/minichain/content/raw.py +49 -0
- ommlds/minichain/content/recursive.py +12 -0
- ommlds/minichain/content/resources.py +22 -0
- ommlds/minichain/content/section.py +26 -0
- ommlds/minichain/content/sequence.py +17 -3
- ommlds/minichain/content/standard.py +32 -0
- ommlds/minichain/content/tag.py +28 -0
- ommlds/minichain/content/templates.py +13 -0
- ommlds/minichain/content/text.py +2 -2
- ommlds/minichain/content/transform/__init__.py +0 -0
- ommlds/minichain/content/transform/json.py +55 -0
- ommlds/minichain/content/transform/markdown.py +8 -0
- ommlds/minichain/content/transform/materialize.py +59 -0
- ommlds/minichain/content/transform/metadata.py +16 -0
- ommlds/minichain/content/transform/namespaces.py +20 -0
- ommlds/minichain/content/transform/placeholders.py +60 -0
- ommlds/minichain/content/{prepare.py → transform/prepare.py} +10 -15
- ommlds/minichain/content/transform/recursive.py +54 -0
- ommlds/minichain/content/transform/resources.py +58 -0
- ommlds/minichain/content/transform/standard.py +43 -0
- ommlds/minichain/content/{transforms → transform}/stringify.py +1 -7
- ommlds/minichain/content/transform/strings.py +33 -0
- ommlds/minichain/content/transform/templates.py +25 -0
- ommlds/minichain/content/transform/types.py +18 -0
- ommlds/minichain/content/transform/visitors.py +38 -0
- ommlds/minichain/content/visitors.py +218 -0
- ommlds/minichain/http/__init__.py +0 -0
- ommlds/minichain/http/stream.py +195 -0
- ommlds/minichain/lib/fs/tools/read.py +1 -1
- ommlds/minichain/lib/fs/tools/recursivels/rendering.py +1 -1
- ommlds/minichain/lib/fs/tools/recursivels/running.py +1 -1
- ommlds/minichain/lib/todo/tools/write.py +2 -1
- ommlds/minichain/lib/todo/types.py +1 -1
- ommlds/minichain/llms/types.py +4 -0
- ommlds/minichain/metadata.py +56 -2
- ommlds/minichain/models/configs.py +2 -2
- ommlds/minichain/models/names.py +2 -0
- ommlds/minichain/registries/globals.py +18 -4
- ommlds/minichain/resources.py +49 -3
- ommlds/minichain/search.py +1 -1
- ommlds/minichain/services/README.md +154 -0
- ommlds/minichain/services/__init__.py +6 -2
- ommlds/minichain/services/_marshal.py +46 -10
- ommlds/minichain/services/_origclasses.py +11 -0
- ommlds/minichain/services/_typedvalues.py +8 -3
- ommlds/minichain/services/requests.py +73 -3
- ommlds/minichain/services/responses.py +73 -3
- ommlds/minichain/services/services.py +9 -0
- ommlds/minichain/standard.py +8 -0
- ommlds/minichain/stream/services.py +43 -17
- ommlds/minichain/text/applypatch.py +2 -1
- ommlds/minichain/text/toolparsing/llamacpp/types.py +1 -1
- ommlds/minichain/tokens/specials.py +1 -1
- ommlds/minichain/tools/execution/catalog.py +2 -2
- ommlds/minichain/tools/execution/errorhandling.py +36 -0
- ommlds/minichain/tools/execution/errors.py +2 -2
- ommlds/minichain/tools/execution/executors.py +1 -1
- ommlds/minichain/tools/fns.py +1 -1
- ommlds/minichain/tools/jsonschema.py +2 -2
- ommlds/minichain/tools/reflect.py +11 -7
- ommlds/minichain/tools/types.py +16 -19
- ommlds/minichain/vectors/_marshal.py +1 -1
- ommlds/minichain/vectors/embeddings.py +1 -1
- ommlds/minichain/wrappers/__init__.py +7 -0
- ommlds/minichain/wrappers/firstinwins.py +144 -0
- ommlds/minichain/wrappers/instrument.py +146 -0
- ommlds/minichain/wrappers/retry.py +168 -0
- ommlds/minichain/wrappers/services.py +98 -0
- ommlds/minichain/wrappers/stream.py +57 -0
- ommlds/nanochat/LICENSE +21 -0
- ommlds/nanochat/__init__.py +0 -0
- ommlds/nanochat/rustbpe/LICENSE +21 -0
- ommlds/nanochat/rustbpe/README.md +10 -0
- ommlds/nanochat/tokenizers.py +440 -0
- ommlds/specs/__init__.py +0 -0
- ommlds/specs/mcp/__init__.py +0 -0
- ommlds/specs/mcp/_marshal.py +23 -0
- ommlds/specs/mcp/clients.py +146 -0
- ommlds/specs/mcp/protocol.py +369 -0
- ommlds/tools/git.py +84 -64
- ommlds/tools/ocr.py +1 -1
- ommlds/wiki/analyze.py +2 -2
- ommlds/wiki/models.py +4 -4
- ommlds/wiki/text/mfh.py +9 -9
- ommlds/wiki/utils/xml.py +5 -5
- {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/METADATA +28 -21
- ommlds-0.0.0.dev512.dist-info/RECORD +534 -0
- {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/WHEEL +1 -1
- ommlds/cli/backends/standard.py +0 -20
- ommlds/cli/sessions/chat/backends/catalog.py +0 -56
- ommlds/cli/sessions/chat/backends/inject.py +0 -37
- ommlds/cli/sessions/chat/chat/state/inject.py +0 -40
- ommlds/cli/sessions/chat/chat/user/inject.py +0 -61
- ommlds/cli/sessions/chat/chat/user/interactive.py +0 -29
- ommlds/cli/sessions/chat/chat/user/oneshot.py +0 -25
- ommlds/cli/sessions/chat/chat/user/types.py +0 -15
- ommlds/cli/sessions/chat/driver.py +0 -43
- ommlds/cli/sessions/chat/tools/inject.py +0 -145
- ommlds/minichain/backends/impls/openai/format2.py +0 -210
- ommlds/minichain/content/materialize.py +0 -196
- ommlds/minichain/content/simple.py +0 -47
- ommlds/minichain/content/transforms/base.py +0 -46
- ommlds/minichain/content/transforms/interleave.py +0 -70
- ommlds/minichain/content/transforms/squeeze.py +0 -72
- ommlds/minichain/content/transforms/strings.py +0 -24
- ommlds/minichain/content/types.py +0 -43
- ommlds/minichain/stream/wrap.py +0 -62
- ommlds-0.0.0.dev466.dist-info/RECORD +0 -376
- /ommlds/{cli/sessions/chat/backends → backends/huggingface}/__init__.py +0 -0
- /ommlds/cli/{sessions/chat/chat → content}/__init__.py +0 -0
- /ommlds/cli/{sessions/chat/chat/ai → inputs}/__init__.py +0 -0
- /ommlds/cli/{sessions/chat/chat/state → rendering}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat/user → drivers}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{content → drivers/ai}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat → drivers}/ai/injection.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/events}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{rendering → drivers/phases}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/inject.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/injection.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/manager.py +0 -0
- /ommlds/cli/sessions/chat/{phases → drivers/phases}/types.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/state}/__init__.py +0 -0
- /ommlds/{minichain/content/transforms → cli/sessions/chat/drivers/tools}/__init__.py +0 -0
- {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev466.dist-info → ommlds-0.0.0.dev512.dist-info}/top_level.txt +0 -0
|
@@ -2,13 +2,10 @@ import contextlib
|
|
|
2
2
|
import os.path
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
-
import llama_cpp as lcc
|
|
6
|
-
|
|
7
5
|
from omlish import check
|
|
8
6
|
from omlish import lang
|
|
9
7
|
from omlish import typedvalues as tv
|
|
10
8
|
|
|
11
|
-
from .....backends import llamacpp as lcu
|
|
12
9
|
from ....chat.choices.services import ChatChoicesRequest
|
|
13
10
|
from ....chat.choices.services import ChatChoicesResponse
|
|
14
11
|
from ....chat.choices.services import static_check_is_chat_choices_service
|
|
@@ -27,6 +24,21 @@ from .format import ROLES_MAP
|
|
|
27
24
|
from .format import get_msg_content
|
|
28
25
|
|
|
29
26
|
|
|
27
|
+
with lang.auto_proxy_import(globals()):
|
|
28
|
+
import llama_cpp as lcc
|
|
29
|
+
|
|
30
|
+
from .....backends import llamacpp as lcu
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# @omlish-manifest $.minichain.backends.strings.manifests.BackendStringsManifest(
|
|
37
|
+
# ['ChatChoicesService'],
|
|
38
|
+
# 'llamacpp',
|
|
39
|
+
# )
|
|
40
|
+
|
|
41
|
+
|
|
30
42
|
##
|
|
31
43
|
|
|
32
44
|
|
|
@@ -2,11 +2,9 @@ import contextlib
|
|
|
2
2
|
import os.path
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
from omlish import lang
|
|
7
6
|
from omlish import typedvalues as tv
|
|
8
7
|
|
|
9
|
-
from .....backends import llamacpp as lcu
|
|
10
8
|
from ....completion import CompletionOption
|
|
11
9
|
from ....completion import CompletionRequest
|
|
12
10
|
from ....completion import CompletionResponse
|
|
@@ -18,6 +16,12 @@ from ....llms.types import Temperature
|
|
|
18
16
|
from ....models.configs import ModelPath
|
|
19
17
|
|
|
20
18
|
|
|
19
|
+
with lang.auto_proxy_import(globals()):
|
|
20
|
+
import llama_cpp as lcc
|
|
21
|
+
|
|
22
|
+
from .....backends import llamacpp as lcu
|
|
23
|
+
|
|
24
|
+
|
|
21
25
|
##
|
|
22
26
|
|
|
23
27
|
|
|
@@ -2,20 +2,17 @@ import contextlib
|
|
|
2
2
|
import threading
|
|
3
3
|
import typing as ta # noqa
|
|
4
4
|
|
|
5
|
-
import llama_cpp as lcc
|
|
6
|
-
|
|
7
5
|
from omlish import check
|
|
8
6
|
from omlish import lang
|
|
9
7
|
from omlish import typedvalues as tv
|
|
10
8
|
|
|
11
|
-
from .....backends import llamacpp as lcu
|
|
12
9
|
from ....chat.choices.services import ChatChoicesOutputs
|
|
13
|
-
from ....chat.stream.services import ChatChoicesStreamRequest
|
|
14
|
-
from ....chat.stream.services import ChatChoicesStreamResponse
|
|
15
|
-
from ....chat.stream.services import static_check_is_chat_choices_stream_service
|
|
16
|
-
from ....chat.stream.types import AiChoiceDeltas
|
|
17
|
-
from ....chat.stream.types import AiChoicesDeltas
|
|
18
|
-
from ....chat.stream.types import
|
|
10
|
+
from ....chat.choices.stream.services import ChatChoicesStreamRequest
|
|
11
|
+
from ....chat.choices.stream.services import ChatChoicesStreamResponse
|
|
12
|
+
from ....chat.choices.stream.services import static_check_is_chat_choices_stream_service
|
|
13
|
+
from ....chat.choices.stream.types import AiChoiceDeltas
|
|
14
|
+
from ....chat.choices.stream.types import AiChoicesDeltas
|
|
15
|
+
from ....chat.stream.types import ContentAiDelta
|
|
19
16
|
from ....configs import Config
|
|
20
17
|
from ....models.configs import ModelPath
|
|
21
18
|
from ....resources import UseResources
|
|
@@ -26,6 +23,21 @@ from .format import ROLES_MAP
|
|
|
26
23
|
from .format import get_msg_content
|
|
27
24
|
|
|
28
25
|
|
|
26
|
+
with lang.auto_proxy_import(globals()):
|
|
27
|
+
import llama_cpp as lcc
|
|
28
|
+
|
|
29
|
+
from .....backends import llamacpp as lcu
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# @omlish-manifest $.minichain.backends.strings.manifests.BackendStringsManifest(
|
|
36
|
+
# ['ChatChoicesStreamService'],
|
|
37
|
+
# 'llamacpp',
|
|
38
|
+
# )
|
|
39
|
+
|
|
40
|
+
|
|
29
41
|
##
|
|
30
42
|
|
|
31
43
|
|
|
@@ -76,18 +88,25 @@ class LlamacppChatChoicesStreamService(lang.ExitStacked):
|
|
|
76
88
|
rs.enter_context(lang.defer(close_output))
|
|
77
89
|
|
|
78
90
|
async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs] | None:
|
|
91
|
+
last_role: ta.Any = None
|
|
92
|
+
|
|
79
93
|
for chunk in output:
|
|
80
94
|
check.state(chunk['object'] == 'chat.completion.chunk')
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
|
|
96
|
+
choice = check.single(chunk['choices'])
|
|
97
|
+
|
|
98
|
+
if not (delta := choice.get('delta', {})):
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
# FIXME: check role is assistant
|
|
102
|
+
if (role := delta.get('role')) != last_role:
|
|
103
|
+
last_role = role
|
|
104
|
+
|
|
105
|
+
# FIXME: stop reason
|
|
106
|
+
|
|
107
|
+
if (content := delta.get('content', '')):
|
|
108
|
+
await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiDelta(content)])]))
|
|
109
|
+
|
|
91
110
|
return None
|
|
92
111
|
|
|
93
112
|
return await new_stream_response(rs, inner)
|
|
@@ -40,10 +40,16 @@ class MistralChatChoicesService:
|
|
|
40
40
|
AiMessage: 'assistant',
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
def __init__(
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
*,
|
|
46
|
+
api_key: str | None = None,
|
|
47
|
+
http_client: http.AsyncHttpClient | None = None,
|
|
48
|
+
) -> None:
|
|
44
49
|
super().__init__()
|
|
45
50
|
|
|
46
51
|
self._api_key = api_key
|
|
52
|
+
self._http_client = http_client
|
|
47
53
|
|
|
48
54
|
def _get_msg_content(self, m: Message) -> str | None:
|
|
49
55
|
if isinstance(m, AiMessage):
|
|
@@ -73,7 +79,7 @@ class MistralChatChoicesService:
|
|
|
73
79
|
],
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
resp = http.
|
|
82
|
+
resp = await http.async_request(
|
|
77
83
|
'https://api.mistral.ai/v1/chat/completions',
|
|
78
84
|
method='POST',
|
|
79
85
|
data=json.dumps_compact(req_dct).encode('utf-8'),
|
|
@@ -82,6 +88,7 @@ class MistralChatChoicesService:
|
|
|
82
88
|
'Accept': 'application/json',
|
|
83
89
|
'Authorization': f'Bearer {key}',
|
|
84
90
|
},
|
|
91
|
+
client=self._http_client,
|
|
85
92
|
)
|
|
86
93
|
|
|
87
94
|
if resp.status == 429:
|
|
@@ -1,32 +1,46 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import typing as ta
|
|
2
3
|
|
|
3
4
|
from omlish import check
|
|
4
5
|
from omlish import lang
|
|
5
6
|
from omlish import typedvalues as tv
|
|
6
7
|
|
|
7
|
-
from
|
|
8
|
+
from ....chat.choices.services import ChatChoicesOutputs
|
|
8
9
|
from ....chat.choices.services import ChatChoicesRequest
|
|
9
10
|
from ....chat.choices.services import ChatChoicesResponse
|
|
10
11
|
from ....chat.choices.services import static_check_is_chat_choices_service
|
|
12
|
+
from ....chat.choices.stream.services import ChatChoicesStreamRequest
|
|
13
|
+
from ....chat.choices.stream.services import ChatChoicesStreamResponse
|
|
14
|
+
from ....chat.choices.stream.services import static_check_is_chat_choices_stream_service
|
|
15
|
+
from ....chat.choices.stream.types import AiChoiceDeltas
|
|
16
|
+
from ....chat.choices.stream.types import AiChoicesDeltas
|
|
11
17
|
from ....chat.choices.types import AiChoice
|
|
12
18
|
from ....chat.choices.types import ChatChoicesOptions
|
|
13
19
|
from ....chat.messages import AiMessage
|
|
14
20
|
from ....chat.messages import Message
|
|
15
21
|
from ....chat.messages import SystemMessage
|
|
16
22
|
from ....chat.messages import UserMessage
|
|
23
|
+
from ....chat.stream.types import ContentAiDelta
|
|
17
24
|
from ....configs import Config
|
|
18
25
|
from ....llms.types import MaxTokens
|
|
19
26
|
from ....models.configs import ModelPath
|
|
20
27
|
from ....models.configs import ModelRepo
|
|
21
28
|
from ....models.configs import ModelSpecifier
|
|
29
|
+
from ....resources import UseResources
|
|
22
30
|
from ....standard import DefaultOptions
|
|
31
|
+
from ....stream.services import StreamResponseSink
|
|
32
|
+
from ....stream.services import new_stream_response
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
with lang.auto_proxy_import(globals()):
|
|
36
|
+
from .....backends import mlx as mlxu
|
|
23
37
|
|
|
24
38
|
|
|
25
39
|
##
|
|
26
40
|
|
|
27
41
|
|
|
28
42
|
# @omlish-manifest $.minichain.backends.strings.manifests.BackendStringsManifest(
|
|
29
|
-
# ['ChatChoicesService'],
|
|
43
|
+
# ['ChatChoicesService', 'ChatChoicesStreamService'],
|
|
30
44
|
# 'mlx',
|
|
31
45
|
# )
|
|
32
46
|
|
|
@@ -34,12 +48,7 @@ from ....standard import DefaultOptions
|
|
|
34
48
|
##
|
|
35
49
|
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
# name='mlx',
|
|
39
|
-
# type='ChatChoicesService',
|
|
40
|
-
# )
|
|
41
|
-
@static_check_is_chat_choices_service
|
|
42
|
-
class MlxChatChoicesService(lang.ExitStacked):
|
|
51
|
+
class BaseMlxChatChoicesService(lang.ExitStacked):
|
|
43
52
|
DEFAULT_MODEL: ta.ClassVar[ModelSpecifier] = (
|
|
44
53
|
# 'mlx-community/DeepSeek-Coder-V2-Lite-Instruct-8bit'
|
|
45
54
|
# 'mlx-community/Llama-3.3-70B-Instruct-4bit'
|
|
@@ -52,8 +61,8 @@ class MlxChatChoicesService(lang.ExitStacked):
|
|
|
52
61
|
# 'mlx-community/Qwen2.5-0.5B-4bit'
|
|
53
62
|
# 'mlx-community/Qwen2.5-32B-Instruct-8bit'
|
|
54
63
|
# 'mlx-community/Qwen2.5-Coder-32B-Instruct-8bit'
|
|
55
|
-
# 'mlx-community/mamba-2.8b-hf-f16'
|
|
56
64
|
# 'mlx-community/Qwen3-30B-A3B-6bit'
|
|
65
|
+
# 'mlx-community/mamba-2.8b-hf-f16'
|
|
57
66
|
)
|
|
58
67
|
|
|
59
68
|
def __init__(self, *configs: Config) -> None:
|
|
@@ -70,17 +79,14 @@ class MlxChatChoicesService(lang.ExitStacked):
|
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
def _get_msg_content(self, m: Message) -> str | None:
|
|
73
|
-
if isinstance(m, AiMessage):
|
|
74
|
-
return check.isinstance(m.c, str)
|
|
75
|
-
|
|
76
|
-
elif isinstance(m, (SystemMessage, UserMessage)):
|
|
82
|
+
if isinstance(m, (AiMessage, SystemMessage, UserMessage)):
|
|
77
83
|
return check.isinstance(m.c, str)
|
|
78
84
|
|
|
79
85
|
else:
|
|
80
86
|
raise TypeError(m)
|
|
81
87
|
|
|
82
88
|
@lang.cached_function(transient=True)
|
|
83
|
-
def _load_model(self) -> mlxu.LoadedModel:
|
|
89
|
+
def _load_model(self) -> 'mlxu.LoadedModel':
|
|
84
90
|
# FIXME: walk state, find all mx.arrays, dealloc/set to empty
|
|
85
91
|
check.not_none(self._exit_stack)
|
|
86
92
|
|
|
@@ -96,10 +102,9 @@ class MlxChatChoicesService(lang.ExitStacked):
|
|
|
96
102
|
max_tokens=MaxTokens,
|
|
97
103
|
)
|
|
98
104
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
tokenizer = loaded_model.tokenization.tokenizer
|
|
105
|
+
@lang.cached_function(transient=True)
|
|
106
|
+
def _get_tokenizer(self) -> 'mlxu.tokenization.Tokenizer':
|
|
107
|
+
tokenizer = self._load_model().tokenization.tokenizer
|
|
103
108
|
|
|
104
109
|
if not (
|
|
105
110
|
hasattr(tokenizer, 'apply_chat_template') and
|
|
@@ -107,26 +112,44 @@ class MlxChatChoicesService(lang.ExitStacked):
|
|
|
107
112
|
):
|
|
108
113
|
raise RuntimeError(tokenizer)
|
|
109
114
|
|
|
110
|
-
|
|
115
|
+
return tokenizer
|
|
116
|
+
|
|
117
|
+
def _build_prompt(self, messages: ta.Sequence[Message]) -> str:
|
|
118
|
+
return check.isinstance(self._get_tokenizer().apply_chat_template(
|
|
111
119
|
[ # type: ignore[arg-type]
|
|
112
120
|
dict(
|
|
113
121
|
role=self.ROLES_MAP[type(m)],
|
|
114
122
|
content=self._get_msg_content(m),
|
|
115
123
|
)
|
|
116
|
-
for m in
|
|
124
|
+
for m in messages
|
|
117
125
|
],
|
|
118
126
|
tokenize=False,
|
|
119
127
|
add_generation_prompt=True,
|
|
120
|
-
)
|
|
128
|
+
), str)
|
|
129
|
+
|
|
130
|
+
def _build_kwargs(self, oc: tv.TypedValuesConsumer) -> dict[str, ta.Any]:
|
|
131
|
+
kwargs: dict[str, ta.Any] = {}
|
|
132
|
+
kwargs.update(oc.pop_scalar_kwargs(**self._OPTION_KWARG_NAMES_MAP))
|
|
133
|
+
return kwargs
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
|
|
136
|
+
# @omlish-manifest $.minichain.registries.manifests.RegistryManifest(
|
|
137
|
+
# name='mlx',
|
|
138
|
+
# type='ChatChoicesService',
|
|
139
|
+
# )
|
|
140
|
+
@static_check_is_chat_choices_service
|
|
141
|
+
class MlxChatChoicesService(BaseMlxChatChoicesService):
|
|
142
|
+
async def invoke(self, request: ChatChoicesRequest) -> ChatChoicesResponse:
|
|
143
|
+
loaded_model = self._load_model()
|
|
144
|
+
|
|
145
|
+
prompt = self._build_prompt(request.v)
|
|
123
146
|
|
|
124
147
|
with tv.consume(
|
|
125
148
|
*self._default_options,
|
|
126
149
|
*request.options,
|
|
127
150
|
override=True,
|
|
128
151
|
) as oc:
|
|
129
|
-
kwargs.
|
|
152
|
+
kwargs = self._build_kwargs(oc)
|
|
130
153
|
|
|
131
154
|
response = mlxu.generate(
|
|
132
155
|
loaded_model.model,
|
|
@@ -139,3 +162,57 @@ class MlxChatChoicesService(lang.ExitStacked):
|
|
|
139
162
|
return ChatChoicesResponse([
|
|
140
163
|
AiChoice([AiMessage(response)]) # noqa
|
|
141
164
|
])
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# @omlish-manifest $.minichain.registries.manifests.RegistryManifest(
|
|
168
|
+
# name='mlx',
|
|
169
|
+
# type='ChatChoicesStreamService',
|
|
170
|
+
# )
|
|
171
|
+
@static_check_is_chat_choices_stream_service
|
|
172
|
+
class MlxChatChoicesStreamService(BaseMlxChatChoicesService):
|
|
173
|
+
def __init__(self, *configs: Config) -> None:
|
|
174
|
+
super().__init__()
|
|
175
|
+
|
|
176
|
+
with tv.consume(*configs) as cc:
|
|
177
|
+
self._model = cc.pop(MlxChatChoicesService.DEFAULT_MODEL)
|
|
178
|
+
self._default_options: tv.TypedValues = DefaultOptions.pop(cc)
|
|
179
|
+
|
|
180
|
+
READ_CHUNK_SIZE = 64 * 1024
|
|
181
|
+
|
|
182
|
+
async def invoke(
|
|
183
|
+
self,
|
|
184
|
+
request: ChatChoicesStreamRequest,
|
|
185
|
+
*,
|
|
186
|
+
max_tokens: int = 4096, # FIXME: ChatOption
|
|
187
|
+
) -> ChatChoicesStreamResponse:
|
|
188
|
+
loaded_model = self._load_model()
|
|
189
|
+
|
|
190
|
+
prompt = self._build_prompt(request.v)
|
|
191
|
+
|
|
192
|
+
with tv.consume(
|
|
193
|
+
*self._default_options,
|
|
194
|
+
*request.options,
|
|
195
|
+
override=True,
|
|
196
|
+
) as oc:
|
|
197
|
+
oc.pop(UseResources, None)
|
|
198
|
+
kwargs = self._build_kwargs(oc)
|
|
199
|
+
|
|
200
|
+
async with UseResources.or_new(request.options) as rs:
|
|
201
|
+
gen: ta.Iterator[mlxu.GenerationOutput] = rs.enter_context(contextlib.closing(mlxu.stream_generate(
|
|
202
|
+
loaded_model.model,
|
|
203
|
+
loaded_model.tokenization,
|
|
204
|
+
check.isinstance(prompt, str),
|
|
205
|
+
mlxu.GenerationParams(**kwargs),
|
|
206
|
+
# verbose=True,
|
|
207
|
+
)))
|
|
208
|
+
|
|
209
|
+
async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs]:
|
|
210
|
+
for go in gen:
|
|
211
|
+
if go.text:
|
|
212
|
+
await sink.emit(AiChoicesDeltas([AiChoiceDeltas([
|
|
213
|
+
ContentAiDelta(go.text),
|
|
214
|
+
])]))
|
|
215
|
+
|
|
216
|
+
return []
|
|
217
|
+
|
|
218
|
+
return await new_stream_response(rs, inner)
|
|
File without changes
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""
|
|
2
|
+
dolphin3:latest d5ab9ae8e1f2 4.9 GB 11 months ago (no tools)
|
|
3
|
+
|
|
4
|
+
functiongemma:270m 7c19b650567a 300 MB 5 minutes ago
|
|
5
|
+
gemma3:27b a418f5838eaf 17 GB 7 weeks ago (no tools)
|
|
6
|
+
gemma3:4b a2af6cc3eb7f 3.3 GB 7 weeks ago (no tools)
|
|
7
|
+
|
|
8
|
+
llama3.2:1b baf6a787fdff 1.3 GB 13 months ago (too stupid for tools)
|
|
9
|
+
llama3.2:latest a80c4f17acd5 2.0 GB 13 months ago
|
|
10
|
+
|
|
11
|
+
devstral-small-2:24b 24277f07f62d 15 GB 15 hours ago
|
|
12
|
+
ministral-3:14b 4760c35aeb9d 9.1 GB 11 hours ago
|
|
13
|
+
mistral:latest 6577803aa9a0 4.4 GB 3 seconds ago
|
|
14
|
+
|
|
15
|
+
nemotron-3-nano:30b b725f1117407 24 GB 15 hours ago
|
|
16
|
+
|
|
17
|
+
olmo-3.1:32b-instruct a16b6a5be6cf 19 GB 11 hours ago (no tools)
|
|
18
|
+
olmo-3.1:32b-think 223d4ec84d91 19 GB 11 hours ago (no tools)
|
|
19
|
+
|
|
20
|
+
phi4-mini:latest 78fad5d182a7 2.5 GB 8 months ago (no tools)
|
|
21
|
+
|
|
22
|
+
qwen3-coder:30b 06c1097efce0 18 GB 11 hours ago
|
|
23
|
+
qwen3-next:80b b2ebb986e4e9 50 GB 11 hours ago
|
|
24
|
+
qwen3:30b ad815644918f 18 GB 11 hours ago
|
|
25
|
+
qwen3:32b 030ee887880f 20 GB 11 hours ago
|
|
26
|
+
"""
|
|
27
|
+
import typing as ta
|
|
28
|
+
|
|
29
|
+
from omlish import check
|
|
30
|
+
from omlish import lang
|
|
31
|
+
from omlish import marshal as msh
|
|
32
|
+
from omlish import typedvalues as tv
|
|
33
|
+
from omlish.formats import json
|
|
34
|
+
from omlish.http import all as http
|
|
35
|
+
from omlish.io.buffers import DelimitingBuffer
|
|
36
|
+
|
|
37
|
+
from .....backends.ollama import protocol as pt
|
|
38
|
+
from ....chat.choices.services import ChatChoicesOutputs
|
|
39
|
+
from ....chat.choices.services import ChatChoicesRequest
|
|
40
|
+
from ....chat.choices.services import ChatChoicesResponse
|
|
41
|
+
from ....chat.choices.services import static_check_is_chat_choices_service
|
|
42
|
+
from ....chat.choices.stream.services import ChatChoicesStreamRequest
|
|
43
|
+
from ....chat.choices.stream.services import ChatChoicesStreamResponse
|
|
44
|
+
from ....chat.choices.stream.services import static_check_is_chat_choices_stream_service
|
|
45
|
+
from ....chat.choices.stream.types import AiChoicesDeltas
|
|
46
|
+
from ....chat.tools.types import Tool
|
|
47
|
+
from ....models.configs import ModelName
|
|
48
|
+
from ....resources import UseResources
|
|
49
|
+
from ....standard import ApiUrl
|
|
50
|
+
from ....stream.services import StreamResponseSink
|
|
51
|
+
from ....stream.services import new_stream_response
|
|
52
|
+
from .protocol import build_mc_ai_choice_deltas
|
|
53
|
+
from .protocol import build_mc_choices_response
|
|
54
|
+
from .protocol import build_ol_request_messages
|
|
55
|
+
from .protocol import build_ol_request_tool
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# @omlish-manifest $.minichain.backends.strings.manifests.BackendStringsManifest(
|
|
62
|
+
# [
|
|
63
|
+
# 'ChatChoicesService',
|
|
64
|
+
# 'ChatChoicesStreamService',
|
|
65
|
+
# ],
|
|
66
|
+
# 'ollama',
|
|
67
|
+
# )
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class BaseOllamaChatChoicesService(lang.Abstract):
|
|
74
|
+
DEFAULT_API_URL: ta.ClassVar[ApiUrl] = ApiUrl('http://localhost:11434/api')
|
|
75
|
+
DEFAULT_MODEL_NAME: ta.ClassVar[ModelName] = ModelName('llama3.2')
|
|
76
|
+
|
|
77
|
+
def __init__(
|
|
78
|
+
self,
|
|
79
|
+
*configs: ApiUrl | ModelName,
|
|
80
|
+
http_client: http.AsyncHttpClient | None = None,
|
|
81
|
+
) -> None:
|
|
82
|
+
super().__init__()
|
|
83
|
+
|
|
84
|
+
self._http_client = http_client
|
|
85
|
+
|
|
86
|
+
with tv.consume(*configs) as cc:
|
|
87
|
+
self._api_url = cc.pop(self.DEFAULT_API_URL)
|
|
88
|
+
self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# @omlish-manifest $.minichain.registries.manifests.RegistryManifest(
|
|
95
|
+
# name='ollama',
|
|
96
|
+
# type='ChatChoicesService',
|
|
97
|
+
# )
|
|
98
|
+
@static_check_is_chat_choices_service
|
|
99
|
+
class OllamaChatChoicesService(BaseOllamaChatChoicesService):
|
|
100
|
+
async def invoke(
|
|
101
|
+
self,
|
|
102
|
+
request: ChatChoicesRequest,
|
|
103
|
+
) -> ChatChoicesResponse:
|
|
104
|
+
messages = build_ol_request_messages(request.v)
|
|
105
|
+
|
|
106
|
+
tools: list[pt.Tool] = []
|
|
107
|
+
with tv.TypedValues(*request.options).consume() as oc:
|
|
108
|
+
t: Tool
|
|
109
|
+
for t in oc.pop(Tool, []):
|
|
110
|
+
tools.append(build_ol_request_tool(t))
|
|
111
|
+
|
|
112
|
+
a_req = pt.ChatRequest(
|
|
113
|
+
model=self._model_name.v,
|
|
114
|
+
messages=messages,
|
|
115
|
+
tools=tools or None,
|
|
116
|
+
stream=False,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
raw_request = msh.marshal(a_req)
|
|
120
|
+
|
|
121
|
+
async with http.manage_async_client(self._http_client) as http_client:
|
|
122
|
+
raw_response = await http_client.request(http.HttpRequest(
|
|
123
|
+
self._api_url.v.removesuffix('/') + '/chat',
|
|
124
|
+
data=json.dumps(raw_request).encode('utf-8'),
|
|
125
|
+
))
|
|
126
|
+
|
|
127
|
+
json_response = json.loads(check.not_none(raw_response.data).decode('utf-8'))
|
|
128
|
+
|
|
129
|
+
resp = msh.unmarshal(json_response, pt.ChatResponse)
|
|
130
|
+
|
|
131
|
+
return build_mc_choices_response(resp)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# @omlish-manifest $.minichain.registries.manifests.RegistryManifest(
|
|
138
|
+
# name='ollama',
|
|
139
|
+
# type='ChatChoicesStreamService',
|
|
140
|
+
# )
|
|
141
|
+
@static_check_is_chat_choices_stream_service
|
|
142
|
+
class OllamaChatChoicesStreamService(BaseOllamaChatChoicesService):
|
|
143
|
+
READ_CHUNK_SIZE: ta.ClassVar[int] = -1
|
|
144
|
+
|
|
145
|
+
async def invoke(
|
|
146
|
+
self,
|
|
147
|
+
request: ChatChoicesStreamRequest,
|
|
148
|
+
) -> ChatChoicesStreamResponse:
|
|
149
|
+
messages = build_ol_request_messages(request.v)
|
|
150
|
+
|
|
151
|
+
tools: list[pt.Tool] = []
|
|
152
|
+
with tv.TypedValues(*request.options).consume() as oc:
|
|
153
|
+
t: Tool
|
|
154
|
+
for t in oc.pop(Tool, []):
|
|
155
|
+
tools.append(build_ol_request_tool(t))
|
|
156
|
+
|
|
157
|
+
a_req = pt.ChatRequest(
|
|
158
|
+
model=self._model_name.v,
|
|
159
|
+
messages=messages,
|
|
160
|
+
tools=tools or None,
|
|
161
|
+
stream=True,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
raw_request = msh.marshal(a_req)
|
|
165
|
+
|
|
166
|
+
http_request = http.HttpRequest(
|
|
167
|
+
self._api_url.v.removesuffix('/') + '/chat',
|
|
168
|
+
data=json.dumps(raw_request).encode('utf-8'),
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
async with UseResources.or_new(request.options) as rs:
|
|
172
|
+
http_client = await rs.enter_async_context(http.manage_async_client(self._http_client))
|
|
173
|
+
http_response = await rs.enter_async_context(await http_client.stream_request(http_request))
|
|
174
|
+
|
|
175
|
+
async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs] | None:
|
|
176
|
+
db = DelimitingBuffer([b'\r', b'\n', b'\r\n'])
|
|
177
|
+
while True:
|
|
178
|
+
b = await http_response.stream.read1(self.READ_CHUNK_SIZE)
|
|
179
|
+
for l in db.feed(b):
|
|
180
|
+
if isinstance(l, DelimitingBuffer.Incomplete):
|
|
181
|
+
# FIXME: handle
|
|
182
|
+
raise TypeError(l)
|
|
183
|
+
|
|
184
|
+
lj = json.loads(l.decode('utf-8'))
|
|
185
|
+
lp: pt.ChatResponse = msh.unmarshal(lj, pt.ChatResponse)
|
|
186
|
+
|
|
187
|
+
if (ds := build_mc_ai_choice_deltas(lp)).deltas:
|
|
188
|
+
await sink.emit(AiChoicesDeltas([ds]))
|
|
189
|
+
|
|
190
|
+
if not b:
|
|
191
|
+
return []
|
|
192
|
+
|
|
193
|
+
return await new_stream_response(rs, inner)
|