ommlds 0.0.0.dev426__py3-none-any.whl → 0.0.0.dev485__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 +336 -39
- ommlds/__about__.py +16 -10
- 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/_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 +40 -8
- ommlds/backends/google/protocol/__init__.py +16 -0
- ommlds/backends/google/protocol/_dataclasses.py +5997 -0
- ommlds/backends/google/protocol/_marshal.py +16 -0
- ommlds/backends/google/protocol/types.py +626 -0
- ommlds/backends/groq/__init__.py +7 -0
- ommlds/backends/groq/_dataclasses.py +3901 -0
- ommlds/backends/groq/_marshal.py +23 -0
- ommlds/backends/groq/protocol.py +249 -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 +19 -17
- ommlds/backends/mlx/limits.py +10 -6
- ommlds/backends/mlx/loading.py +65 -5
- ommlds/backends/ollama/__init__.py +7 -0
- ommlds/backends/ollama/_dataclasses.py +3458 -0
- ommlds/backends/ollama/protocol.py +170 -0
- ommlds/backends/openai/protocol/__init__.py +24 -29
- ommlds/backends/openai/protocol/_common.py +18 -0
- ommlds/backends/openai/protocol/_dataclasses.py +7708 -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 +7 -0
- ommlds/backends/tavily/_dataclasses.py +1734 -0
- ommlds/backends/tavily/protocol.py +301 -0
- ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
- 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 +2562 -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/messages.py +34 -0
- ommlds/cli/content/strings.py +42 -0
- ommlds/cli/inject.py +17 -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/_dataclasses.py +15401 -0
- 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 +6 -2
- 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/huggingface/repos.py +1 -5
- ommlds/minichain/backends/impls/llamacpp/chat.py +40 -22
- ommlds/minichain/backends/impls/llamacpp/completion.py +9 -5
- ommlds/minichain/backends/impls/llamacpp/format.py +4 -2
- ommlds/minichain/backends/impls/llamacpp/stream.py +43 -23
- ommlds/minichain/backends/impls/mistral.py +20 -5
- ommlds/minichain/backends/impls/mlx/chat.py +101 -24
- 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/sentencepiece/tokens.py +9 -6
- ommlds/minichain/backends/impls/tavily.py +66 -0
- ommlds/minichain/backends/impls/tinygrad/chat.py +30 -20
- ommlds/minichain/backends/impls/tokenizers/tokens.py +9 -6
- ommlds/minichain/backends/impls/transformers/sentence.py +6 -3
- ommlds/minichain/backends/impls/transformers/tokens.py +10 -7
- ommlds/minichain/backends/impls/transformers/transformers.py +160 -37
- 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 +68 -45
- 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/text/toolparsing/llamacpp/hermes2.py +3 -2
- ommlds/minichain/text/toolparsing/llamacpp/llama31.py +3 -2
- ommlds/minichain/text/toolparsing/llamacpp/utils.py +3 -2
- 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/minichain/vectors/types.py +1 -1
- 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/cli.py +1 -2
- ommlds/server/server.py +5 -5
- ommlds/server/service.py +1 -1
- 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 +371 -0
- ommlds/tools/git.py +35 -12
- ommlds/tools/ocr.py +8 -9
- ommlds/wiki/analyze.py +6 -7
- 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.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/METADATA +24 -21
- ommlds-0.0.0.dev485.dist-info/RECORD +436 -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.dev426.dist-info/RECORD +0 -303
- /ommlds/{cli/tools → backends/google}/__init__.py +0 -0
- /ommlds/{huggingface.py → backends/huggingface.py} +0 -0
- /ommlds/{minichain/lib/fs/ls → cli/content}/__init__.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.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev426.dist-info → ommlds-0.0.0.dev485.dist-info}/top_level.txt +0 -0
ommlds/minichain/stream/wrap.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# ruff: noqa: UP028
|
|
2
2
|
import typing as ta
|
|
3
3
|
|
|
4
|
-
from ..resources import
|
|
4
|
+
from ..resources import UseResources
|
|
5
5
|
from ..services import Request
|
|
6
6
|
from ..services import Service
|
|
7
7
|
from ..types import Output
|
|
8
|
-
from .services import ResponseGenerator
|
|
9
8
|
from .services import StreamResponse
|
|
9
|
+
from .services import StreamResponseSink
|
|
10
10
|
from .services import new_stream_response
|
|
11
11
|
|
|
12
12
|
|
|
@@ -29,36 +29,34 @@ class WrappedStreamService(ta.Generic[StreamRequestT, V, OutputT, StreamOutputT]
|
|
|
29
29
|
|
|
30
30
|
#
|
|
31
31
|
|
|
32
|
-
def _process_request(self, request: StreamRequestT) -> StreamRequestT:
|
|
32
|
+
async def _process_request(self, request: StreamRequestT) -> StreamRequestT:
|
|
33
33
|
return request
|
|
34
34
|
|
|
35
|
-
def _process_stream_outputs(self, outputs: ta.Sequence[StreamOutputT]) -> ta.Sequence[StreamOutputT]:
|
|
35
|
+
async def _process_stream_outputs(self, outputs: ta.Sequence[StreamOutputT]) -> ta.Sequence[StreamOutputT]:
|
|
36
36
|
return outputs
|
|
37
37
|
|
|
38
|
-
def
|
|
39
|
-
return
|
|
38
|
+
async def _process_value(self, v: V) -> ta.Iterable[V]:
|
|
39
|
+
return [v]
|
|
40
40
|
|
|
41
|
-
def _process_outputs(self, outputs: ta.Sequence[OutputT]) -> ta.Sequence[OutputT]:
|
|
41
|
+
async def _process_outputs(self, outputs: ta.Sequence[OutputT]) -> ta.Sequence[OutputT]:
|
|
42
42
|
return outputs
|
|
43
43
|
|
|
44
44
|
#
|
|
45
45
|
|
|
46
|
-
def invoke(self, request: StreamRequestT) -> StreamResponse[V, OutputT, StreamOutputT]:
|
|
47
|
-
with
|
|
48
|
-
|
|
49
|
-
in_vs
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return new_stream_response(
|
|
46
|
+
async def invoke(self, request: StreamRequestT) -> StreamResponse[V, OutputT, StreamOutputT]:
|
|
47
|
+
async with UseResources.or_new(request.options) as rs: # noqa
|
|
48
|
+
in_resp = await self._inner.invoke(await self._process_request(request))
|
|
49
|
+
in_vs = await rs.enter_async_context(in_resp.v)
|
|
50
|
+
|
|
51
|
+
async def inner(sink: StreamResponseSink[V]) -> ta.Sequence[OutputT] | None:
|
|
52
|
+
async for in_v in in_vs:
|
|
53
|
+
for out_v in (await self._process_value(in_v)):
|
|
54
|
+
await sink.emit(out_v)
|
|
55
|
+
|
|
56
|
+
return await self._process_outputs(in_vs.outputs)
|
|
57
|
+
|
|
58
|
+
return await new_stream_response(
|
|
61
59
|
rs,
|
|
62
|
-
|
|
63
|
-
self._process_stream_outputs(
|
|
60
|
+
inner,
|
|
61
|
+
await self._process_stream_outputs(in_resp.outputs),
|
|
64
62
|
)
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# @omlish-llm-author gemini-2.5-pro
|
|
2
|
-
import logging
|
|
3
2
|
import re
|
|
4
3
|
|
|
4
|
+
from omlish.logs import all as logs
|
|
5
|
+
|
|
5
6
|
from .types import ChatMsg
|
|
6
7
|
from .utils import handle_think_tag_prelude
|
|
7
8
|
from .utils import parse_json_from_string
|
|
8
9
|
from .utils import process_tool_call
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
log =
|
|
12
|
+
log = logs.get_module_logger(globals())
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
##
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# @omlish-llm-author gemini-2.5-pro
|
|
2
2
|
import json
|
|
3
|
-
import logging
|
|
4
3
|
import re
|
|
5
4
|
|
|
5
|
+
from omlish.logs import all as logs
|
|
6
|
+
|
|
6
7
|
from .types import ChatMsg
|
|
7
8
|
from .types import ChatToolCall
|
|
8
9
|
from .utils import parse_json_tool_calls
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
log =
|
|
12
|
+
log = logs.get_module_logger(globals())
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
##
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# @omlish-llm-author gemini-2.5-pro
|
|
2
2
|
import json
|
|
3
|
-
import logging
|
|
4
3
|
import re
|
|
5
4
|
import typing as ta
|
|
6
5
|
|
|
6
|
+
from omlish.logs import all as logs
|
|
7
|
+
|
|
7
8
|
from .types import ChatMsg
|
|
8
9
|
from .types import ChatToolCall
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
log =
|
|
12
|
+
log = logs.get_module_logger(globals())
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
##
|
|
@@ -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)
|