ommlds 0.0.0.dev440__py3-none-any.whl → 0.0.0.dev480__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 +332 -35
- ommlds/__about__.py +15 -9
- 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/_marshal.py +2 -2
- ommlds/backends/anthropic/protocol/sse/_marshal.py +1 -1
- ommlds/backends/anthropic/protocol/sse/assemble.py +23 -7
- ommlds/backends/anthropic/protocol/sse/events.py +13 -0
- ommlds/backends/anthropic/protocol/types.py +30 -9
- ommlds/backends/google/protocol/__init__.py +3 -0
- ommlds/backends/google/protocol/_marshal.py +16 -0
- ommlds/backends/google/protocol/types.py +626 -0
- ommlds/backends/groq/_marshal.py +23 -0
- ommlds/backends/groq/protocol.py +249 -0
- ommlds/backends/mlx/generation.py +1 -1
- ommlds/backends/mlx/loading.py +58 -1
- ommlds/backends/ollama/__init__.py +0 -0
- ommlds/backends/ollama/protocol.py +170 -0
- ommlds/backends/openai/protocol/__init__.py +9 -28
- ommlds/backends/openai/protocol/_common.py +18 -0
- ommlds/backends/openai/protocol/_marshal.py +27 -0
- ommlds/backends/openai/protocol/chatcompletion/chunk.py +58 -31
- ommlds/backends/openai/protocol/chatcompletion/contentpart.py +49 -44
- ommlds/backends/openai/protocol/chatcompletion/message.py +55 -43
- ommlds/backends/openai/protocol/chatcompletion/request.py +114 -66
- ommlds/backends/openai/protocol/chatcompletion/response.py +71 -45
- ommlds/backends/openai/protocol/chatcompletion/responseformat.py +27 -20
- ommlds/backends/openai/protocol/chatcompletion/tokenlogprob.py +16 -7
- ommlds/backends/openai/protocol/completionusage.py +24 -15
- ommlds/backends/tavily/__init__.py +0 -0
- ommlds/backends/tavily/protocol.py +301 -0
- ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
- ommlds/backends/transformers/__init__.py +0 -0
- ommlds/backends/transformers/filecache.py +109 -0
- ommlds/backends/transformers/streamers.py +73 -0
- ommlds/cli/asyncs.py +30 -0
- ommlds/cli/backends/catalog.py +93 -0
- ommlds/cli/backends/configs.py +9 -0
- ommlds/cli/backends/inject.py +31 -36
- ommlds/cli/backends/injection.py +16 -0
- ommlds/cli/backends/types.py +46 -0
- ommlds/cli/content/__init__.py +0 -0
- ommlds/cli/content/messages.py +34 -0
- ommlds/cli/content/strings.py +42 -0
- ommlds/cli/inject.py +15 -32
- ommlds/cli/inputs/__init__.py +0 -0
- ommlds/cli/inputs/asyncs.py +32 -0
- ommlds/cli/inputs/sync.py +75 -0
- ommlds/cli/main.py +270 -110
- ommlds/cli/rendering/__init__.py +0 -0
- ommlds/cli/rendering/configs.py +9 -0
- ommlds/cli/rendering/inject.py +31 -0
- ommlds/cli/rendering/markdown.py +52 -0
- ommlds/cli/rendering/raw.py +73 -0
- ommlds/cli/rendering/types.py +21 -0
- ommlds/cli/secrets.py +21 -0
- ommlds/cli/sessions/base.py +1 -1
- ommlds/cli/sessions/chat/chat/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/ai/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/ai/configs.py +11 -0
- ommlds/cli/sessions/chat/chat/ai/inject.py +74 -0
- ommlds/cli/sessions/chat/chat/ai/injection.py +14 -0
- ommlds/cli/sessions/chat/chat/ai/rendering.py +70 -0
- ommlds/cli/sessions/chat/chat/ai/services.py +79 -0
- ommlds/cli/sessions/chat/chat/ai/tools.py +44 -0
- ommlds/cli/sessions/chat/chat/ai/types.py +28 -0
- ommlds/cli/sessions/chat/chat/state/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/state/configs.py +11 -0
- ommlds/cli/sessions/chat/chat/state/inject.py +36 -0
- ommlds/cli/sessions/chat/chat/state/inmemory.py +33 -0
- ommlds/cli/sessions/chat/chat/state/storage.py +52 -0
- ommlds/cli/sessions/chat/chat/state/types.py +38 -0
- ommlds/cli/sessions/chat/chat/user/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/user/configs.py +17 -0
- ommlds/cli/sessions/chat/chat/user/inject.py +62 -0
- ommlds/cli/sessions/chat/chat/user/interactive.py +31 -0
- ommlds/cli/sessions/chat/chat/user/oneshot.py +25 -0
- ommlds/cli/sessions/chat/chat/user/types.py +15 -0
- ommlds/cli/sessions/chat/configs.py +27 -0
- ommlds/cli/sessions/chat/driver.py +43 -0
- ommlds/cli/sessions/chat/inject.py +33 -65
- ommlds/cli/sessions/chat/phases/__init__.py +0 -0
- ommlds/cli/sessions/chat/phases/inject.py +27 -0
- ommlds/cli/sessions/chat/phases/injection.py +14 -0
- ommlds/cli/sessions/chat/phases/manager.py +29 -0
- ommlds/cli/sessions/chat/phases/types.py +29 -0
- ommlds/cli/sessions/chat/session.py +27 -0
- ommlds/cli/sessions/chat/tools/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/configs.py +22 -0
- ommlds/cli/sessions/chat/tools/confirmation.py +46 -0
- ommlds/cli/sessions/chat/tools/execution.py +66 -0
- ommlds/cli/sessions/chat/tools/fs/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/fs/configs.py +12 -0
- ommlds/cli/sessions/chat/tools/fs/inject.py +35 -0
- ommlds/cli/sessions/chat/tools/inject.py +88 -0
- ommlds/cli/sessions/chat/tools/injection.py +44 -0
- ommlds/cli/sessions/chat/tools/rendering.py +58 -0
- ommlds/cli/sessions/chat/tools/todo/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/todo/configs.py +12 -0
- ommlds/cli/sessions/chat/tools/todo/inject.py +31 -0
- ommlds/cli/sessions/chat/tools/weather/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/weather/configs.py +12 -0
- ommlds/cli/sessions/chat/tools/weather/inject.py +22 -0
- ommlds/cli/{tools/weather.py → sessions/chat/tools/weather/tools.py} +1 -1
- ommlds/cli/sessions/completion/configs.py +21 -0
- ommlds/cli/sessions/completion/inject.py +42 -0
- ommlds/cli/sessions/completion/session.py +35 -0
- ommlds/cli/sessions/embedding/configs.py +21 -0
- ommlds/cli/sessions/embedding/inject.py +42 -0
- ommlds/cli/sessions/embedding/session.py +33 -0
- ommlds/cli/sessions/inject.py +28 -11
- ommlds/cli/state/__init__.py +0 -0
- ommlds/cli/state/inject.py +28 -0
- ommlds/cli/{state.py → state/storage.py} +41 -24
- ommlds/minichain/__init__.py +84 -24
- ommlds/minichain/_marshal.py +49 -9
- ommlds/minichain/_typedvalues.py +2 -4
- ommlds/minichain/backends/catalogs/base.py +20 -1
- ommlds/minichain/backends/catalogs/simple.py +2 -2
- ommlds/minichain/backends/catalogs/strings.py +10 -8
- ommlds/minichain/backends/impls/anthropic/chat.py +65 -27
- ommlds/minichain/backends/impls/anthropic/names.py +10 -8
- ommlds/minichain/backends/impls/anthropic/protocol.py +109 -0
- ommlds/minichain/backends/impls/anthropic/stream.py +111 -43
- ommlds/minichain/backends/impls/duckduckgo/search.py +1 -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 +114 -22
- ommlds/minichain/backends/impls/google/search.py +7 -2
- ommlds/minichain/backends/impls/google/stream.py +219 -0
- ommlds/minichain/backends/impls/google/tools.py +149 -0
- ommlds/minichain/backends/impls/groq/__init__.py +0 -0
- ommlds/minichain/backends/impls/groq/chat.py +75 -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 +125 -0
- ommlds/minichain/backends/impls/llamacpp/chat.py +33 -18
- ommlds/minichain/backends/impls/llamacpp/completion.py +1 -1
- ommlds/minichain/backends/impls/llamacpp/format.py +4 -2
- ommlds/minichain/backends/impls/llamacpp/stream.py +37 -20
- ommlds/minichain/backends/impls/mistral.py +20 -5
- ommlds/minichain/backends/impls/mlx/chat.py +96 -22
- ommlds/minichain/backends/impls/ollama/__init__.py +0 -0
- ommlds/minichain/backends/impls/ollama/chat.py +199 -0
- ommlds/minichain/backends/impls/openai/chat.py +18 -8
- ommlds/minichain/backends/impls/openai/completion.py +10 -3
- ommlds/minichain/backends/impls/openai/embedding.py +10 -3
- ommlds/minichain/backends/impls/openai/format.py +131 -106
- ommlds/minichain/backends/impls/openai/names.py +31 -5
- ommlds/minichain/backends/impls/openai/stream.py +43 -25
- ommlds/minichain/backends/impls/tavily.py +66 -0
- ommlds/minichain/backends/impls/tinygrad/chat.py +23 -16
- ommlds/minichain/backends/impls/transformers/sentence.py +1 -1
- ommlds/minichain/backends/impls/transformers/tokens.py +1 -1
- ommlds/minichain/backends/impls/transformers/transformers.py +155 -34
- ommlds/minichain/backends/strings/parsing.py +1 -1
- ommlds/minichain/backends/strings/resolving.py +4 -1
- ommlds/minichain/chat/_marshal.py +16 -9
- ommlds/minichain/chat/choices/adapters.py +4 -4
- ommlds/minichain/chat/choices/services.py +1 -1
- ommlds/minichain/chat/choices/stream/__init__.py +0 -0
- ommlds/minichain/chat/choices/stream/adapters.py +35 -0
- 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/choices/types.py +2 -2
- ommlds/minichain/chat/history.py +3 -3
- ommlds/minichain/chat/messages.py +55 -19
- ommlds/minichain/chat/services.py +3 -3
- ommlds/minichain/chat/stream/_marshal.py +16 -0
- ommlds/minichain/chat/stream/joining.py +85 -0
- ommlds/minichain/chat/stream/services.py +15 -21
- ommlds/minichain/chat/stream/types.py +32 -19
- ommlds/minichain/chat/tools/execution.py +8 -7
- ommlds/minichain/chat/tools/ids.py +9 -15
- ommlds/minichain/chat/tools/parsing.py +17 -26
- ommlds/minichain/chat/transforms/base.py +29 -38
- ommlds/minichain/chat/transforms/metadata.py +30 -4
- ommlds/minichain/chat/transforms/services.py +9 -11
- ommlds/minichain/content/_marshal.py +44 -20
- ommlds/minichain/content/json.py +13 -0
- ommlds/minichain/content/materialize.py +14 -21
- ommlds/minichain/content/prepare.py +4 -0
- ommlds/minichain/content/transforms/interleave.py +1 -1
- ommlds/minichain/content/transforms/squeeze.py +1 -1
- ommlds/minichain/content/transforms/stringify.py +1 -1
- ommlds/minichain/json.py +20 -0
- ommlds/minichain/lib/code/__init__.py +0 -0
- ommlds/minichain/lib/code/prompts.py +6 -0
- ommlds/minichain/lib/fs/binfiles.py +108 -0
- ommlds/minichain/lib/fs/context.py +126 -0
- ommlds/minichain/lib/fs/errors.py +101 -0
- ommlds/minichain/lib/fs/suggestions.py +36 -0
- ommlds/minichain/lib/fs/tools/__init__.py +0 -0
- ommlds/minichain/lib/fs/tools/edit.py +104 -0
- ommlds/minichain/lib/fs/tools/ls.py +38 -0
- ommlds/minichain/lib/fs/tools/read.py +115 -0
- ommlds/minichain/lib/fs/tools/recursivels/__init__.py +0 -0
- ommlds/minichain/lib/fs/tools/recursivels/execution.py +40 -0
- ommlds/minichain/lib/todo/__init__.py +0 -0
- ommlds/minichain/lib/todo/context.py +54 -0
- ommlds/minichain/lib/todo/tools/__init__.py +0 -0
- ommlds/minichain/lib/todo/tools/read.py +44 -0
- ommlds/minichain/lib/todo/tools/write.py +335 -0
- ommlds/minichain/lib/todo/types.py +60 -0
- ommlds/minichain/llms/_marshal.py +25 -17
- ommlds/minichain/llms/types.py +4 -0
- ommlds/minichain/registries/globals.py +18 -4
- ommlds/minichain/resources.py +66 -43
- ommlds/minichain/search.py +1 -1
- ommlds/minichain/services/_marshal.py +46 -39
- ommlds/minichain/services/facades.py +3 -3
- ommlds/minichain/services/services.py +1 -1
- ommlds/minichain/standard.py +8 -0
- ommlds/minichain/stream/services.py +152 -38
- ommlds/minichain/stream/wrap.py +22 -24
- ommlds/minichain/tools/_marshal.py +1 -1
- ommlds/minichain/tools/execution/catalog.py +2 -1
- ommlds/minichain/tools/execution/context.py +34 -14
- ommlds/minichain/tools/execution/errors.py +15 -0
- ommlds/minichain/tools/execution/executors.py +8 -3
- ommlds/minichain/tools/execution/reflect.py +40 -5
- ommlds/minichain/tools/fns.py +46 -9
- ommlds/minichain/tools/jsonschema.py +14 -5
- ommlds/minichain/tools/reflect.py +54 -18
- ommlds/minichain/tools/types.py +33 -1
- ommlds/minichain/utils.py +27 -0
- ommlds/minichain/vectors/_marshal.py +11 -10
- ommlds/nanochat/LICENSE +21 -0
- ommlds/nanochat/__init__.py +0 -0
- ommlds/nanochat/rustbpe/LICENSE +21 -0
- ommlds/nanochat/tokenizers.py +406 -0
- ommlds/server/server.py +3 -3
- ommlds/specs/__init__.py +0 -0
- ommlds/specs/mcp/__init__.py +0 -0
- ommlds/specs/mcp/_marshal.py +23 -0
- ommlds/specs/mcp/protocol.py +266 -0
- ommlds/tools/git.py +27 -10
- ommlds/tools/ocr.py +8 -9
- ommlds/wiki/analyze.py +2 -2
- ommlds/wiki/text/mfh.py +1 -5
- ommlds/wiki/text/wtp.py +1 -3
- ommlds/wiki/utils/xml.py +5 -5
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/METADATA +24 -21
- ommlds-0.0.0.dev480.dist-info/RECORD +427 -0
- ommlds/cli/backends/standard.py +0 -20
- ommlds/cli/sessions/chat/base.py +0 -42
- ommlds/cli/sessions/chat/interactive.py +0 -73
- ommlds/cli/sessions/chat/printing.py +0 -96
- ommlds/cli/sessions/chat/prompt.py +0 -143
- ommlds/cli/sessions/chat/state.py +0 -109
- ommlds/cli/sessions/chat/tools.py +0 -91
- ommlds/cli/sessions/completion/completion.py +0 -44
- ommlds/cli/sessions/embedding/embedding.py +0 -42
- ommlds/cli/tools/config.py +0 -13
- ommlds/cli/tools/inject.py +0 -64
- ommlds/minichain/chat/stream/adapters.py +0 -69
- ommlds/minichain/lib/fs/ls/execution.py +0 -32
- ommlds-0.0.0.dev440.dist-info/RECORD +0 -303
- /ommlds/{cli/tools → backends/google}/__init__.py +0 -0
- /ommlds/{minichain/lib/fs/ls → backends/groq}/__init__.py +0 -0
- /ommlds/{huggingface.py → backends/huggingface.py} +0 -0
- /ommlds/minichain/lib/fs/{ls → tools/recursivels}/rendering.py +0 -0
- /ommlds/minichain/lib/fs/{ls → tools/recursivels}/running.py +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,7 @@ from .types import ToolDtype
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@lang.static_init
|
|
11
|
-
def
|
|
11
|
+
def _install_standard_marshaling() -> None:
|
|
12
12
|
tool_dtype_poly = msh.polymorphism_from_subclasses(ToolDtype, naming=msh.Naming.SNAKE)
|
|
13
13
|
msh.install_standard_factories(
|
|
14
14
|
msh.PolymorphismMarshalerFactory(tool_dtype_poly),
|
|
@@ -4,6 +4,7 @@ from omlish import check
|
|
|
4
4
|
from omlish import dataclasses as dc
|
|
5
5
|
from omlish import lang
|
|
6
6
|
|
|
7
|
+
from ...content.types import Content
|
|
7
8
|
from ..fns import ToolFn
|
|
8
9
|
from ..types import ToolSpec
|
|
9
10
|
from .context import ToolContext
|
|
@@ -68,7 +69,7 @@ class ToolCatalog(ToolExecutor):
|
|
|
68
69
|
ctx: ToolContext,
|
|
69
70
|
name: str,
|
|
70
71
|
args: ta.Mapping[str, ta.Any],
|
|
71
|
-
) ->
|
|
72
|
+
) -> Content:
|
|
72
73
|
e = self._by_name[name]
|
|
73
74
|
|
|
74
75
|
return await e.executor().execute_tool(
|
|
@@ -2,8 +2,8 @@ import contextlib
|
|
|
2
2
|
import contextvars
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
+
from omlish import check
|
|
5
6
|
from omlish import collections as col
|
|
6
|
-
from omlish import dataclasses as dc
|
|
7
7
|
from omlish import lang
|
|
8
8
|
|
|
9
9
|
|
|
@@ -13,30 +13,34 @@ T = ta.TypeVar('T')
|
|
|
13
13
|
##
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
@dc.dataclass(frozen=True)
|
|
17
16
|
class ToolContext(lang.Final):
|
|
18
|
-
|
|
17
|
+
def __init__(self, *items: ta.Any) -> None:
|
|
18
|
+
super().__init__()
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
self._dct: col.TypeMap = col.TypeMap(items)
|
|
21
|
+
if ToolContext in self._dct:
|
|
22
|
+
raise KeyError(ToolContext)
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
def __repr__(self) -> str:
|
|
25
|
+
return f'{self.__class__.__name__}<{", ".join(ic.__name__ for ic in self._dct)}>'
|
|
25
26
|
|
|
26
27
|
def __len__(self) -> int:
|
|
27
|
-
return len(self.
|
|
28
|
+
return len(self._dct)
|
|
28
29
|
|
|
29
30
|
def __iter__(self) -> ta.Iterator[ta.Any]:
|
|
30
|
-
return iter(self.
|
|
31
|
+
return iter(self._dct)
|
|
32
|
+
|
|
33
|
+
def __contains__(self, ty: type[T]) -> bool:
|
|
34
|
+
return ty in self._dct
|
|
31
35
|
|
|
32
36
|
def get(self, ty: type[T]) -> T | None:
|
|
33
|
-
return self.
|
|
37
|
+
return self._dct.get(ty)
|
|
34
38
|
|
|
35
39
|
def __getitem__(self, cls: type[T]) -> T:
|
|
36
|
-
return self.
|
|
40
|
+
return self._dct[cls]
|
|
37
41
|
|
|
38
42
|
def get_any(self, cls: type | tuple[type, ...]) -> ta.Sequence[T]:
|
|
39
|
-
return self.
|
|
43
|
+
return self._dct.get_any(cls)
|
|
40
44
|
|
|
41
45
|
|
|
42
46
|
##
|
|
@@ -45,8 +49,24 @@ class ToolContext(lang.Final):
|
|
|
45
49
|
_TOOL_CONTEXT: contextvars.ContextVar[ToolContext] = contextvars.ContextVar(f'{__name__}._TOOL_CONTEXT')
|
|
46
50
|
|
|
47
51
|
|
|
48
|
-
@
|
|
49
|
-
def bind_tool_context(ctx: ToolContext) -> ta.
|
|
52
|
+
@ta.overload
|
|
53
|
+
def bind_tool_context(ctx: ToolContext) -> ta.ContextManager[ToolContext]:
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@ta.overload
|
|
58
|
+
def bind_tool_context(*items: ta.Any) -> ta.ContextManager[ToolContext]:
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@contextlib.contextmanager # type: ignore[misc]
|
|
63
|
+
def bind_tool_context(*args):
|
|
64
|
+
if args and isinstance(args[0], ToolContext):
|
|
65
|
+
check.arg(len(args) == 1)
|
|
66
|
+
ctx = args[0]
|
|
67
|
+
else:
|
|
68
|
+
ctx = ToolContext(*args)
|
|
69
|
+
|
|
50
70
|
try:
|
|
51
71
|
cur = _TOOL_CONTEXT.get()
|
|
52
72
|
except LookupError:
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
|
|
3
|
+
from omlish import lang
|
|
4
|
+
|
|
5
|
+
from ...content.materialize import CanContent
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ToolExecutionError(Exception, lang.Abstract):
|
|
12
|
+
@property
|
|
13
|
+
@abc.abstractmethod
|
|
14
|
+
def content(self) -> CanContent:
|
|
15
|
+
raise NotImplementedError
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- args is Mapping[str, Content] too
|
|
4
|
+
"""
|
|
1
5
|
import abc
|
|
2
6
|
import typing as ta
|
|
3
7
|
|
|
4
8
|
from omlish import dataclasses as dc
|
|
5
9
|
from omlish import lang
|
|
6
10
|
|
|
11
|
+
from ...content.types import Content
|
|
7
12
|
from ..fns import ToolFn
|
|
8
13
|
from ..fns import execute_tool_fn
|
|
9
14
|
from .context import ToolContext
|
|
@@ -20,7 +25,7 @@ class ToolExecutor(lang.Abstract):
|
|
|
20
25
|
ctx: ToolContext,
|
|
21
26
|
name: str,
|
|
22
27
|
args: ta.Mapping[str, ta.Any],
|
|
23
|
-
) -> ta.Awaitable[
|
|
28
|
+
) -> ta.Awaitable[Content]:
|
|
24
29
|
raise NotImplementedError
|
|
25
30
|
|
|
26
31
|
|
|
@@ -36,7 +41,7 @@ class ToolFnToolExecutor(ToolExecutor):
|
|
|
36
41
|
ctx: ToolContext,
|
|
37
42
|
name: str,
|
|
38
43
|
args: ta.Mapping[str, ta.Any],
|
|
39
|
-
) ->
|
|
44
|
+
) -> Content:
|
|
40
45
|
with bind_tool_context(ctx):
|
|
41
46
|
return await execute_tool_fn(
|
|
42
47
|
self.tool_fn,
|
|
@@ -56,5 +61,5 @@ class NameSwitchedToolExecutor(ToolExecutor):
|
|
|
56
61
|
ctx: ToolContext,
|
|
57
62
|
name: str,
|
|
58
63
|
args: ta.Mapping[str, ta.Any],
|
|
59
|
-
) ->
|
|
64
|
+
) -> Content:
|
|
60
65
|
return await self.tool_executors_by_name[name].execute_tool(ctx, name, args)
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
|
+
- ta.type_hints
|
|
3
4
|
"""
|
|
4
5
|
import inspect
|
|
5
6
|
import typing as ta
|
|
6
7
|
|
|
7
8
|
from omlish import lang
|
|
9
|
+
from omlish import marshal as msh
|
|
10
|
+
from omlish import reflect as rfl
|
|
8
11
|
|
|
9
12
|
from ..fns import ToolFn
|
|
10
13
|
from ..reflect import reflect_tool_spec
|
|
@@ -14,7 +17,13 @@ from .catalog import ToolCatalogEntry
|
|
|
14
17
|
##
|
|
15
18
|
|
|
16
19
|
|
|
17
|
-
def reflect_tool_catalog_entry(
|
|
20
|
+
def reflect_tool_catalog_entry(
|
|
21
|
+
fn: ta.Callable,
|
|
22
|
+
*,
|
|
23
|
+
marshal_input: bool = False,
|
|
24
|
+
marshal_output: bool = False,
|
|
25
|
+
no_marshal_check: bool = False,
|
|
26
|
+
) -> ToolCatalogEntry:
|
|
18
27
|
impl: ToolFn.Impl
|
|
19
28
|
if lang.is_maysync(fn):
|
|
20
29
|
impl = ToolFn.MaysyncImpl(fn)
|
|
@@ -23,15 +32,41 @@ def reflect_tool_catalog_entry(fn: ta.Callable) -> ToolCatalogEntry:
|
|
|
23
32
|
else:
|
|
24
33
|
impl = ToolFn.FnImpl(s=fn, a=lang.as_async(fn, wrap=True))
|
|
25
34
|
|
|
35
|
+
#
|
|
36
|
+
|
|
37
|
+
tf_input: ToolFn.Input
|
|
26
38
|
sig = inspect.signature(fn)
|
|
27
|
-
if
|
|
28
|
-
|
|
39
|
+
if marshal_input:
|
|
40
|
+
in_rtys: dict[str, rfl.Type] = {}
|
|
41
|
+
for p in sig.parameters.values():
|
|
42
|
+
p_rty = rfl.type_(p.annotation)
|
|
43
|
+
if not no_marshal_check:
|
|
44
|
+
msh.global_marshaling().new_unmarshal_factory_context().make_unmarshaler(p_rty)
|
|
45
|
+
in_rtys[p.name] = p_rty
|
|
46
|
+
tf_input = ToolFn.MarshalInput(in_rtys)
|
|
47
|
+
else:
|
|
48
|
+
tf_input = ToolFn.RawKwargsInput()
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
|
|
52
|
+
tf_output: ToolFn.Output
|
|
53
|
+
if marshal_output:
|
|
54
|
+
out_rty = rfl.type_(sig.return_annotation)
|
|
55
|
+
if not no_marshal_check:
|
|
56
|
+
msh.global_marshaling().new_marshal_factory_context().make_marshaler(out_rty)
|
|
57
|
+
tf_output = ToolFn.MarshalOutput(out_rty)
|
|
58
|
+
else:
|
|
59
|
+
if sig.return_annotation is not str:
|
|
60
|
+
raise NotImplementedError(fn)
|
|
61
|
+
tf_output = ToolFn.RawStringOutput()
|
|
62
|
+
|
|
63
|
+
#
|
|
29
64
|
|
|
30
65
|
return ToolCatalogEntry(
|
|
31
66
|
reflect_tool_spec(fn),
|
|
32
67
|
ToolFn(
|
|
33
68
|
impl,
|
|
34
|
-
|
|
35
|
-
|
|
69
|
+
tf_input,
|
|
70
|
+
tf_output,
|
|
36
71
|
),
|
|
37
72
|
)
|
ommlds/minichain/tools/fns.py
CHANGED
|
@@ -7,6 +7,11 @@ import typing as ta
|
|
|
7
7
|
from omlish import check
|
|
8
8
|
from omlish import dataclasses as dc
|
|
9
9
|
from omlish import lang
|
|
10
|
+
from omlish import marshal as msh
|
|
11
|
+
from omlish import reflect as rfl
|
|
12
|
+
|
|
13
|
+
from ..content.json import JsonContent
|
|
14
|
+
from ..content.types import Content
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
D = ta.TypeVar('D')
|
|
@@ -51,7 +56,11 @@ class ToolFn(lang.Final):
|
|
|
51
56
|
check.arg(dc.is_dataclass(self.cls))
|
|
52
57
|
|
|
53
58
|
@dc.dataclass(frozen=True)
|
|
54
|
-
class
|
|
59
|
+
class MarshalInput(Input, lang.Final):
|
|
60
|
+
rtys: ta.Mapping[str, rfl.Type]
|
|
61
|
+
|
|
62
|
+
@dc.dataclass(frozen=True)
|
|
63
|
+
class RawKwargsInput(Input, lang.Final):
|
|
55
64
|
pass
|
|
56
65
|
|
|
57
66
|
input: Input
|
|
@@ -70,6 +79,10 @@ class ToolFn(lang.Final):
|
|
|
70
79
|
check.isinstance(self.cls, type)
|
|
71
80
|
check.arg(dc.is_dataclass(self.cls))
|
|
72
81
|
|
|
82
|
+
@dc.dataclass(frozen=True)
|
|
83
|
+
class MarshalOutput(Output, lang.Final):
|
|
84
|
+
rty: rfl.Type
|
|
85
|
+
|
|
73
86
|
@dc.dataclass(frozen=True)
|
|
74
87
|
class RawStringOutput(Output, lang.Final):
|
|
75
88
|
pass
|
|
@@ -100,7 +113,7 @@ async def execute_tool_fn(
|
|
|
100
113
|
args: ta.Mapping[str, ta.Any],
|
|
101
114
|
*,
|
|
102
115
|
forbid_sync_as_async: bool = False,
|
|
103
|
-
) ->
|
|
116
|
+
) -> Content:
|
|
104
117
|
m_fn: ta.Callable[..., ta.Awaitable[ta.Any]]
|
|
105
118
|
if isinstance(tfn.impl, ToolFn.FnImpl):
|
|
106
119
|
s_fn = tfn.impl.s
|
|
@@ -115,20 +128,44 @@ async def execute_tool_fn(
|
|
|
115
128
|
else:
|
|
116
129
|
raise TypeError(tfn.impl)
|
|
117
130
|
|
|
118
|
-
|
|
131
|
+
#
|
|
132
|
+
|
|
133
|
+
fn_kw: ta.Mapping[str, ta.Any]
|
|
119
134
|
if isinstance(tfn.input, ToolFn.DataclassInput):
|
|
120
135
|
raise NotImplementedError
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
|
|
137
|
+
elif isinstance(tfn.input, ToolFn.MarshalInput):
|
|
138
|
+
fn_kw_dct: dict[str, ta.Any] = {}
|
|
139
|
+
for k, v in args.items():
|
|
140
|
+
fn_kw_dct[k] = msh.unmarshal(v, tfn.input.rtys[k])
|
|
141
|
+
fn_kw = fn_kw_dct
|
|
142
|
+
|
|
143
|
+
elif isinstance(tfn.input, ToolFn.RawKwargsInput):
|
|
144
|
+
fn_kw = args
|
|
145
|
+
|
|
123
146
|
else:
|
|
124
|
-
raise
|
|
147
|
+
raise TypeError(tfn.input)
|
|
125
148
|
|
|
126
|
-
|
|
149
|
+
#
|
|
150
|
+
|
|
151
|
+
fn_out = await m_fn(**fn_kw)
|
|
152
|
+
|
|
153
|
+
#
|
|
154
|
+
|
|
155
|
+
ret: Content
|
|
127
156
|
if isinstance(tfn.output, ToolFn.DataclassOutput):
|
|
128
157
|
raise NotImplementedError
|
|
158
|
+
|
|
159
|
+
elif isinstance(tfn.output, ToolFn.MarshalOutput):
|
|
160
|
+
out_v = msh.marshal(fn_out, tfn.output.rty)
|
|
161
|
+
ret = JsonContent(out_v)
|
|
162
|
+
|
|
129
163
|
elif isinstance(tfn.output, ToolFn.RawStringOutput):
|
|
130
|
-
ret = check.isinstance(
|
|
164
|
+
ret = check.isinstance(fn_out, str)
|
|
165
|
+
|
|
131
166
|
else:
|
|
132
|
-
raise
|
|
167
|
+
raise TypeError(tfn.output)
|
|
168
|
+
|
|
169
|
+
#
|
|
133
170
|
|
|
134
171
|
return ret
|
|
@@ -9,6 +9,7 @@ from ..content.prepare import default_content_str_preparer
|
|
|
9
9
|
from .types import EnumToolDtype
|
|
10
10
|
from .types import MappingToolDtype
|
|
11
11
|
from .types import NullableToolDtype
|
|
12
|
+
from .types import ObjectToolDtype
|
|
12
13
|
from .types import PrimitiveToolDtype
|
|
13
14
|
from .types import SequenceToolDtype
|
|
14
15
|
from .types import ToolDtype
|
|
@@ -72,15 +73,23 @@ class ToolJsonschemaRenderer:
|
|
|
72
73
|
'enum': list(t.values),
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
if isinstance(t, ObjectToolDtype):
|
|
77
|
+
return {
|
|
78
|
+
'type': 'object',
|
|
79
|
+
'properties': {
|
|
80
|
+
k: self.render_type(v)
|
|
81
|
+
for k, v in t.fields.items()
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
75
85
|
raise TypeError(t)
|
|
76
86
|
|
|
77
87
|
def render_tool_params(self, ts: ToolSpec) -> dict:
|
|
78
|
-
pr_dct: dict[str, dict]
|
|
88
|
+
pr_dct: dict[str, dict] = {}
|
|
79
89
|
req_lst: list[str] | None = None
|
|
80
|
-
if ts.params
|
|
81
|
-
pr_dct = {}
|
|
90
|
+
if ts.params:
|
|
82
91
|
req_lst = []
|
|
83
|
-
for p in ts.params
|
|
92
|
+
for p in ts.params:
|
|
84
93
|
pr_dct[check.non_empty_str(p.name)] = {
|
|
85
94
|
**({'description': self._content_str_preparer.prepare_str(p.desc)} if p.desc is not None else {}),
|
|
86
95
|
**(self.render_type(p.type) if p.type is not None else {}),
|
|
@@ -90,7 +99,7 @@ class ToolJsonschemaRenderer:
|
|
|
90
99
|
|
|
91
100
|
return {
|
|
92
101
|
'type': 'object',
|
|
93
|
-
|
|
102
|
+
'properties': pr_dct,
|
|
94
103
|
**({'required': req_lst} if req_lst is not None else {}),
|
|
95
104
|
# By default any additional properties are allowed.
|
|
96
105
|
# https://json-schema.org/understanding-json-schema/reference/object#additionalproperties
|
|
@@ -15,17 +15,19 @@ import textwrap
|
|
|
15
15
|
import types
|
|
16
16
|
import typing as ta
|
|
17
17
|
|
|
18
|
-
from omdev.py import docstrings
|
|
19
18
|
from omlish import check
|
|
20
19
|
from omlish import collections as col
|
|
21
20
|
from omlish import dataclasses as dc
|
|
21
|
+
from omlish import lang
|
|
22
22
|
from omlish import metadata as md
|
|
23
23
|
from omlish import reflect as rfl
|
|
24
24
|
from omlish.lite.cached import cached_nullary
|
|
25
25
|
|
|
26
|
+
from ..content.materialize import CanContent
|
|
26
27
|
from .types import EnumToolDtype
|
|
27
28
|
from .types import MappingToolDtype
|
|
28
29
|
from .types import NullableToolDtype
|
|
30
|
+
from .types import ObjectToolDtype
|
|
29
31
|
from .types import PrimitiveToolDtype
|
|
30
32
|
from .types import SequenceToolDtype
|
|
31
33
|
from .types import ToolDtype
|
|
@@ -35,6 +37,10 @@ from .types import TupleToolDtype
|
|
|
35
37
|
from .types import UnionToolDtype
|
|
36
38
|
|
|
37
39
|
|
|
40
|
+
with lang.auto_proxy_import(globals()):
|
|
41
|
+
from omdev.py import docstrings
|
|
42
|
+
|
|
43
|
+
|
|
38
44
|
##
|
|
39
45
|
|
|
40
46
|
|
|
@@ -108,6 +114,12 @@ class ToolReflector:
|
|
|
108
114
|
])
|
|
109
115
|
|
|
110
116
|
def reflect_type(self, rty: rfl.Type) -> ToolDtype:
|
|
117
|
+
if isinstance(rty, type) and dc.is_dataclass(rty):
|
|
118
|
+
return ObjectToolDtype({
|
|
119
|
+
f.name: self.reflect_type(rfl.type_(f.type))
|
|
120
|
+
for f in dc.fields(rty)
|
|
121
|
+
})
|
|
122
|
+
|
|
111
123
|
if isinstance(rty, (type, rfl.Any)):
|
|
112
124
|
return PrimitiveToolDtype.of(rty)
|
|
113
125
|
|
|
@@ -147,10 +159,10 @@ class ToolReflector:
|
|
|
147
159
|
|
|
148
160
|
#
|
|
149
161
|
|
|
150
|
-
def _prepare_desc(self, s:
|
|
162
|
+
def _prepare_desc(self, s: CanContent) -> CanContent:
|
|
151
163
|
if s is None:
|
|
152
164
|
return None
|
|
153
|
-
if not self._raw_descs:
|
|
165
|
+
if not self._raw_descs and isinstance(s, str):
|
|
154
166
|
s = s.strip()
|
|
155
167
|
return s
|
|
156
168
|
|
|
@@ -160,14 +172,22 @@ class ToolReflector:
|
|
|
160
172
|
|
|
161
173
|
#
|
|
162
174
|
|
|
175
|
+
p_ovr_dct: dict[str, dict[str, ta.Any]] = {}
|
|
163
176
|
ts_ovr: dict[str, ta.Any] = {}
|
|
177
|
+
o: _ToolSpecOverride
|
|
164
178
|
for o in md.get_object_metadata(fn, type=_ToolSpecOverride):
|
|
165
|
-
# TODO: better params handling / merging
|
|
166
179
|
ts_ovr.update({
|
|
167
180
|
k: v
|
|
168
181
|
for k, v in dc.asdict(o).items()
|
|
169
|
-
if
|
|
182
|
+
if k != 'params'
|
|
183
|
+
and v is not None
|
|
170
184
|
})
|
|
185
|
+
for op in (o.params or []):
|
|
186
|
+
p_ovr_dct.setdefault(check.non_empty_str(op.name), {}).update({
|
|
187
|
+
k: v
|
|
188
|
+
for k, v in dc.asdict(op).items()
|
|
189
|
+
if v is not None
|
|
190
|
+
})
|
|
171
191
|
|
|
172
192
|
#
|
|
173
193
|
|
|
@@ -207,23 +227,39 @@ class ToolReflector:
|
|
|
207
227
|
if 'params' not in ts_kw:
|
|
208
228
|
ds_p_dct = {
|
|
209
229
|
ds_p.arg_name: ds_p
|
|
210
|
-
for ds_p in (ds.params if ds is not None else
|
|
230
|
+
for ds_p in (ds.params if ds is not None else {})
|
|
211
231
|
}
|
|
212
232
|
|
|
213
|
-
|
|
214
|
-
for sig_p in sig().parameters.values():
|
|
215
|
-
check.not_in(sig_p.name, params)
|
|
216
|
-
|
|
217
|
-
ds_p = ds_p_dct.get(sig_p.name)
|
|
233
|
+
sig_p_dct = sig().parameters
|
|
218
234
|
|
|
219
|
-
|
|
220
|
-
sig_p.name,
|
|
235
|
+
pns: list[str] = list({**p_ovr_dct, **ds_p_dct, **sig_p_dct})
|
|
221
236
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
237
|
+
params: dict[str, ToolParam] = {}
|
|
238
|
+
for pn in pns:
|
|
239
|
+
ovr_p = p_ovr_dct.get(pn, {})
|
|
240
|
+
ds_p = ds_p_dct.get(pn)
|
|
241
|
+
sig_p = sig_p_dct.get(pn)
|
|
242
|
+
|
|
243
|
+
p_desc: CanContent
|
|
244
|
+
if (p_desc := ovr_p.get('desc')) is None:
|
|
245
|
+
if ds_p is not None:
|
|
246
|
+
p_desc = ds_p.description
|
|
247
|
+
|
|
248
|
+
p_type: ToolDtype | None
|
|
249
|
+
if (p_type := ovr_p.get('type')) is None:
|
|
250
|
+
if sig_p is not None and sig_p.name in th():
|
|
251
|
+
p_type = self.reflect_type(rfl.type_(th()[sig_p.name]))
|
|
252
|
+
|
|
253
|
+
p_required: bool | None
|
|
254
|
+
if (p_required := ovr_p.get('required')) is None:
|
|
255
|
+
if sig_p is not None:
|
|
256
|
+
p_required = sig_p.default is inspect.Parameter.empty
|
|
257
|
+
|
|
258
|
+
params[pn] = ToolParam(
|
|
259
|
+
pn,
|
|
260
|
+
desc=self._prepare_desc(p_desc) if p_desc is not None else None,
|
|
261
|
+
type=p_type,
|
|
262
|
+
required=p_required,
|
|
227
263
|
)
|
|
228
264
|
|
|
229
265
|
ts_kw.update(params=tuple(params.values()) if params else None)
|
ommlds/minichain/tools/types.py
CHANGED
|
@@ -6,11 +6,14 @@ from omlish import cached
|
|
|
6
6
|
from omlish import check
|
|
7
7
|
from omlish import collections as col
|
|
8
8
|
from omlish import dataclasses as dc
|
|
9
|
+
from omlish import dispatch
|
|
9
10
|
from omlish import lang
|
|
10
11
|
from omlish import marshal as msh
|
|
11
12
|
from omlish import reflect as rfl
|
|
12
13
|
|
|
13
14
|
from ..content.materialize import CanContent
|
|
15
|
+
from ..content.transforms.base import ContentTransform
|
|
16
|
+
from ..content.types import Content
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
msh.register_global_module_import('._marshal', __package__)
|
|
@@ -127,6 +130,15 @@ class EnumToolDtype(ToolDtype):
|
|
|
127
130
|
values: ta.Sequence[ta.Any]
|
|
128
131
|
|
|
129
132
|
|
|
133
|
+
#
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@dc.dataclass(frozen=True)
|
|
137
|
+
@dc.extra_class_params(terse_repr=True)
|
|
138
|
+
class ObjectToolDtype(ToolDtype):
|
|
139
|
+
fields: ta.Mapping[str, ToolDtype]
|
|
140
|
+
|
|
141
|
+
|
|
130
142
|
##
|
|
131
143
|
|
|
132
144
|
|
|
@@ -177,9 +189,29 @@ class ToolSpec:
|
|
|
177
189
|
|
|
178
190
|
|
|
179
191
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
180
|
-
class
|
|
192
|
+
class ToolUse(lang.Final):
|
|
181
193
|
id: str | None = None
|
|
182
194
|
name: str
|
|
183
195
|
args: ta.Mapping[str, ta.Any]
|
|
184
196
|
|
|
185
197
|
raw_args: str | None = None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
201
|
+
class ToolUseResult(lang.Final):
|
|
202
|
+
id: str | None = None
|
|
203
|
+
name: str
|
|
204
|
+
c: Content
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
##
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class _ToolUseContentTransform(ContentTransform, lang.Final, lang.NotInstantiable):
|
|
211
|
+
@dispatch.install_method(ContentTransform.apply)
|
|
212
|
+
def apply_tool_use(self, tu: ToolUse) -> ToolUse:
|
|
213
|
+
return tu # TODO: args are Content
|
|
214
|
+
|
|
215
|
+
@dispatch.install_method(ContentTransform.apply)
|
|
216
|
+
def apply_tool_use_result(self, tur: ToolUseResult) -> ToolUseResult:
|
|
217
|
+
return dc.replace(tur, c=self.apply(tur.c)) # noqa
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
from omlish import reflect as rfl
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def join_human_readable_str_list(
|
|
11
|
+
strs: ta.Iterable[str],
|
|
12
|
+
*,
|
|
13
|
+
sep: str = ', ',
|
|
14
|
+
disj: str = 'or ',
|
|
15
|
+
) -> str:
|
|
16
|
+
seq = list(strs)
|
|
17
|
+
return sep.join(
|
|
18
|
+
(disj if i == len(seq) - 1 else '') + s
|
|
19
|
+
for i, s in enumerate(seq)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def str_literal_values(lit: ta.Any) -> ta.Sequence[str]:
|
|
27
|
+
return tuple(check.isinstance(rfl.type_(lit), rfl.Literal).args)
|
|
@@ -9,7 +9,6 @@ from omlish import check
|
|
|
9
9
|
from omlish import lang
|
|
10
10
|
from omlish import marshal as msh
|
|
11
11
|
from omlish import reflect as rfl
|
|
12
|
-
from omlish.funcs import match as mfs
|
|
13
12
|
|
|
14
13
|
from .types import Vector
|
|
15
14
|
|
|
@@ -25,10 +24,11 @@ class _VectorMarshaler(msh.Marshaler):
|
|
|
25
24
|
return self.et.marshal(ctx, list(map(float, check.isinstance(o, Vector))))
|
|
26
25
|
|
|
27
26
|
|
|
28
|
-
class _VectorMarshalerFactory(msh.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
class _VectorMarshalerFactory(msh.MarshalerFactory):
|
|
28
|
+
def make_marshaler(self, ctx: msh.MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Marshaler] | None:
|
|
29
|
+
if rty is not Vector:
|
|
30
|
+
return None
|
|
31
|
+
return lambda: _VectorMarshaler(ctx.make_marshaler(ta.Sequence[float]))
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@dc.dataclass(frozen=True)
|
|
@@ -39,17 +39,18 @@ class _VectorUnmarshaler(msh.Unmarshaler):
|
|
|
39
39
|
return Vector(self.et.unmarshal(ctx, v))
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class _VectorUnmarshalerFactory(msh.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
class _VectorUnmarshalerFactory(msh.UnmarshalerFactory):
|
|
43
|
+
def make_unmarshaler(self, ctx: msh.UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Unmarshaler] | None: # noqa
|
|
44
|
+
if rty is not Vector:
|
|
45
|
+
return None
|
|
46
|
+
return lambda: _VectorUnmarshaler(ctx.make_unmarshaler(ta.Sequence[float]))
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
##
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
@lang.static_init
|
|
52
|
-
def
|
|
53
|
+
def _install_standard_marshaling() -> None:
|
|
53
54
|
msh.install_standard_factories(
|
|
54
55
|
_VectorMarshalerFactory(),
|
|
55
56
|
_VectorUnmarshalerFactory(),
|
ommlds/nanochat/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Andrej Karpathy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
File without changes
|