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
ommlds/minichain/_typedvalues.py
CHANGED
|
@@ -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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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.
|
|
78
|
+
msh.FieldOptions: msh.FieldOptions(
|
|
72
79
|
name=marshal_name,
|
|
73
|
-
|
|
74
|
-
|
|
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:
|
|
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) ->
|
|
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
|
|
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
|
|
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) ->
|
|
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
|
-
|
|
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
|
-
|
|
50
|
+
cls = get_registry_cls(
|
|
50
51
|
service_cls,
|
|
51
52
|
rs.name,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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(
|
|
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
|
-
|
|
108
|
+
**kwargs,
|
|
87
109
|
)
|
|
88
110
|
|
|
89
111
|
raw_request = msh.marshal(a_req)
|
|
90
112
|
|
|
91
|
-
raw_response = http.
|
|
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-
|
|
18
|
-
'claude-opus-4-
|
|
19
|
-
'claude-opus': 'claude-opus-4-
|
|
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
|
|
20
|
-
from ....chat.stream.types import
|
|
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__(
|
|
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 =
|
|
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.
|
|
88
|
-
http_response = rs.
|
|
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
|
-
|
|
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
|
-
|
|
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([
|
|
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([
|
|
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([
|
|
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([
|
|
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)
|