ommlds 0.0.0.dev480__py3-none-any.whl → 0.0.0.dev503__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ommlds/.omlish-manifests.json +100 -33
- ommlds/README.md +11 -0
- ommlds/__about__.py +9 -6
- 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/cerebras/__init__.py +7 -0
- ommlds/backends/cerebras/_dataclasses.py +4254 -0
- ommlds/backends/cerebras/_marshal.py +24 -0
- ommlds/backends/cerebras/protocol.py +312 -0
- ommlds/backends/google/protocol/__init__.py +13 -0
- ommlds/backends/google/protocol/_dataclasses.py +5997 -0
- ommlds/backends/groq/__init__.py +7 -0
- ommlds/backends/groq/_dataclasses.py +3901 -0
- ommlds/backends/groq/clients.py +9 -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 +3488 -0
- ommlds/backends/ollama/protocol.py +3 -0
- ommlds/backends/openai/protocol/__init__.py +15 -1
- ommlds/backends/openai/protocol/_dataclasses.py +7708 -0
- ommlds/backends/tavily/__init__.py +7 -0
- ommlds/backends/tavily/_dataclasses.py +1734 -0
- ommlds/backends/transformers/__init__.py +14 -0
- ommlds/cli/__init__.py +7 -0
- ommlds/cli/_dataclasses.py +3515 -0
- ommlds/cli/backends/catalog.py +0 -5
- ommlds/cli/backends/inject.py +70 -7
- ommlds/cli/backends/meta.py +82 -0
- ommlds/cli/content/messages.py +1 -1
- ommlds/cli/inject.py +11 -3
- ommlds/cli/main.py +137 -68
- ommlds/cli/rendering/types.py +6 -0
- ommlds/cli/secrets.py +2 -1
- ommlds/cli/sessions/base.py +1 -10
- ommlds/cli/sessions/chat/configs.py +9 -17
- ommlds/cli/sessions/chat/{chat → drivers}/ai/configs.py +3 -1
- ommlds/cli/sessions/chat/drivers/ai/events.py +57 -0
- ommlds/cli/sessions/chat/{chat → drivers}/ai/inject.py +10 -3
- ommlds/cli/sessions/chat/{chat → drivers}/ai/rendering.py +1 -1
- ommlds/cli/sessions/chat/{chat → drivers}/ai/services.py +1 -1
- ommlds/cli/sessions/chat/{chat → drivers}/ai/tools.py +4 -8
- ommlds/cli/sessions/chat/{chat → drivers}/ai/types.py +9 -0
- 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 +38 -0
- ommlds/cli/sessions/chat/drivers/impl.py +50 -0
- ommlds/cli/sessions/chat/drivers/inject.py +70 -0
- ommlds/cli/sessions/chat/{chat → drivers}/state/configs.py +2 -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 +0 -4
- ommlds/cli/sessions/chat/{chat → drivers}/state/storage.py +17 -10
- ommlds/cli/sessions/chat/{chat → drivers}/state/types.py +10 -5
- ommlds/cli/sessions/chat/{tools → drivers/tools}/configs.py +2 -2
- 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/{tools → drivers/tools}/fs/inject.py +3 -3
- ommlds/cli/sessions/chat/{tools → drivers/tools}/inject.py +7 -12
- ommlds/cli/sessions/chat/{tools → drivers/tools}/injection.py +5 -5
- ommlds/cli/sessions/chat/{tools → drivers/tools}/rendering.py +3 -3
- ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/inject.py +3 -3
- ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/tools.py +1 -1
- ommlds/cli/sessions/chat/drivers/types.py +31 -0
- ommlds/cli/sessions/chat/{chat → drivers}/user/configs.py +0 -3
- 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 +8 -31
- 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 +310 -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 +97 -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 +157 -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 +36 -0
- ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +197 -0
- ommlds/cli/sessions/chat/session.py +8 -13
- ommlds/cli/sessions/completion/configs.py +3 -4
- ommlds/cli/sessions/completion/inject.py +1 -2
- ommlds/cli/sessions/completion/session.py +4 -8
- ommlds/cli/sessions/configs.py +10 -0
- ommlds/cli/sessions/embedding/configs.py +3 -4
- ommlds/cli/sessions/embedding/inject.py +1 -2
- ommlds/cli/sessions/embedding/session.py +4 -8
- ommlds/cli/sessions/inject.py +15 -15
- ommlds/cli/state/storage.py +7 -1
- ommlds/minichain/__init__.py +161 -38
- ommlds/minichain/_dataclasses.py +20452 -0
- ommlds/minichain/_typedvalues.py +11 -4
- 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 +1 -1
- ommlds/minichain/backends/impls/cerebras/__init__.py +0 -0
- ommlds/minichain/backends/impls/cerebras/chat.py +80 -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 +125 -0
- ommlds/minichain/backends/impls/duckduckgo/search.py +5 -1
- ommlds/minichain/backends/impls/google/names.py +6 -0
- ommlds/minichain/backends/impls/google/stream.py +1 -1
- ommlds/minichain/backends/impls/google/tools.py +2 -2
- ommlds/minichain/backends/impls/groq/chat.py +2 -0
- ommlds/minichain/backends/impls/groq/protocol.py +2 -2
- ommlds/minichain/backends/impls/groq/stream.py +3 -1
- ommlds/minichain/backends/impls/huggingface/repos.py +1 -5
- ommlds/minichain/backends/impls/llamacpp/chat.py +6 -3
- ommlds/minichain/backends/impls/llamacpp/completion.py +7 -3
- ommlds/minichain/backends/impls/llamacpp/stream.py +6 -3
- ommlds/minichain/backends/impls/mlx/chat.py +6 -3
- ommlds/minichain/backends/impls/ollama/chat.py +51 -57
- ommlds/minichain/backends/impls/ollama/protocol.py +144 -0
- ommlds/minichain/backends/impls/openai/format.py +4 -3
- ommlds/minichain/backends/impls/openai/names.py +3 -1
- ommlds/minichain/backends/impls/openai/stream.py +33 -1
- ommlds/minichain/backends/impls/sentencepiece/tokens.py +9 -6
- ommlds/minichain/backends/impls/tinygrad/chat.py +7 -4
- 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 +10 -8
- ommlds/minichain/backends/strings/resolving.py +1 -1
- ommlds/minichain/chat/content.py +42 -0
- ommlds/minichain/chat/messages.py +43 -39
- ommlds/minichain/chat/stream/joining.py +36 -12
- ommlds/minichain/chat/stream/types.py +1 -1
- ommlds/minichain/chat/templating.py +3 -3
- ommlds/minichain/content/__init__.py +19 -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/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 +51 -0
- ommlds/minichain/content/transform/metadata.py +16 -0
- ommlds/minichain/content/{prepare.py → transform/prepare.py} +10 -15
- ommlds/minichain/content/transform/recursive.py +97 -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/visitors.py +231 -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/metadata.py +56 -2
- ommlds/minichain/resources.py +22 -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/stream/services.py +24 -1
- 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 +1 -1
- 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 +6 -6
- ommlds/minichain/tools/types.py +12 -15
- 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/rustbpe/README.md +9 -0
- ommlds/nanochat/tokenizers.py +40 -6
- ommlds/specs/mcp/clients.py +146 -0
- ommlds/specs/mcp/protocol.py +123 -18
- ommlds/tools/git.py +82 -65
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/METADATA +13 -11
- ommlds-0.0.0.dev503.dist-info/RECORD +520 -0
- ommlds/cli/sessions/chat/chat/state/inject.py +0 -36
- ommlds/cli/sessions/chat/chat/user/inject.py +0 -62
- ommlds/cli/sessions/chat/chat/user/interactive.py +0 -31
- 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/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.dev480.dist-info/RECORD +0 -427
- /ommlds/cli/sessions/chat/{chat → drivers}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat → drivers}/ai/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat → drivers}/ai/injection.py +0 -0
- /ommlds/cli/sessions/chat/{chat/state → drivers/events}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{chat/user → 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/{phases → drivers/state}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/fs/configs.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/todo/configs.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/__init__.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/configs.py +0 -0
- /ommlds/cli/sessions/chat/{tools → drivers/tools}/weather/inject.py +0 -0
- /ommlds/{minichain/content/transforms → cli/sessions/chat/drivers/user}/__init__.py +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev480.dist-info → ommlds-0.0.0.dev503.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import lang
|
|
4
|
+
|
|
5
|
+
from ..services.requests import Request
|
|
6
|
+
from ..services.services import Service
|
|
7
|
+
from ..stream.services import StreamOptions
|
|
8
|
+
from ..stream.services import StreamResponse
|
|
9
|
+
from ..types import Output
|
|
10
|
+
from .services import WrappedOptionT
|
|
11
|
+
from .services import WrappedOutputT
|
|
12
|
+
from .services import WrappedRequestV
|
|
13
|
+
from .services import WrappedResponseV
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
WrappedStreamOutputT = ta.TypeVar('WrappedStreamOutputT', bound=Output)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
WrappedStreamOptions: ta.TypeAlias = WrappedOptionT | StreamOptions
|
|
20
|
+
|
|
21
|
+
WrappedStreamRequest: ta.TypeAlias = Request[
|
|
22
|
+
WrappedRequestV,
|
|
23
|
+
WrappedStreamOptions,
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
WrappedStreamResponse: ta.TypeAlias = StreamResponse[
|
|
27
|
+
WrappedResponseV,
|
|
28
|
+
WrappedOutputT,
|
|
29
|
+
WrappedStreamOutputT,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
WrappedStreamService: ta.TypeAlias = Service[
|
|
33
|
+
WrappedStreamRequest,
|
|
34
|
+
WrappedStreamResponse,
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class WrapperStreamService(
|
|
42
|
+
lang.Abstract,
|
|
43
|
+
ta.Generic[
|
|
44
|
+
WrappedRequestV,
|
|
45
|
+
WrappedOptionT,
|
|
46
|
+
WrappedResponseV,
|
|
47
|
+
WrappedOutputT,
|
|
48
|
+
WrappedStreamOutputT,
|
|
49
|
+
],
|
|
50
|
+
):
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
service: WrappedStreamService,
|
|
54
|
+
) -> None:
|
|
55
|
+
super().__init__()
|
|
56
|
+
|
|
57
|
+
self._service = service
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# https://github.com/karpathy/nanochat/tree/9467d83cf23dcc9a9b4ca6e35103142f48a55b27
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# rustbpe
|
|
6
|
+
|
|
7
|
+
> The missing tiktoken training code
|
|
8
|
+
|
|
9
|
+
A very lightweight Rust library for training a GPT tokenizer. The issue is that the inference library [tiktoken](https://github.com/openai/tiktoken) is great, but only does inference. Separately, the huggingface [tokenizers](https://github.com/huggingface/tokenizers) library does training, but it is rather bloated and really hard to navigate because it has to support all the different historical baggage of how people dealt with tokenizers over the years. More recently, I also wrote the [minbpe](https://github.com/karpathy/minbpe) library which does both training and inference, but only in inefficient Python. Basically what I really want is a non-fancy, super simple, but still relatively efficient training code for GPT tokenizer (more efficient than minbpe, much cleaner/simpler than tokenizers), and then export the trained vocab for inference with tiktoken. Does that make sense? So here we are. There are more opportunities for optimization here, I just stopped a bit early because unlike minbpe before it, rustbpe is now simple and fast enough, and not a significant bottleneck for nanochat.
|
ommlds/nanochat/tokenizers.py
CHANGED
|
@@ -18,7 +18,10 @@ from omlish import lang
|
|
|
18
18
|
|
|
19
19
|
with lang.auto_proxy_import(globals()):
|
|
20
20
|
import tiktoken
|
|
21
|
-
import tokenizers
|
|
21
|
+
import tokenizers.decoders
|
|
22
|
+
import tokenizers.models
|
|
23
|
+
import tokenizers.pre_tokenizers
|
|
24
|
+
import tokenizers.trainers
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
rustbpe: ta.Any = lang.proxy_import('.rustbpe', __package__)
|
|
@@ -27,7 +30,7 @@ rustbpe: ta.Any = lang.proxy_import('.rustbpe', __package__)
|
|
|
27
30
|
##
|
|
28
31
|
|
|
29
32
|
|
|
30
|
-
SPECIAL_TOKENS = [
|
|
33
|
+
SPECIAL_TOKENS: ta.Sequence[str] = [
|
|
31
34
|
# every document begins with the Beginning of Sequence (BOS) token that delimits documents
|
|
32
35
|
'<|bos|>',
|
|
33
36
|
# tokens below are only used during finetuning to render Conversations into token ids
|
|
@@ -45,10 +48,18 @@ SPECIAL_TOKENS = [
|
|
|
45
48
|
# NOTE: this split pattern deviates from GPT-4 in that we use \p{N}{1,2} instead of \p{N}{1,3}
|
|
46
49
|
# I did this because I didn't want to "waste" too many tokens on numbers for smaller vocab sizes.
|
|
47
50
|
# I haven't validated that this is actually a good idea, TODO.
|
|
48
|
-
SPLIT_PATTERN =
|
|
51
|
+
SPLIT_PATTERN = (
|
|
52
|
+
r"'(?i:[sdmt]|ll|ve|re)|"
|
|
53
|
+
r"[^\r\n\p{L}\p{N}]?+\p{L}+|"
|
|
54
|
+
r"\p{N}{1,2}|"
|
|
55
|
+
r" ?[^\s\p{L}\p{N}]++[\r\n]*|"
|
|
56
|
+
r"\s*[\r\n]|"
|
|
57
|
+
r"\s+(?!\S)|"
|
|
58
|
+
r"\s+"
|
|
59
|
+
)
|
|
49
60
|
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
##
|
|
52
63
|
# Generic GPT-4-style tokenizer based on HuggingFace Tokenizer
|
|
53
64
|
|
|
54
65
|
|
|
@@ -87,22 +98,28 @@ class HuggingFaceTokenizer:
|
|
|
87
98
|
unk_token=None,
|
|
88
99
|
fuse_unk=False,
|
|
89
100
|
))
|
|
101
|
+
|
|
90
102
|
# Normalizer: None
|
|
91
103
|
tokenizer.normalizer = None
|
|
104
|
+
|
|
92
105
|
# Pre-tokenizer: GPT-4 style
|
|
93
106
|
# the regex pattern used by GPT-4 to split text into groups before BPE
|
|
94
107
|
# NOTE: The pattern was changed from \p{N}{1,3} to \p{N}{1,2} because I suspect it is harmful to
|
|
95
108
|
# very small models and smaller vocab sizes, because it is a little bit wasteful in the token space.
|
|
96
109
|
# (but I haven't validated this! TODO)
|
|
97
110
|
gpt4_split_regex = tokenizers.Regex(split_pattern) # huggingface demands that you wrap it in Regex!!
|
|
111
|
+
|
|
98
112
|
tokenizer.pre_tokenizer = tokenizers.pre_tokenizers.Sequence([
|
|
99
113
|
tokenizers.pre_tokenizers.Split(pattern=gpt4_split_regex, behavior='isolated', invert=False),
|
|
100
114
|
tokenizers.pre_tokenizers.ByteLevel(add_prefix_space=False, use_regex=False),
|
|
101
115
|
])
|
|
116
|
+
|
|
102
117
|
# Decoder: ByteLevel (it pairs together with the ByteLevel pre-tokenizer)
|
|
103
118
|
tokenizer.decoder = tokenizers.decoders.ByteLevel()
|
|
119
|
+
|
|
104
120
|
# Post-processor: None
|
|
105
121
|
tokenizer.post_processor = None
|
|
122
|
+
|
|
106
123
|
# Trainer: BPE
|
|
107
124
|
trainer = tokenizers.trainers.BpeTrainer(
|
|
108
125
|
vocab_size=vocab_size,
|
|
@@ -111,8 +128,10 @@ class HuggingFaceTokenizer:
|
|
|
111
128
|
initial_alphabet=tokenizers.pre_tokenizers.ByteLevel.alphabet(),
|
|
112
129
|
special_tokens=special_tokens,
|
|
113
130
|
)
|
|
131
|
+
|
|
114
132
|
# Kick off the training
|
|
115
133
|
tokenizer.train_from_iterator(text_iterator, trainer)
|
|
134
|
+
|
|
116
135
|
return cls(tokenizer)
|
|
117
136
|
|
|
118
137
|
def encode_ordinary(self, text):
|
|
@@ -174,7 +193,7 @@ class HuggingFaceTokenizer:
|
|
|
174
193
|
print(f'Saved tokenizer to {tokenizer_path}')
|
|
175
194
|
|
|
176
195
|
|
|
177
|
-
|
|
196
|
+
##
|
|
178
197
|
# Tokenizer based on rustbpe + tiktoken combo
|
|
179
198
|
|
|
180
199
|
|
|
@@ -255,6 +274,7 @@ class RustBPETokenizer:
|
|
|
255
274
|
ids.insert(0, prepend_id) # TODO: slightly inefficient here? :( hmm
|
|
256
275
|
if append is not None:
|
|
257
276
|
ids.append(append_id)
|
|
277
|
+
|
|
258
278
|
elif isinstance(text, list):
|
|
259
279
|
ids = self.enc.encode_ordinary_batch(text, num_threads=num_threads)
|
|
260
280
|
if prepend is not None:
|
|
@@ -263,6 +283,7 @@ class RustBPETokenizer:
|
|
|
263
283
|
if append is not None:
|
|
264
284
|
for ids_row in ids:
|
|
265
285
|
ids_row.append(append_id)
|
|
286
|
+
|
|
266
287
|
else:
|
|
267
288
|
raise ValueError(f'Invalid input type: {type(text)}') # noqa
|
|
268
289
|
|
|
@@ -285,6 +306,7 @@ class RustBPETokenizer:
|
|
|
285
306
|
def render_conversation(self, conversation, max_tokens=2048):
|
|
286
307
|
"""
|
|
287
308
|
Tokenize a single Chat conversation (which we call a "doc" or "document" here).
|
|
309
|
+
|
|
288
310
|
Returns:
|
|
289
311
|
- ids: list[int] is a list of token ids of this rendered conversation
|
|
290
312
|
- mask: list[int] of same length, mask = 1 for tokens that the Assistant is expected to train on.
|
|
@@ -324,7 +346,10 @@ class RustBPETokenizer:
|
|
|
324
346
|
for i, message in enumerate(messages):
|
|
325
347
|
# some sanity checking here around assumptions, to prevent footguns
|
|
326
348
|
must_be_from = 'user' if i % 2 == 0 else 'assistant'
|
|
327
|
-
check.state(
|
|
349
|
+
check.state(
|
|
350
|
+
message['role'] == must_be_from,
|
|
351
|
+
f"Message {i} is from {message['role']} but should be from {must_be_from}",
|
|
352
|
+
)
|
|
328
353
|
|
|
329
354
|
# content can be either a simple string or a list of parts (e.g. containing tool calls)
|
|
330
355
|
content = message['content']
|
|
@@ -335,33 +360,42 @@ class RustBPETokenizer:
|
|
|
335
360
|
add_tokens(user_start, 0)
|
|
336
361
|
add_tokens(value_ids, 0)
|
|
337
362
|
add_tokens(user_end, 0)
|
|
363
|
+
|
|
338
364
|
elif message['role'] == 'assistant':
|
|
339
365
|
add_tokens(assistant_start, 0)
|
|
366
|
+
|
|
340
367
|
if isinstance(content, str):
|
|
341
368
|
# simple string => simply add the tokens
|
|
342
369
|
value_ids = self.encode(content)
|
|
343
370
|
add_tokens(value_ids, 1)
|
|
371
|
+
|
|
344
372
|
elif isinstance(content, list):
|
|
345
373
|
for part in content:
|
|
346
374
|
value_ids = self.encode(part['text'])
|
|
375
|
+
|
|
347
376
|
if part['type'] == 'text':
|
|
348
377
|
# string part => simply add the tokens
|
|
349
378
|
add_tokens(value_ids, 1)
|
|
379
|
+
|
|
350
380
|
elif part['type'] == 'python':
|
|
351
381
|
# python tool call => add the tokens inside <|python_start|> and <|python_end|>
|
|
352
382
|
add_tokens(python_start, 1)
|
|
353
383
|
add_tokens(value_ids, 1)
|
|
354
384
|
add_tokens(python_end, 1)
|
|
385
|
+
|
|
355
386
|
elif part['type'] == 'python_output':
|
|
356
387
|
# python output => add the tokens inside <|output_start|> and <|output_end|>
|
|
357
388
|
# none of these tokens are supervised because the tokens come from Python at test time
|
|
358
389
|
add_tokens(output_start, 0)
|
|
359
390
|
add_tokens(value_ids, 0)
|
|
360
391
|
add_tokens(output_end, 0)
|
|
392
|
+
|
|
361
393
|
else:
|
|
362
394
|
raise ValueError(f"Unknown part type: {part['type']}")
|
|
395
|
+
|
|
363
396
|
else:
|
|
364
397
|
raise ValueError(f'Unknown content type: {type(content)}')
|
|
398
|
+
|
|
365
399
|
add_tokens(assistant_end, 1)
|
|
366
400
|
|
|
367
401
|
# truncate to max_tokens tokens MAX (helps prevent OOMs)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import subprocess
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
import anyio.abc
|
|
6
|
+
|
|
7
|
+
from omlish import check
|
|
8
|
+
from omlish import dataclasses as dc
|
|
9
|
+
from omlish import marshal as msh
|
|
10
|
+
from omlish.asyncs import anyio as aiu
|
|
11
|
+
from omlish.specs import jsonrpc as jr
|
|
12
|
+
|
|
13
|
+
from . import protocol as pt
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class McpServerConnection:
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
tg: anyio.abc.TaskGroup,
|
|
23
|
+
stream: anyio.abc.ByteStream,
|
|
24
|
+
*,
|
|
25
|
+
default_timeout: float | None = 30.,
|
|
26
|
+
) -> None:
|
|
27
|
+
super().__init__()
|
|
28
|
+
|
|
29
|
+
self._conn = jr.Connection(
|
|
30
|
+
tg,
|
|
31
|
+
stream,
|
|
32
|
+
request_handler=self._handle_client_request,
|
|
33
|
+
notification_handler=self._handle_client_notification,
|
|
34
|
+
default_timeout=default_timeout,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def from_process(
|
|
41
|
+
cls,
|
|
42
|
+
tg: anyio.abc.TaskGroup,
|
|
43
|
+
proc: anyio.abc.Process,
|
|
44
|
+
**kwargs: ta.Any,
|
|
45
|
+
) -> 'McpServerConnection':
|
|
46
|
+
return cls(
|
|
47
|
+
tg,
|
|
48
|
+
aiu.StapledByteStream(
|
|
49
|
+
check.not_none(proc.stdin),
|
|
50
|
+
check.not_none(proc.stdout),
|
|
51
|
+
),
|
|
52
|
+
**kwargs,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def open_process(
|
|
57
|
+
cls,
|
|
58
|
+
tg: anyio.abc.TaskGroup,
|
|
59
|
+
cmd: ta.Sequence[str],
|
|
60
|
+
open_kwargs: ta.Mapping[str, ta.Any] | None = None,
|
|
61
|
+
**kwargs: ta.Any,
|
|
62
|
+
) -> ta.AsyncContextManager[tuple[anyio.abc.Process, 'McpServerConnection']]:
|
|
63
|
+
@contextlib.asynccontextmanager
|
|
64
|
+
async def inner():
|
|
65
|
+
async with await anyio.open_process(
|
|
66
|
+
cmd,
|
|
67
|
+
stdin=subprocess.PIPE,
|
|
68
|
+
stdout=subprocess.PIPE,
|
|
69
|
+
**open_kwargs or {},
|
|
70
|
+
) as proc:
|
|
71
|
+
async with cls.from_process(
|
|
72
|
+
tg,
|
|
73
|
+
proc,
|
|
74
|
+
**kwargs,
|
|
75
|
+
) as client:
|
|
76
|
+
yield (proc, client)
|
|
77
|
+
|
|
78
|
+
return inner()
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
|
|
82
|
+
async def __aenter__(self) -> 'McpServerConnection':
|
|
83
|
+
await self._conn.__aenter__()
|
|
84
|
+
return self
|
|
85
|
+
|
|
86
|
+
async def __aexit__(self, et, e, tb) -> None:
|
|
87
|
+
await self._conn.__aexit__(et, e, tb)
|
|
88
|
+
|
|
89
|
+
#
|
|
90
|
+
|
|
91
|
+
async def _handle_client_request(self, _client: jr.Connection, req: jr.Request) -> None:
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
async def _handle_client_notification(self, _client: jr.Connection, no: jr.Request) -> None:
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
|
|
99
|
+
async def request(self, req: pt.ClientRequest[pt.ClientResultT]) -> pt.ClientResultT:
|
|
100
|
+
res_cls = pt.MESSAGE_TYPES_BY_JSON_RPC_METHOD_NAME[pt.ClientResult][req.json_rpc_method_name] # type: ignore[type-abstract] # noqa
|
|
101
|
+
req_mv = msh.marshal(req)
|
|
102
|
+
res_mv = await self._conn.request(req.json_rpc_method_name, req_mv) # type: ignore[arg-type]
|
|
103
|
+
res = msh.unmarshal(res_mv, res_cls)
|
|
104
|
+
return ta.cast(pt.ClientResultT, res)
|
|
105
|
+
|
|
106
|
+
async def notify(self, no: pt.Notification) -> None:
|
|
107
|
+
no_mv = msh.marshal(no)
|
|
108
|
+
await self._conn.notify(no.json_rpc_method_name, no_mv) # type: ignore[arg-type]
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
|
|
112
|
+
async def yield_cursor_request(
|
|
113
|
+
self,
|
|
114
|
+
req: pt.CursorClientRequest[pt.CursorClientResultT],
|
|
115
|
+
) -> ta.AsyncGenerator[pt.CursorClientResultT]:
|
|
116
|
+
check.none(req.cursor)
|
|
117
|
+
|
|
118
|
+
cursor: str | None = None
|
|
119
|
+
while True:
|
|
120
|
+
res = await self.request(dc.replace(req, cursor=cursor)) # noqa
|
|
121
|
+
yield res
|
|
122
|
+
|
|
123
|
+
if (cursor := res.next_cursor) is None:
|
|
124
|
+
break
|
|
125
|
+
|
|
126
|
+
async def list_cursor_request(
|
|
127
|
+
self,
|
|
128
|
+
req: pt.CursorClientRequest[pt.CursorClientResultT],
|
|
129
|
+
) -> list[pt.CursorClientResultT]:
|
|
130
|
+
return [res async for res in self.yield_cursor_request(req)]
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
|
|
134
|
+
async def list_tools(self) -> list[pt.Tool]:
|
|
135
|
+
return [
|
|
136
|
+
tool
|
|
137
|
+
async for res in self.yield_cursor_request(pt.ListToolsRequest())
|
|
138
|
+
for tool in res.tools
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
async def list_prompts(self) -> list[pt.Prompt]:
|
|
142
|
+
return [
|
|
143
|
+
prompt
|
|
144
|
+
async for res in self.yield_cursor_request(pt.ListPromptsRequest())
|
|
145
|
+
for prompt in res.prompts
|
|
146
|
+
]
|
ommlds/specs/mcp/protocol.py
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"""
|
|
2
2
|
https://modelcontextprotocol.io/specification/2025-06-18
|
|
3
3
|
https://modelcontextprotocol.io/specification/2025-06-18/schema
|
|
4
|
+
|
|
5
|
+
TODO:
|
|
6
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/cancellation
|
|
7
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/progress
|
|
8
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/client/sampling
|
|
9
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation
|
|
10
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/server/prompts
|
|
11
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/server/resources
|
|
12
|
+
- https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging
|
|
4
13
|
"""
|
|
5
14
|
import abc
|
|
6
15
|
import typing as ta
|
|
@@ -11,6 +20,16 @@ from omlish import lang
|
|
|
11
20
|
from omlish import marshal as msh
|
|
12
21
|
|
|
13
22
|
|
|
23
|
+
ClientRequestT = ta.TypeVar('ClientRequestT', bound='ClientRequest')
|
|
24
|
+
ClientResultT = ta.TypeVar('ClientResultT', bound='ClientResult')
|
|
25
|
+
|
|
26
|
+
ServerRequestT = ta.TypeVar('ServerRequestT', bound='ServerRequest')
|
|
27
|
+
ServerResultT = ta.TypeVar('ServerResultT', bound='ServerResult')
|
|
28
|
+
|
|
29
|
+
CursorClientRequestT = ta.TypeVar('CursorClientRequestT', bound='CursorClientRequest')
|
|
30
|
+
CursorClientResultT = ta.TypeVar('CursorClientResultT', bound='CursorClientResult')
|
|
31
|
+
|
|
32
|
+
|
|
14
33
|
msh.register_global_module_import('._marshal', __package__)
|
|
15
34
|
|
|
16
35
|
|
|
@@ -41,27 +60,36 @@ class Message(lang.Sealed, lang.Abstract):
|
|
|
41
60
|
raise NotImplementedError
|
|
42
61
|
|
|
43
62
|
|
|
44
|
-
|
|
63
|
+
#
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ClientRequest(Message, lang.Abstract, ta.Generic[ClientResultT]):
|
|
45
67
|
pass
|
|
46
68
|
|
|
47
69
|
|
|
48
|
-
class ClientResult(Message, lang.Abstract):
|
|
70
|
+
class ClientResult(Message, lang.Abstract, ta.Generic[ClientRequestT]):
|
|
49
71
|
pass
|
|
50
72
|
|
|
51
73
|
|
|
52
|
-
|
|
74
|
+
#
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ServerRequest(Message, lang.Abstract, ta.Generic[ServerResultT]):
|
|
53
78
|
pass
|
|
54
79
|
|
|
55
80
|
|
|
56
|
-
class ServerResult(Message, lang.Abstract):
|
|
81
|
+
class ServerResult(Message, lang.Abstract, ta.Generic[ServerRequestT]):
|
|
57
82
|
pass
|
|
58
83
|
|
|
59
84
|
|
|
85
|
+
#
|
|
86
|
+
|
|
87
|
+
|
|
60
88
|
class Notification(Message, lang.Abstract):
|
|
61
89
|
pass
|
|
62
90
|
|
|
63
91
|
|
|
64
|
-
|
|
92
|
+
##
|
|
65
93
|
|
|
66
94
|
|
|
67
95
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
@@ -84,7 +112,7 @@ DEFAULT_PROTOCOL_VERSION = '2025-06-18'
|
|
|
84
112
|
|
|
85
113
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
86
114
|
@_set_class_marshal_options
|
|
87
|
-
class ClientCapabilities:
|
|
115
|
+
class ClientCapabilities(lang.Final):
|
|
88
116
|
elicitation: ta.Any | None = None
|
|
89
117
|
|
|
90
118
|
experimental: ta.Mapping[str, ta.Any] | None = None
|
|
@@ -101,7 +129,7 @@ class ClientCapabilities:
|
|
|
101
129
|
|
|
102
130
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
103
131
|
@_set_class_marshal_options
|
|
104
|
-
class InitializeRequest(ClientRequest):
|
|
132
|
+
class InitializeRequest(ClientRequest['InitializeResult']):
|
|
105
133
|
json_rpc_method_name: ta.ClassVar[str] = 'initialize'
|
|
106
134
|
|
|
107
135
|
client_info: Implementation
|
|
@@ -143,12 +171,13 @@ class ServerCapabilities:
|
|
|
143
171
|
|
|
144
172
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
145
173
|
@_set_class_marshal_options
|
|
146
|
-
class InitializeResult(ClientResult, WithMeta):
|
|
174
|
+
class InitializeResult(ClientResult[InitializeRequest], WithMeta):
|
|
147
175
|
json_rpc_method_name: ta.ClassVar[str] = 'initialize'
|
|
148
176
|
|
|
149
177
|
server_info: Implementation
|
|
150
178
|
protocol_version: str
|
|
151
179
|
capabilities: ServerCapabilities
|
|
180
|
+
instructions: str | None = None
|
|
152
181
|
|
|
153
182
|
|
|
154
183
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
@@ -160,6 +189,19 @@ class InitializedNotification(Notification):
|
|
|
160
189
|
##
|
|
161
190
|
|
|
162
191
|
|
|
192
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
193
|
+
class CursorClientRequest(ClientRequest[CursorClientResultT], lang.Abstract):
|
|
194
|
+
cursor: str | None = None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
198
|
+
class CursorClientResult(ClientResult[CursorClientRequestT], lang.Abstract):
|
|
199
|
+
next_cursor: str | None = None
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
##
|
|
203
|
+
|
|
204
|
+
|
|
163
205
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
164
206
|
@_set_class_marshal_options
|
|
165
207
|
class ToolAnnotations(lang.Final):
|
|
@@ -172,7 +214,7 @@ class ToolAnnotations(lang.Final):
|
|
|
172
214
|
|
|
173
215
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
174
216
|
@_set_class_marshal_options
|
|
175
|
-
class Tool(lang.Final):
|
|
217
|
+
class Tool(WithMeta, lang.Final):
|
|
176
218
|
name: str
|
|
177
219
|
title: str | None = None
|
|
178
220
|
|
|
@@ -186,19 +228,16 @@ class Tool(lang.Final):
|
|
|
186
228
|
|
|
187
229
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
188
230
|
@_set_class_marshal_options
|
|
189
|
-
class ListToolsRequest(
|
|
231
|
+
class ListToolsRequest(CursorClientRequest['ListToolsResult']):
|
|
190
232
|
json_rpc_method_name: ta.ClassVar[str] = 'tools/list'
|
|
191
233
|
|
|
192
|
-
cursor: str | None = None
|
|
193
|
-
|
|
194
234
|
|
|
195
235
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
196
236
|
@_set_class_marshal_options
|
|
197
|
-
class ListToolsResult(
|
|
237
|
+
class ListToolsResult(CursorClientResult[ListToolsRequest], WithMeta):
|
|
198
238
|
json_rpc_method_name: ta.ClassVar[str] = 'tools/list'
|
|
199
239
|
|
|
200
240
|
tools: ta.Sequence[Tool]
|
|
201
|
-
next_cursor: str | None = None
|
|
202
241
|
|
|
203
242
|
|
|
204
243
|
##
|
|
@@ -219,7 +258,7 @@ class TextContentBlock(ContentBlock, lang.Final):
|
|
|
219
258
|
|
|
220
259
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
221
260
|
@_set_class_marshal_options
|
|
222
|
-
class CallToolRequest(ClientRequest):
|
|
261
|
+
class CallToolRequest(ClientRequest['CallToolResult']):
|
|
223
262
|
json_rpc_method_name: ta.ClassVar[str] = 'tools/call'
|
|
224
263
|
|
|
225
264
|
name: str
|
|
@@ -228,7 +267,7 @@ class CallToolRequest(ClientRequest):
|
|
|
228
267
|
|
|
229
268
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
230
269
|
@_set_class_marshal_options
|
|
231
|
-
class CallToolResult(ClientResult, WithMeta):
|
|
270
|
+
class CallToolResult(ClientResult[CallToolRequest], WithMeta):
|
|
232
271
|
json_rpc_method_name: ta.ClassVar[str] = 'tools/call'
|
|
233
272
|
|
|
234
273
|
content: ta.Sequence[ContentBlock]
|
|
@@ -241,16 +280,82 @@ class CallToolResult(ClientResult, WithMeta):
|
|
|
241
280
|
|
|
242
281
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
243
282
|
@_set_class_marshal_options
|
|
244
|
-
class
|
|
283
|
+
class PingClientRequest(ClientRequest['PingClientResult'], WithMeta):
|
|
245
284
|
json_rpc_method_name: ta.ClassVar[str] = 'ping'
|
|
246
285
|
|
|
247
286
|
|
|
248
287
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
249
288
|
@_set_class_marshal_options
|
|
250
|
-
class
|
|
289
|
+
class PingClientResult(ClientResult[PingClientRequest]):
|
|
251
290
|
json_rpc_method_name: ta.ClassVar[str] = 'ping'
|
|
252
291
|
|
|
253
292
|
|
|
293
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
294
|
+
@_set_class_marshal_options
|
|
295
|
+
class PingServerRequest(ServerRequest['PingServerResult'], WithMeta):
|
|
296
|
+
json_rpc_method_name: ta.ClassVar[str] = 'ping'
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
300
|
+
@_set_class_marshal_options
|
|
301
|
+
class PingServerResult(ServerResult[PingServerRequest]):
|
|
302
|
+
json_rpc_method_name: ta.ClassVar[str] = 'ping'
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
##
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
309
|
+
@_set_class_marshal_options
|
|
310
|
+
class PromptArgument(lang.Final):
|
|
311
|
+
name: str
|
|
312
|
+
title: str | None = None
|
|
313
|
+
|
|
314
|
+
description: str | None = None
|
|
315
|
+
|
|
316
|
+
required: bool | None = None
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
320
|
+
@_set_class_marshal_options
|
|
321
|
+
class Prompt(WithMeta, lang.Final):
|
|
322
|
+
name: str
|
|
323
|
+
title: str | None = None
|
|
324
|
+
|
|
325
|
+
description: str | None = None
|
|
326
|
+
|
|
327
|
+
arguments: ta.Sequence[PromptArgument] | None = None
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
331
|
+
@_set_class_marshal_options
|
|
332
|
+
class ListPromptsRequest(CursorClientRequest['ListPromptsResult']):
|
|
333
|
+
json_rpc_method_name: ta.ClassVar[str] = 'prompts/list'
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
337
|
+
@_set_class_marshal_options
|
|
338
|
+
class ListPromptsResult(CursorClientResult[ListPromptsRequest], WithMeta):
|
|
339
|
+
json_rpc_method_name: ta.ClassVar[str] = 'prompts/list'
|
|
340
|
+
|
|
341
|
+
prompts: ta.Sequence[Prompt]
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
##
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
LoggingLevel: ta.TypeAlias = ta.Literal[
|
|
348
|
+
'debug',
|
|
349
|
+
'info',
|
|
350
|
+
'notice',
|
|
351
|
+
'warning',
|
|
352
|
+
'error',
|
|
353
|
+
'critical',
|
|
354
|
+
'alert',
|
|
355
|
+
'emergency',
|
|
356
|
+
]
|
|
357
|
+
|
|
358
|
+
|
|
254
359
|
##
|
|
255
360
|
|
|
256
361
|
|