ommlds 0.0.0.dev436__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.dev436.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.dev436.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.dev436.dist-info → ommlds-0.0.0.dev480.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev436.dist-info → ommlds-0.0.0.dev480.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev436.dist-info → ommlds-0.0.0.dev480.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev436.dist-info → ommlds-0.0.0.dev480.dist-info}/top_level.txt +0 -0
|
@@ -3,31 +3,25 @@ import uuid
|
|
|
3
3
|
|
|
4
4
|
from omlish import dataclasses as dc
|
|
5
5
|
|
|
6
|
-
from ..messages import
|
|
6
|
+
from ..messages import Chat
|
|
7
7
|
from ..messages import Message
|
|
8
|
-
from ..messages import
|
|
8
|
+
from ..messages import ToolUseMessage
|
|
9
9
|
from ..transforms.base import MessageTransform
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
##
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def simple_uuid_tool_exec_request_id_factory(m:
|
|
15
|
+
def simple_uuid_tool_exec_request_id_factory(m: ToolUseMessage) -> str: # noqa
|
|
16
16
|
return str(uuid.uuid4())
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@dc.dataclass(frozen=True)
|
|
20
|
-
class
|
|
21
|
-
id_factory: ta.Callable[[
|
|
20
|
+
class ToolUseIdAddingMessageTransform(MessageTransform):
|
|
21
|
+
id_factory: ta.Callable[[ToolUseMessage], str] = dc.field(default=simple_uuid_tool_exec_request_id_factory) # noqa
|
|
22
22
|
|
|
23
|
-
def transform_message(self, m: Message) ->
|
|
24
|
-
if not isinstance(m,
|
|
25
|
-
return m
|
|
23
|
+
def transform_message(self, m: Message) -> Chat:
|
|
24
|
+
if not isinstance(m, ToolUseMessage) or m.tu.id is not None:
|
|
25
|
+
return [m]
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
for ter in m.tool_exec_requests:
|
|
29
|
-
if ter.id is None:
|
|
30
|
-
ter = dc.replace(ter, id=self.id_factory(m, ter))
|
|
31
|
-
lst.append(ter)
|
|
32
|
-
|
|
33
|
-
return dc.replace(m, tool_exec_requests=lst)
|
|
27
|
+
return [dc.replace(m, tu=dc.replace(m.tu, id=self.id_factory(m)))]
|
|
@@ -1,54 +1,45 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
1
3
|
from omlish import check
|
|
2
4
|
from omlish import dataclasses as dc
|
|
3
5
|
|
|
4
|
-
from ...content.types import Content
|
|
5
6
|
from ...text.toolparsing.base import ParsedToolExec
|
|
6
7
|
from ...text.toolparsing.base import ToolExecParser
|
|
7
8
|
from ..messages import AiMessage
|
|
8
|
-
from ..messages import
|
|
9
|
-
from ..
|
|
9
|
+
from ..messages import AnyAiMessage
|
|
10
|
+
from ..messages import ToolUse
|
|
11
|
+
from ..messages import ToolUseMessage
|
|
12
|
+
from ..transforms.base import AiMessageTransform
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
##
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
@dc.dataclass(frozen=True)
|
|
16
|
-
class ToolExecParsingMessageTransform(
|
|
19
|
+
class ToolExecParsingMessageTransform(AiMessageTransform):
|
|
17
20
|
parser: ToolExecParser
|
|
18
21
|
|
|
19
|
-
def transform_message(self, message:
|
|
22
|
+
def transform_message(self, message: AnyAiMessage) -> ta.Sequence[AnyAiMessage]:
|
|
23
|
+
if not isinstance(message, AiMessage):
|
|
24
|
+
return [message]
|
|
25
|
+
|
|
20
26
|
pts = self.parser.parse_tool_execs_(check.isinstance(message.c or '', str))
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
out: list[AnyAiMessage] = []
|
|
29
|
+
|
|
24
30
|
for pt in pts:
|
|
25
31
|
if isinstance(pt, ParsedToolExec):
|
|
26
|
-
|
|
32
|
+
out.append(ToolUseMessage(ToolUse(
|
|
27
33
|
id=pt.id,
|
|
28
34
|
name=pt.name,
|
|
29
35
|
args=pt.args,
|
|
30
36
|
raw_args=pt.raw_body,
|
|
31
|
-
))
|
|
37
|
+
)))
|
|
32
38
|
|
|
33
39
|
elif isinstance(pt, str):
|
|
34
|
-
|
|
40
|
+
out.append(AiMessage(pt))
|
|
35
41
|
|
|
36
42
|
else:
|
|
37
43
|
raise TypeError(pt)
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
if len(sl) == 1:
|
|
41
|
-
[c] = sl
|
|
42
|
-
elif sl:
|
|
43
|
-
c = sl
|
|
44
|
-
else:
|
|
45
|
-
c = None
|
|
46
|
-
|
|
47
|
-
return dc.replace(
|
|
48
|
-
message,
|
|
49
|
-
c=c,
|
|
50
|
-
tool_exec_requests=[
|
|
51
|
-
*(message.tool_exec_requests or []),
|
|
52
|
-
*xl,
|
|
53
|
-
],
|
|
54
|
-
)
|
|
45
|
+
return out
|
|
@@ -1,76 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Mirrors omlish.funcs.pairs.
|
|
3
|
+
|
|
4
|
+
TODO:
|
|
5
|
+
- MessagesTransform ? MessageTransformMessagesTransform? :| ...
|
|
6
|
+
"""
|
|
1
7
|
import abc
|
|
2
8
|
import typing as ta
|
|
3
9
|
|
|
4
10
|
from omlish import dataclasses as dc
|
|
5
11
|
from omlish import lang
|
|
6
12
|
|
|
13
|
+
from ..messages import AnyAiMessage
|
|
14
|
+
from ..messages import AnyUserMessage
|
|
7
15
|
from ..messages import Chat
|
|
8
16
|
from ..messages import Message
|
|
9
17
|
|
|
10
18
|
|
|
19
|
+
MessageF = ta.TypeVar('MessageF', bound=Message)
|
|
11
20
|
MessageT = ta.TypeVar('MessageT', bound=Message)
|
|
12
21
|
|
|
13
22
|
|
|
14
23
|
##
|
|
15
24
|
|
|
16
25
|
|
|
17
|
-
class MessageTransform(lang.Abstract, ta.Generic[MessageT]):
|
|
26
|
+
class MessageTransform(lang.Abstract, ta.Generic[MessageF, MessageT]):
|
|
18
27
|
@abc.abstractmethod
|
|
19
|
-
def transform_message(self, message:
|
|
28
|
+
def transform_message(self, message: MessageF) -> ta.Sequence[MessageT]:
|
|
20
29
|
raise NotImplementedError
|
|
21
30
|
|
|
22
31
|
|
|
32
|
+
AiMessageTransform: ta.TypeAlias = MessageTransform[AnyAiMessage, AnyAiMessage]
|
|
33
|
+
UserMessageTransform: ta.TypeAlias = MessageTransform[AnyUserMessage, AnyUserMessage]
|
|
34
|
+
|
|
35
|
+
|
|
23
36
|
@dc.dataclass(frozen=True)
|
|
24
37
|
class CompositeMessageTransform(MessageTransform):
|
|
25
38
|
mts: ta.Sequence[MessageTransform]
|
|
26
39
|
|
|
27
|
-
def transform_message(self, message: Message) ->
|
|
40
|
+
def transform_message(self, message: Message) -> Chat:
|
|
41
|
+
chat: Chat = [message]
|
|
28
42
|
for mt in self.mts:
|
|
29
|
-
|
|
30
|
-
return
|
|
43
|
+
chat = [o for i in chat for o in mt.transform_message(i)]
|
|
44
|
+
return chat
|
|
31
45
|
|
|
32
46
|
|
|
33
47
|
@dc.dataclass(frozen=True)
|
|
34
|
-
class FnMessageTransform(MessageTransform, ta.Generic[MessageT]):
|
|
35
|
-
fn: ta.Callable[[
|
|
48
|
+
class FnMessageTransform(MessageTransform, ta.Generic[MessageF, MessageT]):
|
|
49
|
+
fn: ta.Callable[[MessageF], ta.Sequence[MessageT]]
|
|
36
50
|
|
|
37
|
-
def transform_message(self, message:
|
|
51
|
+
def transform_message(self, message: MessageF) -> ta.Sequence[MessageT]:
|
|
38
52
|
return self.fn(message)
|
|
39
53
|
|
|
40
54
|
|
|
41
55
|
@dc.dataclass(frozen=True)
|
|
42
|
-
class TypeFilteredMessageTransform(MessageTransform
|
|
56
|
+
class TypeFilteredMessageTransform(MessageTransform, ta.Generic[MessageF, MessageT]):
|
|
43
57
|
ty: type | tuple[type, ...]
|
|
44
|
-
mt: MessageTransform[MessageT]
|
|
58
|
+
mt: MessageTransform[MessageF, MessageT]
|
|
45
59
|
|
|
46
|
-
def transform_message(self, message: Message) ->
|
|
60
|
+
def transform_message(self, message: Message) -> Chat:
|
|
47
61
|
if isinstance(message, self.ty):
|
|
48
|
-
return self.mt.transform_message(ta.cast(
|
|
62
|
+
return self.mt.transform_message(ta.cast(MessageF, message))
|
|
49
63
|
else:
|
|
50
|
-
return message
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@ta.overload
|
|
54
|
-
def fn_message_transform(
|
|
55
|
-
fn: ta.Callable[[MessageT], MessageT],
|
|
56
|
-
ty: type[MessageT],
|
|
57
|
-
) -> MessageTransform[MessageT]:
|
|
58
|
-
...
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@ta.overload
|
|
62
|
-
def fn_message_transform(
|
|
63
|
-
fn: ta.Callable[[Message], Message],
|
|
64
|
-
ty: type | tuple[type, ...] | None = None,
|
|
65
|
-
) -> MessageTransform:
|
|
66
|
-
...
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def fn_message_transform(fn, ty=None) -> MessageTransform[MessageT]:
|
|
70
|
-
mt: MessageTransform = FnMessageTransform(fn)
|
|
71
|
-
if ty is not None:
|
|
72
|
-
mt = TypeFilteredMessageTransform(ty, mt)
|
|
73
|
-
return mt
|
|
64
|
+
return [message]
|
|
74
65
|
|
|
75
66
|
|
|
76
67
|
##
|
|
@@ -108,7 +99,7 @@ class MessageTransformChatTransform(ChatTransform):
|
|
|
108
99
|
mt: MessageTransform
|
|
109
100
|
|
|
110
101
|
def transform_chat(self, chat: Chat) -> Chat:
|
|
111
|
-
return [self.mt.transform_message(
|
|
102
|
+
return [o for i in chat for o in self.mt.transform_message(i)]
|
|
112
103
|
|
|
113
104
|
|
|
114
105
|
@dc.dataclass(frozen=True)
|
|
@@ -117,6 +108,6 @@ class LastMessageTransformChatTransform(ChatTransform):
|
|
|
117
108
|
|
|
118
109
|
def transform_chat(self, chat: Chat) -> Chat:
|
|
119
110
|
if chat:
|
|
120
|
-
return [*chat[:-1], self.mt.transform_message(chat[-1])]
|
|
111
|
+
return [*chat[:-1], *self.mt.transform_message(chat[-1])]
|
|
121
112
|
else:
|
|
122
113
|
return []
|
|
@@ -3,13 +3,20 @@ import typing as ta
|
|
|
3
3
|
import uuid
|
|
4
4
|
|
|
5
5
|
from omlish import dataclasses as dc
|
|
6
|
+
from omlish import lang
|
|
7
|
+
from omlish import typedvalues as tv
|
|
6
8
|
|
|
7
9
|
from ...metadata import CreatedAt
|
|
8
10
|
from ...metadata import Uuid
|
|
11
|
+
from ..messages import Chat
|
|
9
12
|
from ..messages import Message
|
|
13
|
+
from ..metadata import MessageMetadata
|
|
10
14
|
from .base import MessageTransform
|
|
11
15
|
|
|
12
16
|
|
|
17
|
+
MessageT = ta.TypeVar('MessageT', bound=Message)
|
|
18
|
+
|
|
19
|
+
|
|
13
20
|
##
|
|
14
21
|
|
|
15
22
|
|
|
@@ -17,17 +24,36 @@ from .base import MessageTransform
|
|
|
17
24
|
class UuidAddingMessageTransform(MessageTransform):
|
|
18
25
|
uuid_factory: ta.Callable[[], uuid.UUID] = dc.field(default_factory=lambda: uuid.uuid4)
|
|
19
26
|
|
|
20
|
-
def transform_message(self, m: Message) ->
|
|
27
|
+
def transform_message(self, m: Message) -> Chat:
|
|
21
28
|
if Uuid not in m.metadata:
|
|
22
29
|
m = m.with_metadata(Uuid(self.uuid_factory()))
|
|
23
|
-
return m
|
|
30
|
+
return [m]
|
|
24
31
|
|
|
25
32
|
|
|
26
33
|
@dc.dataclass(frozen=True)
|
|
27
34
|
class CreatedAtAddingMessageTransform(MessageTransform):
|
|
28
35
|
clock: ta.Callable[[], datetime.datetime] = dc.field(default=datetime.datetime.now)
|
|
29
36
|
|
|
30
|
-
def transform_message(self, m: Message) ->
|
|
37
|
+
def transform_message(self, m: Message) -> Chat:
|
|
31
38
|
if CreatedAt not in m.metadata:
|
|
32
39
|
m = m.with_metadata(CreatedAt(self.clock()))
|
|
33
|
-
return m
|
|
40
|
+
return [m]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# FIXME: Unique?
|
|
47
|
+
class TransformedMessageOrigin(tv.ScalarTypedValue[Message], MessageMetadata, lang.Final):
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dc.dataclass(frozen=True)
|
|
52
|
+
class OriginAddingMessageTransform(MessageTransform):
|
|
53
|
+
child: MessageTransform
|
|
54
|
+
|
|
55
|
+
def transform_message(self, m: Message) -> Chat:
|
|
56
|
+
return [
|
|
57
|
+
o.with_metadata(TransformedMessageOrigin(m)) if TransformedMessageOrigin not in o.metadata else m
|
|
58
|
+
for o in self.child.transform_message(m)
|
|
59
|
+
]
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
from omlish import check
|
|
2
1
|
from omlish import dataclasses as dc
|
|
3
2
|
|
|
4
|
-
from ..messages import
|
|
3
|
+
from ..messages import check_ai_chat
|
|
5
4
|
from ..services import ChatRequest
|
|
6
5
|
from ..services import ChatResponse
|
|
7
6
|
from ..services import ChatService
|
|
8
7
|
from ..services import static_check_is_chat_service
|
|
9
8
|
from .base import ChatTransform
|
|
10
|
-
from .base import MessageTransform
|
|
11
9
|
|
|
12
10
|
|
|
13
11
|
##
|
|
@@ -19,10 +17,10 @@ class RequestChatTransformingChatService:
|
|
|
19
17
|
ct: ChatTransform
|
|
20
18
|
svc: ChatService
|
|
21
19
|
|
|
22
|
-
def invoke(self, request: ChatRequest) -> ChatResponse:
|
|
20
|
+
async def invoke(self, request: ChatRequest) -> ChatResponse:
|
|
23
21
|
new_chat = self.ct.transform_chat(request.v)
|
|
24
22
|
new_req = dc.replace(request, v=new_chat)
|
|
25
|
-
return self.svc.invoke(new_req)
|
|
23
|
+
return await self.svc.invoke(new_req)
|
|
26
24
|
|
|
27
25
|
|
|
28
26
|
#
|
|
@@ -30,11 +28,11 @@ class RequestChatTransformingChatService:
|
|
|
30
28
|
|
|
31
29
|
@static_check_is_chat_service
|
|
32
30
|
@dc.dataclass(frozen=True)
|
|
33
|
-
class
|
|
34
|
-
|
|
31
|
+
class ResponseChatTransformingChatService:
|
|
32
|
+
ct: ChatTransform
|
|
35
33
|
svc: ChatService
|
|
36
34
|
|
|
37
|
-
def invoke(self, request: ChatRequest) -> ChatResponse:
|
|
38
|
-
orig_resp = self.svc.invoke(request)
|
|
39
|
-
|
|
40
|
-
return dc.replace(orig_resp, v=
|
|
35
|
+
async def invoke(self, request: ChatRequest) -> ChatResponse:
|
|
36
|
+
orig_resp = await self.svc.invoke(request)
|
|
37
|
+
new_chat = check_ai_chat(self.ct.transform_chat(orig_resp.v))
|
|
38
|
+
return dc.replace(orig_resp, v=new_chat)
|
|
@@ -6,9 +6,9 @@ from omlish import check
|
|
|
6
6
|
from omlish import lang
|
|
7
7
|
from omlish import marshal as msh
|
|
8
8
|
from omlish import reflect as rfl
|
|
9
|
-
from omlish.funcs import match as mfs
|
|
10
9
|
|
|
11
10
|
from .images import ImageContent # noqa
|
|
11
|
+
from .json import JsonContent # noqa
|
|
12
12
|
from .materialize import CanContent
|
|
13
13
|
from .materialize import _InnerCanContent
|
|
14
14
|
from .sequence import BlockContent # noqa
|
|
@@ -52,10 +52,11 @@ class _ContentMarshaler(msh.Marshaler):
|
|
|
52
52
|
raise TypeError(o)
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
class _ContentMarshalerFactory(msh.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
class _ContentMarshalerFactory(msh.MarshalerFactory):
|
|
56
|
+
def make_marshaler(self, ctx: msh.MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Marshaler] | None:
|
|
57
|
+
if not (rty is MarshalContent or rty == _MARSHAL_CONTENT_UNION_RTY):
|
|
58
|
+
return None
|
|
59
|
+
return lambda: _ContentMarshaler(ctx.make_marshaler(ExtendedContent))
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
@dc.dataclass(frozen=True)
|
|
@@ -73,10 +74,11 @@ class _ContentUnmarshaler(msh.Unmarshaler):
|
|
|
73
74
|
raise TypeError(v)
|
|
74
75
|
|
|
75
76
|
|
|
76
|
-
class _ContentUnmarshalerFactory(msh.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
class _ContentUnmarshalerFactory(msh.UnmarshalerFactory):
|
|
78
|
+
def make_unmarshaler(self, ctx: msh.UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Unmarshaler] | None: # noqa
|
|
79
|
+
if not (rty is MarshalContent or rty == _MARSHAL_CONTENT_UNION_RTY):
|
|
80
|
+
return None
|
|
81
|
+
return lambda: _ContentUnmarshaler(ctx.make_unmarshaler(ExtendedContent))
|
|
80
82
|
|
|
81
83
|
|
|
82
84
|
##
|
|
@@ -103,10 +105,11 @@ class _CanContentMarshaler(msh.Marshaler):
|
|
|
103
105
|
return self.c.marshal(ctx, check.isinstance(o, CONTENT_RUNTIME_TYPES))
|
|
104
106
|
|
|
105
107
|
|
|
106
|
-
class _CanContentMarshalerFactory(msh.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
class _CanContentMarshalerFactory(msh.MarshalerFactory):
|
|
109
|
+
def make_marshaler(self, ctx: msh.MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Marshaler] | None:
|
|
110
|
+
if not (rty is MarshalCanContent or rty == _MARSHAL_CAN_CONTENT_UNION_RTY):
|
|
111
|
+
return None
|
|
112
|
+
return lambda: _CanContentMarshaler(ctx.make_marshaler(Content))
|
|
110
113
|
|
|
111
114
|
|
|
112
115
|
@dc.dataclass(frozen=True)
|
|
@@ -117,10 +120,11 @@ class _CanContentUnmarshaler(msh.Unmarshaler):
|
|
|
117
120
|
return self.c.unmarshal(ctx, v)
|
|
118
121
|
|
|
119
122
|
|
|
120
|
-
class _CanContentUnmarshalerFactory(msh.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
class _CanContentUnmarshalerFactory(msh.UnmarshalerFactory):
|
|
124
|
+
def make_unmarshaler(self, ctx: msh.UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Unmarshaler] | None: # noqa
|
|
125
|
+
if not (rty is MarshalCanContent or rty == _MARSHAL_CAN_CONTENT_UNION_RTY):
|
|
126
|
+
return None
|
|
127
|
+
return lambda: _CanContentUnmarshaler(ctx.make_unmarshaler(Content))
|
|
124
128
|
|
|
125
129
|
|
|
126
130
|
##
|
|
@@ -139,28 +143,48 @@ class _ImageContentUnmarshaler(msh.Unmarshaler):
|
|
|
139
143
|
##
|
|
140
144
|
|
|
141
145
|
|
|
146
|
+
class _JsonContentMarshaler(msh.Marshaler):
|
|
147
|
+
def marshal(self, ctx: msh.MarshalContext, o: ta.Any) -> msh.Value:
|
|
148
|
+
return ta.cast(msh.Value, check.isinstance(o, JsonContent).v)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class _JsonContentUnmarshaler(msh.Unmarshaler):
|
|
152
|
+
def unmarshal(self, ctx: msh.UnmarshalContext, v: msh.Value) -> ta.Any:
|
|
153
|
+
return JsonContent(v)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
##
|
|
157
|
+
|
|
158
|
+
|
|
142
159
|
@lang.static_init
|
|
143
|
-
def
|
|
160
|
+
def _install_standard_marshaling() -> None:
|
|
144
161
|
extended_content_poly = msh.Polymorphism(
|
|
145
162
|
ExtendedContent,
|
|
146
163
|
[
|
|
147
164
|
msh.Impl(InlineContent, 'inline'),
|
|
148
165
|
msh.Impl(BlockContent, 'block'),
|
|
149
166
|
msh.Impl(ImageContent, 'image'),
|
|
167
|
+
msh.Impl(JsonContent, 'json'),
|
|
150
168
|
msh.Impl(TextContent, 'text'),
|
|
151
169
|
],
|
|
152
170
|
)
|
|
153
171
|
|
|
154
172
|
msh.install_standard_factories(
|
|
155
173
|
msh.PolymorphismMarshalerFactory(extended_content_poly),
|
|
156
|
-
msh.TypeMapMarshalerFactory({
|
|
174
|
+
msh.TypeMapMarshalerFactory({
|
|
175
|
+
ImageContent: _ImageContentMarshaler(),
|
|
176
|
+
JsonContent: _JsonContentMarshaler(),
|
|
177
|
+
}),
|
|
157
178
|
_ContentMarshalerFactory(),
|
|
158
179
|
_CanContentMarshalerFactory(),
|
|
159
180
|
)
|
|
160
181
|
|
|
161
182
|
msh.install_standard_factories(
|
|
162
183
|
msh.PolymorphismUnmarshalerFactory(extended_content_poly),
|
|
163
|
-
msh.TypeMapUnmarshalerFactory({
|
|
184
|
+
msh.TypeMapUnmarshalerFactory({
|
|
185
|
+
ImageContent: _ImageContentUnmarshaler(),
|
|
186
|
+
JsonContent: _JsonContentUnmarshaler(),
|
|
187
|
+
}),
|
|
164
188
|
_ContentUnmarshalerFactory(),
|
|
165
189
|
_CanContentUnmarshalerFactory(),
|
|
166
190
|
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from omlish import dataclasses as dc
|
|
2
|
+
from omlish import lang
|
|
3
|
+
|
|
4
|
+
from ..json import JsonValue
|
|
5
|
+
from .simple import SimpleSingleExtendedContent
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dc.dataclass(frozen=True)
|
|
12
|
+
class JsonContent(SimpleSingleExtendedContent, lang.Final):
|
|
13
|
+
v: JsonValue
|
|
@@ -112,7 +112,7 @@ class ContentMaterializer:
|
|
|
112
112
|
finally:
|
|
113
113
|
self._cur_depth -= 1
|
|
114
114
|
|
|
115
|
-
@dispatch.method
|
|
115
|
+
@dispatch.method()
|
|
116
116
|
def _materialize(self, o: CanContent) -> Content:
|
|
117
117
|
raise TypeError(o)
|
|
118
118
|
|
|
@@ -130,7 +130,13 @@ class ContentMaterializer:
|
|
|
130
130
|
|
|
131
131
|
@_materialize.register
|
|
132
132
|
def _materialize_iterable(self, o: ta.Iterable) -> Content:
|
|
133
|
-
|
|
133
|
+
# `collections.abc.Iterable` appears as a virtual base in the dispatch c3.mro for ContentNamespace before `type`
|
|
134
|
+
# does (due to NamespaceMeta having `__iter__`), so handle that here too.
|
|
135
|
+
if isinstance(o, type) and issubclass(o, ContentNamespace):
|
|
136
|
+
return self._materialize_namespace_type(o)
|
|
137
|
+
|
|
138
|
+
else:
|
|
139
|
+
return [self.materialize(e) for e in o]
|
|
134
140
|
|
|
135
141
|
@_materialize.register
|
|
136
142
|
def _materialize_none(self, o: None) -> Content:
|
|
@@ -151,25 +157,12 @@ class ContentMaterializer:
|
|
|
151
157
|
def _materialize_namespace_type(self, o: type[ContentNamespace]) -> Content:
|
|
152
158
|
check.issubclass(o, ContentNamespace)
|
|
153
159
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
for n, e in v:
|
|
161
|
-
if n.startswith('_'):
|
|
162
|
-
continue
|
|
163
|
-
yield from rec(e)
|
|
164
|
-
|
|
165
|
-
elif isinstance(v, ta.Iterable):
|
|
166
|
-
for e in v:
|
|
167
|
-
yield from rec(e)
|
|
168
|
-
|
|
169
|
-
else:
|
|
170
|
-
yield self.materialize(v)
|
|
171
|
-
|
|
172
|
-
return list(rec(o))
|
|
160
|
+
out: list[Content] = []
|
|
161
|
+
for n, e in o:
|
|
162
|
+
if n.startswith('_'):
|
|
163
|
+
continue
|
|
164
|
+
out.append(self.materialize(e))
|
|
165
|
+
return out
|
|
173
166
|
|
|
174
167
|
#
|
|
175
168
|
|
ommlds/minichain/json.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# ruff: noqa: UP007
|
|
1
2
|
import typing as ta
|
|
2
3
|
|
|
3
4
|
from omlish import dataclasses as dc
|
|
@@ -11,3 +12,22 @@ from omlish import lang
|
|
|
11
12
|
class JsonSchema(lang.Final):
|
|
12
13
|
name: str
|
|
13
14
|
root: ta.Any
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
JsonValue: ta.TypeAlias = ta.Union[
|
|
21
|
+
ta.Mapping[str, 'JsonValue'],
|
|
22
|
+
|
|
23
|
+
ta.Sequence['JsonValue'],
|
|
24
|
+
|
|
25
|
+
str,
|
|
26
|
+
|
|
27
|
+
int,
|
|
28
|
+
float,
|
|
29
|
+
|
|
30
|
+
bool,
|
|
31
|
+
|
|
32
|
+
None,
|
|
33
|
+
]
|
|
File without changes
|