ommlds 0.0.0.dev450__py3-none-any.whl → 0.0.0.dev452__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.
Potentially problematic release.
This version of ommlds might be problematic. Click here for more details.
- ommlds/.omlish-manifests.json +12 -12
- ommlds/backends/anthropic/protocol/_marshal.py +2 -2
- ommlds/backends/anthropic/protocol/sse/_marshal.py +1 -1
- ommlds/backends/anthropic/protocol/sse/assemble.py +1 -1
- ommlds/backends/anthropic/protocol/types.py +30 -9
- ommlds/backends/google/protocol/_marshal.py +1 -1
- ommlds/backends/openai/protocol/_common.py +18 -0
- ommlds/backends/openai/protocol/_marshal.py +3 -2
- ommlds/backends/openai/protocol/chatcompletion/chunk.py +4 -0
- ommlds/backends/openai/protocol/chatcompletion/contentpart.py +15 -7
- ommlds/backends/openai/protocol/chatcompletion/message.py +10 -0
- ommlds/backends/openai/protocol/chatcompletion/request.py +25 -7
- ommlds/backends/openai/protocol/chatcompletion/response.py +10 -0
- ommlds/backends/openai/protocol/chatcompletion/responseformat.py +6 -0
- ommlds/backends/openai/protocol/chatcompletion/tokenlogprob.py +4 -0
- ommlds/backends/openai/protocol/completionusage.py +5 -0
- ommlds/cli/main.py +2 -2
- ommlds/cli/sessions/chat/code.py +34 -19
- ommlds/cli/sessions/chat/inject.py +4 -4
- ommlds/cli/sessions/chat/interactive.py +2 -1
- ommlds/cli/sessions/chat/printing.py +6 -2
- ommlds/cli/sessions/chat/prompt.py +28 -27
- ommlds/cli/sessions/chat/tools.py +13 -14
- ommlds/cli/tools/config.py +1 -1
- ommlds/cli/tools/inject.py +4 -1
- ommlds/minichain/__init__.py +32 -8
- ommlds/minichain/_marshal.py +39 -0
- ommlds/minichain/backends/impls/anthropic/chat.py +82 -10
- ommlds/minichain/backends/impls/anthropic/names.py +3 -3
- ommlds/minichain/backends/impls/anthropic/stream.py +7 -7
- ommlds/minichain/backends/impls/google/chat.py +48 -22
- ommlds/minichain/backends/impls/google/stream.py +8 -4
- ommlds/minichain/backends/impls/llamacpp/chat.py +23 -17
- ommlds/minichain/backends/impls/llamacpp/format.py +4 -2
- ommlds/minichain/backends/impls/llamacpp/stream.py +6 -6
- ommlds/minichain/backends/impls/mistral.py +1 -1
- ommlds/minichain/backends/impls/mlx/chat.py +1 -1
- ommlds/minichain/backends/impls/openai/chat.py +6 -3
- ommlds/minichain/backends/impls/openai/format.py +80 -61
- ommlds/minichain/backends/impls/openai/format2.py +210 -0
- ommlds/minichain/backends/impls/openai/stream.py +9 -6
- ommlds/minichain/backends/impls/tinygrad/chat.py +10 -5
- ommlds/minichain/backends/impls/transformers/transformers.py +20 -16
- ommlds/minichain/chat/_marshal.py +16 -9
- ommlds/minichain/chat/choices/adapters.py +3 -3
- ommlds/minichain/chat/choices/types.py +2 -2
- ommlds/minichain/chat/history.py +1 -1
- ommlds/minichain/chat/messages.py +55 -19
- ommlds/minichain/chat/services.py +2 -2
- ommlds/minichain/chat/stream/_marshal.py +16 -0
- ommlds/minichain/chat/stream/adapters.py +39 -28
- ommlds/minichain/chat/stream/services.py +2 -2
- ommlds/minichain/chat/stream/types.py +20 -13
- 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 +5 -7
- ommlds/minichain/content/_marshal.py +24 -3
- ommlds/minichain/content/json.py +13 -0
- ommlds/minichain/content/materialize.py +13 -20
- ommlds/minichain/content/prepare.py +4 -0
- ommlds/minichain/json.py +20 -0
- ommlds/minichain/lib/fs/context.py +15 -1
- ommlds/minichain/lib/fs/errors.py +6 -0
- ommlds/minichain/lib/fs/tools/edit.py +104 -0
- ommlds/minichain/lib/fs/tools/ls.py +2 -2
- ommlds/minichain/lib/fs/tools/read.py +2 -2
- ommlds/minichain/lib/fs/tools/recursivels/execution.py +2 -2
- ommlds/minichain/lib/todo/context.py +29 -2
- ommlds/minichain/lib/todo/tools/read.py +11 -6
- ommlds/minichain/lib/todo/tools/write.py +73 -13
- ommlds/minichain/lib/todo/types.py +6 -1
- ommlds/minichain/llms/_marshal.py +1 -1
- ommlds/minichain/services/_marshal.py +1 -1
- ommlds/minichain/tools/_marshal.py +1 -1
- ommlds/minichain/tools/execution/catalog.py +2 -1
- ommlds/minichain/tools/execution/executors.py +8 -3
- ommlds/minichain/tools/execution/reflect.py +43 -5
- ommlds/minichain/tools/fns.py +46 -9
- ommlds/minichain/tools/jsonschema.py +5 -6
- ommlds/minichain/tools/reflect.py +2 -2
- ommlds/minichain/tools/types.py +24 -1
- ommlds/minichain/vectors/_marshal.py +1 -1
- ommlds/server/server.py +1 -1
- ommlds/tools/git.py +18 -2
- ommlds/tools/ocr.py +7 -1
- {ommlds-0.0.0.dev450.dist-info → ommlds-0.0.0.dev452.dist-info}/METADATA +3 -3
- {ommlds-0.0.0.dev450.dist-info → ommlds-0.0.0.dev452.dist-info}/RECORD +94 -89
- {ommlds-0.0.0.dev450.dist-info → ommlds-0.0.0.dev452.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev450.dist-info → ommlds-0.0.0.dev452.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev450.dist-info → ommlds-0.0.0.dev452.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev450.dist-info → ommlds-0.0.0.dev452.dist-info}/top_level.txt +0 -0
|
@@ -3,17 +3,21 @@ import typing as ta
|
|
|
3
3
|
from omlish import dataclasses as dc
|
|
4
4
|
from omlish import lang
|
|
5
5
|
|
|
6
|
+
from .._common import _set_class_marshal_options
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
##
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
13
|
+
@_set_class_marshal_options
|
|
11
14
|
class ChatCompletionTokenLogprob(lang.Final):
|
|
12
15
|
token: str
|
|
13
16
|
bytes: ta.Sequence[int] | None = None
|
|
14
17
|
logprob: float
|
|
15
18
|
|
|
16
19
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
20
|
+
@_set_class_marshal_options
|
|
17
21
|
class TopLogprob(lang.Final):
|
|
18
22
|
token: str
|
|
19
23
|
bytes: ta.Sequence[int] | None = None
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
from omlish import dataclasses as dc
|
|
2
2
|
from omlish import lang
|
|
3
3
|
|
|
4
|
+
from ._common import _set_class_marshal_options
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
##
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
11
|
+
@_set_class_marshal_options
|
|
9
12
|
class CompletionUsage(lang.Final):
|
|
10
13
|
completion_tokens: int
|
|
11
14
|
prompt_tokens: int
|
|
12
15
|
total_tokens: int
|
|
13
16
|
|
|
14
17
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
18
|
+
@_set_class_marshal_options
|
|
15
19
|
class CompletionTokensDetails(lang.Final):
|
|
16
20
|
accepted_prediction_tokens: int | None = None
|
|
17
21
|
audio_tokens: int | None = None
|
|
@@ -21,6 +25,7 @@ class CompletionUsage(lang.Final):
|
|
|
21
25
|
completion_tokens_details: CompletionTokensDetails | None = None
|
|
22
26
|
|
|
23
27
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
28
|
+
@_set_class_marshal_options
|
|
24
29
|
class PromptTokensDetails(lang.Final):
|
|
25
30
|
audio_tokens: int | None = None
|
|
26
31
|
cached_tokens: int | None = None
|
ommlds/cli/main.py
CHANGED
|
@@ -68,7 +68,7 @@ async def _a_main(args: ta.Any = None) -> None:
|
|
|
68
68
|
|
|
69
69
|
parser.add_argument('--enable-fs-tools', action='store_true')
|
|
70
70
|
parser.add_argument('--enable-todo-tools', action='store_true')
|
|
71
|
-
parser.add_argument('--enable-unsafe-
|
|
71
|
+
parser.add_argument('--enable-unsafe-tools-do-not-use-lol', action='store_true')
|
|
72
72
|
parser.add_argument('--enable-test-weather-tool', action='store_true')
|
|
73
73
|
parser.add_argument('--dangerous-no-tool-confirmation', action='store_true')
|
|
74
74
|
|
|
@@ -174,7 +174,7 @@ async def _a_main(args: ta.Any = None) -> None:
|
|
|
174
174
|
tools_config = ToolsConfig(
|
|
175
175
|
enable_fs_tools=args.enable_fs_tools or args.code,
|
|
176
176
|
enable_todo_tools=args.enable_todo_tools or args.code,
|
|
177
|
-
|
|
177
|
+
enable_unsafe_tools_do_not_use_lol=args.enable_unsafe_tools_do_not_use_lol,
|
|
178
178
|
enable_test_weather_tool=args.enable_test_weather_tool,
|
|
179
179
|
)
|
|
180
180
|
|
ommlds/cli/sessions/chat/code.py
CHANGED
|
@@ -7,12 +7,13 @@ from omlish import lang
|
|
|
7
7
|
|
|
8
8
|
from .... import minichain as mc
|
|
9
9
|
from ....minichain.lib.code.prompts import CODE_AGENT_SYSTEM_PROMPT
|
|
10
|
+
from ...tools.config import ToolsConfig
|
|
10
11
|
from .base import DEFAULT_CHAT_MODEL_BACKEND
|
|
11
12
|
from .base import ChatOptions
|
|
12
13
|
from .base import ChatSession
|
|
13
14
|
from .printing import ChatSessionPrinter
|
|
14
15
|
from .state import ChatStateManager
|
|
15
|
-
from .tools import
|
|
16
|
+
from .tools import ToolUseExecutor
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
with lang.auto_proxy_import(globals()):
|
|
@@ -42,7 +43,8 @@ class CodeChatSession(ChatSession['CodeChatSession.Config']):
|
|
|
42
43
|
chat_options: ChatOptions | None = None,
|
|
43
44
|
printer: ChatSessionPrinter,
|
|
44
45
|
backend_catalog: mc.BackendCatalog,
|
|
45
|
-
tool_exec_request_executor:
|
|
46
|
+
tool_exec_request_executor: ToolUseExecutor,
|
|
47
|
+
tools_config: ToolsConfig | None = None,
|
|
46
48
|
) -> None:
|
|
47
49
|
super().__init__(config)
|
|
48
50
|
|
|
@@ -51,6 +53,7 @@ class CodeChatSession(ChatSession['CodeChatSession.Config']):
|
|
|
51
53
|
self._printer = printer
|
|
52
54
|
self._backend_catalog = backend_catalog
|
|
53
55
|
self._tool_exec_request_executor = tool_exec_request_executor
|
|
56
|
+
self._tools_config = tools_config
|
|
54
57
|
|
|
55
58
|
async def run(self) -> None:
|
|
56
59
|
if self._config.new:
|
|
@@ -68,7 +71,11 @@ class CodeChatSession(ChatSession['CodeChatSession.Config']):
|
|
|
68
71
|
|
|
69
72
|
# FIXME: lol
|
|
70
73
|
from ....minichain.lib.fs.context import FsContext
|
|
71
|
-
fs_tool_context = FsContext(
|
|
74
|
+
fs_tool_context = FsContext(
|
|
75
|
+
root_dir=os.getcwd(),
|
|
76
|
+
writes_permitted=self._tools_config is not None and self._tools_config.enable_unsafe_tools_do_not_use_lol,
|
|
77
|
+
)
|
|
78
|
+
|
|
72
79
|
from ....minichain.lib.todo.context import TodoContext
|
|
73
80
|
todo_tool_context = TodoContext()
|
|
74
81
|
|
|
@@ -82,7 +89,10 @@ class CodeChatSession(ChatSession['CodeChatSession.Config']):
|
|
|
82
89
|
if not i and self._config.initial_message is not None:
|
|
83
90
|
req_msg = mc.UserMessage(self._config.initial_message)
|
|
84
91
|
else:
|
|
85
|
-
|
|
92
|
+
try:
|
|
93
|
+
prompt = await ptk.prompt('> ')
|
|
94
|
+
except EOFError:
|
|
95
|
+
break
|
|
86
96
|
req_msg = mc.UserMessage(prompt)
|
|
87
97
|
|
|
88
98
|
state = self._state_manager.extend_chat([req_msg])
|
|
@@ -92,23 +102,28 @@ class CodeChatSession(ChatSession['CodeChatSession.Config']):
|
|
|
92
102
|
state.chat,
|
|
93
103
|
(self._chat_options or []),
|
|
94
104
|
))
|
|
95
|
-
resp_msg = check.single(response.v).m
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
tool_resp_lst = []
|
|
107
|
+
for resp_msg in check.single(response.v).ms:
|
|
108
|
+
state = self._state_manager.extend_chat([resp_msg])
|
|
99
109
|
|
|
100
|
-
|
|
101
|
-
|
|
110
|
+
if isinstance(resp_msg, mc.AiMessage):
|
|
111
|
+
self._printer.print(resp_msg)
|
|
102
112
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
elif isinstance(resp_msg, mc.ToolUseMessage):
|
|
114
|
+
trm = await self._tool_exec_request_executor.execute_tool_use(
|
|
115
|
+
resp_msg.tu,
|
|
116
|
+
fs_tool_context,
|
|
117
|
+
todo_tool_context,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
self._printer.print(trm.tur.c)
|
|
121
|
+
tool_resp_lst.append(trm)
|
|
122
|
+
|
|
123
|
+
else:
|
|
124
|
+
raise TypeError(resp_msg)
|
|
125
|
+
|
|
126
|
+
if not tool_resp_lst:
|
|
127
|
+
break
|
|
113
128
|
|
|
114
129
|
state = self._state_manager.extend_chat(tool_resp_lst)
|
|
@@ -14,9 +14,9 @@ from .state import ChatStateManager
|
|
|
14
14
|
from .state import StateStorageChatStateManager
|
|
15
15
|
from .tools import AskingToolExecutionConfirmation
|
|
16
16
|
from .tools import NopToolExecutionConfirmation
|
|
17
|
-
from .tools import ToolExecRequestExecutor
|
|
18
|
-
from .tools import ToolExecRequestExecutorImpl
|
|
19
17
|
from .tools import ToolExecutionConfirmation
|
|
18
|
+
from .tools import ToolUseExecutor
|
|
19
|
+
from .tools import ToolUseExecutorImpl
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
##
|
|
@@ -89,8 +89,8 @@ def bind_chat_session(cfg: ChatSession.Config) -> inj.Elements:
|
|
|
89
89
|
#
|
|
90
90
|
|
|
91
91
|
els.extend([
|
|
92
|
-
inj.bind(
|
|
93
|
-
inj.bind(
|
|
92
|
+
inj.bind(ToolUseExecutorImpl, singleton=True),
|
|
93
|
+
inj.bind(ToolUseExecutor, to_key=ToolUseExecutorImpl),
|
|
94
94
|
])
|
|
95
95
|
|
|
96
96
|
#
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import dataclasses as dc
|
|
2
2
|
|
|
3
|
+
from omlish import check
|
|
3
4
|
from omlish import lang
|
|
4
5
|
|
|
5
6
|
from .... import minichain as mc
|
|
@@ -63,7 +64,7 @@ class InteractiveChatSession(ChatSession['InteractiveChatSession.Config']):
|
|
|
63
64
|
|
|
64
65
|
response = await mdl.invoke(mc.ChatChoicesRequest([*state.chat, req_msg]))
|
|
65
66
|
|
|
66
|
-
resp_msg = response.v[0].
|
|
67
|
+
resp_msg = check.isinstance(check.single(response.v[0].ms), mc.AiMessage)
|
|
67
68
|
|
|
68
69
|
self._printer.print(resp_msg)
|
|
69
70
|
|
|
@@ -3,6 +3,7 @@ import typing as ta
|
|
|
3
3
|
|
|
4
4
|
from omlish import check
|
|
5
5
|
from omlish import lang
|
|
6
|
+
from omlish.formats import json
|
|
6
7
|
|
|
7
8
|
from .... import minichain as mc
|
|
8
9
|
|
|
@@ -43,11 +44,14 @@ class StringChatSessionPrinter(ChatSessionPrinter, lang.Abstract):
|
|
|
43
44
|
elif isinstance(obj, mc.AiMessage):
|
|
44
45
|
if obj.c is not None:
|
|
45
46
|
self._print_str(check.isinstance(obj.c, str))
|
|
46
|
-
elif isinstance(obj, mc.
|
|
47
|
-
self._print_str(check.isinstance(obj.c, str))
|
|
47
|
+
elif isinstance(obj, mc.ToolUseResultMessage):
|
|
48
|
+
self._print_str(check.isinstance(obj.tur.c, str))
|
|
48
49
|
else:
|
|
49
50
|
raise TypeError(obj)
|
|
50
51
|
|
|
52
|
+
elif isinstance(obj, mc.JsonContent):
|
|
53
|
+
self._print_str(json.dumps_pretty(obj.v))
|
|
54
|
+
|
|
51
55
|
elif isinstance(obj, str):
|
|
52
56
|
self._print_str(obj)
|
|
53
57
|
|
|
@@ -10,7 +10,7 @@ from .base import ChatOptions
|
|
|
10
10
|
from .base import ChatSession
|
|
11
11
|
from .printing import ChatSessionPrinter
|
|
12
12
|
from .state import ChatStateManager
|
|
13
|
-
from .tools import
|
|
13
|
+
from .tools import ToolUseExecutor
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
##
|
|
@@ -42,7 +42,7 @@ class PromptChatSession(ChatSession['PromptChatSession.Config']):
|
|
|
42
42
|
chat_options: ChatOptions | None = None,
|
|
43
43
|
printer: ChatSessionPrinter,
|
|
44
44
|
backend_catalog: mc.BackendCatalog,
|
|
45
|
-
tool_exec_request_executor:
|
|
45
|
+
tool_exec_request_executor: ToolUseExecutor,
|
|
46
46
|
) -> None:
|
|
47
47
|
super().__init__(config)
|
|
48
48
|
|
|
@@ -83,11 +83,10 @@ class PromptChatSession(ChatSession['PromptChatSession.Config']):
|
|
|
83
83
|
lst: list[str] = []
|
|
84
84
|
async for o in st_resp:
|
|
85
85
|
if o:
|
|
86
|
-
|
|
87
|
-
if
|
|
88
|
-
print(check.isinstance(
|
|
89
|
-
lst.append(check.isinstance(
|
|
90
|
-
check.none(m.tool_exec_requests)
|
|
86
|
+
c = check.isinstance(check.single(check.single(o.choices).deltas), mc.ContentAiChoiceDelta).c
|
|
87
|
+
if c is not None:
|
|
88
|
+
print(check.isinstance(c, str), end='', flush=True)
|
|
89
|
+
lst.append(check.isinstance(c, str))
|
|
91
90
|
print()
|
|
92
91
|
|
|
93
92
|
resp_m = mc.AiMessage(''.join(lst))
|
|
@@ -118,33 +117,35 @@ class PromptChatSession(ChatSession['PromptChatSession.Config']):
|
|
|
118
117
|
(self._chat_options or []),
|
|
119
118
|
))
|
|
120
119
|
|
|
121
|
-
resp_m
|
|
122
|
-
|
|
120
|
+
for resp_m in response.v[0].ms:
|
|
121
|
+
new_chat.append(resp_m)
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
if isinstance(resp_m, mc.AiMessage):
|
|
124
|
+
self._printer.print(resp_m)
|
|
126
125
|
|
|
127
|
-
|
|
126
|
+
elif isinstance(resp_m, mc.ToolUseMessage):
|
|
127
|
+
tr: mc.ToolUse = resp_m.tu
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
# FIXME: lol
|
|
130
|
+
from ....minichain.lib.fs.context import FsContext
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
trm = await self._tool_exec_request_executor.execute_tool_use(
|
|
133
|
+
tr,
|
|
134
|
+
FsContext(root_dir=os.getcwd()),
|
|
135
|
+
)
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
print(trm.tur.c)
|
|
138
|
+
new_chat.append(trm)
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
response = await mdl.invoke(mc.ChatChoicesRequest(
|
|
141
|
+
[*state.chat, *new_chat],
|
|
142
|
+
(self._chat_options or []),
|
|
143
|
+
))
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
resp_m = check.isinstance(check.single(response.v[0].ms), mc.AiMessage)
|
|
146
|
+
new_chat.append(resp_m)
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
else:
|
|
149
|
+
raise TypeError(resp_m)
|
|
149
150
|
|
|
150
151
|
self._state_manager.extend_chat(new_chat)
|
|
@@ -3,7 +3,6 @@ import typing as ta
|
|
|
3
3
|
|
|
4
4
|
from omlish import check
|
|
5
5
|
from omlish import lang
|
|
6
|
-
from omlish import marshal as msh
|
|
7
6
|
from omlish.formats import json
|
|
8
7
|
|
|
9
8
|
from .... import minichain as mc
|
|
@@ -24,7 +23,7 @@ class ToolExecutionConfirmation(lang.Abstract):
|
|
|
24
23
|
@abc.abstractmethod
|
|
25
24
|
def confirm_tool_execution_or_raise(
|
|
26
25
|
self,
|
|
27
|
-
tr: mc.
|
|
26
|
+
tr: mc.ToolUse,
|
|
28
27
|
tce: mc.ToolCatalogEntry,
|
|
29
28
|
) -> ta.Awaitable[None]:
|
|
30
29
|
raise NotImplementedError
|
|
@@ -33,7 +32,7 @@ class ToolExecutionConfirmation(lang.Abstract):
|
|
|
33
32
|
class NopToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
34
33
|
async def confirm_tool_execution_or_raise(
|
|
35
34
|
self,
|
|
36
|
-
tr: mc.
|
|
35
|
+
tr: mc.ToolUse,
|
|
37
36
|
tce: mc.ToolCatalogEntry,
|
|
38
37
|
) -> None:
|
|
39
38
|
pass
|
|
@@ -42,14 +41,14 @@ class NopToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
|
42
41
|
class AskingToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
43
42
|
async def confirm_tool_execution_or_raise(
|
|
44
43
|
self,
|
|
45
|
-
tr: mc.
|
|
44
|
+
tr: mc.ToolUse,
|
|
46
45
|
tce: mc.ToolCatalogEntry,
|
|
47
46
|
) -> None:
|
|
48
47
|
tr_dct = dict(
|
|
49
48
|
id=tr.id,
|
|
50
49
|
name=tce.spec.name,
|
|
51
50
|
args=tr.args,
|
|
52
|
-
spec=msh.marshal(tce.spec),
|
|
51
|
+
# spec=msh.marshal(tce.spec),
|
|
53
52
|
)
|
|
54
53
|
cr = await ptk.strict_confirm(f'Execute requested tool?\n\n{json.dumps_pretty(tr_dct)}\n\n')
|
|
55
54
|
|
|
@@ -60,17 +59,17 @@ class AskingToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
|
60
59
|
##
|
|
61
60
|
|
|
62
61
|
|
|
63
|
-
class
|
|
62
|
+
class ToolUseExecutor(lang.Abstract):
|
|
64
63
|
@abc.abstractmethod
|
|
65
|
-
def
|
|
64
|
+
def execute_tool_use(
|
|
66
65
|
self,
|
|
67
|
-
tr: mc.
|
|
66
|
+
tr: mc.ToolUse,
|
|
68
67
|
*ctx_items: ta.Any,
|
|
69
|
-
) -> ta.Awaitable[mc.
|
|
68
|
+
) -> ta.Awaitable[mc.ToolUseResultMessage]:
|
|
70
69
|
raise NotImplementedError
|
|
71
70
|
|
|
72
71
|
|
|
73
|
-
class
|
|
72
|
+
class ToolUseExecutorImpl(ToolUseExecutor):
|
|
74
73
|
def __init__(
|
|
75
74
|
self,
|
|
76
75
|
*,
|
|
@@ -82,16 +81,16 @@ class ToolExecRequestExecutorImpl(ToolExecRequestExecutor):
|
|
|
82
81
|
self._catalog = catalog
|
|
83
82
|
self._confirmation = confirmation
|
|
84
83
|
|
|
85
|
-
async def
|
|
84
|
+
async def execute_tool_use(
|
|
86
85
|
self,
|
|
87
|
-
tr: mc.
|
|
86
|
+
tr: mc.ToolUse,
|
|
88
87
|
*ctx_items: ta.Any,
|
|
89
|
-
) -> mc.
|
|
88
|
+
) -> mc.ToolUseResultMessage:
|
|
90
89
|
tce = self._catalog.by_name[check.non_empty_str(tr.name)]
|
|
91
90
|
|
|
92
91
|
await self._confirmation.confirm_tool_execution_or_raise(tr, tce)
|
|
93
92
|
|
|
94
|
-
return await mc.
|
|
93
|
+
return await mc.execute_tool_use(
|
|
95
94
|
mc.ToolContext(
|
|
96
95
|
tr,
|
|
97
96
|
*ctx_items,
|
ommlds/cli/tools/config.py
CHANGED
ommlds/cli/tools/inject.py
CHANGED
|
@@ -60,10 +60,13 @@ def bind_tools(tools_config: ToolsConfig) -> inj.Elements:
|
|
|
60
60
|
from ...minichain.lib.todo.tools.write import todo_write_tool
|
|
61
61
|
els.append(bind_tool(todo_write_tool()))
|
|
62
62
|
|
|
63
|
-
if tools_config.
|
|
63
|
+
if tools_config.enable_unsafe_tools_do_not_use_lol:
|
|
64
64
|
from ...minichain.lib.bash import bash_tool
|
|
65
65
|
els.append(bind_tool(bash_tool()))
|
|
66
66
|
|
|
67
|
+
from ...minichain.lib.fs.tools.edit import edit_tool
|
|
68
|
+
els.append(bind_tool(edit_tool()))
|
|
69
|
+
|
|
67
70
|
if tools_config.enable_test_weather_tool:
|
|
68
71
|
els.append(bind_tool(WEATHER_TOOL))
|
|
69
72
|
|
ommlds/minichain/__init__.py
CHANGED
|
@@ -107,14 +107,16 @@ with _lang.auto_proxy_init(
|
|
|
107
107
|
ChatChoicesStreamOutput,
|
|
108
108
|
ChatChoicesStreamOutputs,
|
|
109
109
|
|
|
110
|
-
ToolExecRequestDelta,
|
|
111
|
-
AiMessageDelta,
|
|
112
110
|
AiChoiceDelta,
|
|
111
|
+
ContentAiChoiceDelta,
|
|
112
|
+
ToolUseAiChoiceDelta,
|
|
113
|
+
|
|
113
114
|
AiChoiceDeltas,
|
|
115
|
+
AiChoicesDeltas,
|
|
114
116
|
)
|
|
115
117
|
|
|
116
118
|
from .chat.tools.execution import ( # noqa
|
|
117
|
-
|
|
119
|
+
execute_tool_use,
|
|
118
120
|
)
|
|
119
121
|
|
|
120
122
|
from .chat.transforms.base import ( # noqa
|
|
@@ -122,7 +124,6 @@ with _lang.auto_proxy_init(
|
|
|
122
124
|
CompositeMessageTransform,
|
|
123
125
|
FnMessageTransform,
|
|
124
126
|
TypeFilteredMessageTransform,
|
|
125
|
-
fn_message_transform,
|
|
126
127
|
|
|
127
128
|
ChatTransform,
|
|
128
129
|
CompositeChatTransform,
|
|
@@ -153,12 +154,22 @@ with _lang.auto_proxy_init(
|
|
|
153
154
|
)
|
|
154
155
|
|
|
155
156
|
from .chat.messages import ( # noqa
|
|
156
|
-
AiMessage,
|
|
157
|
-
Chat,
|
|
158
157
|
Message,
|
|
158
|
+
Chat,
|
|
159
|
+
|
|
160
|
+
AnyUserMessage,
|
|
161
|
+
UserChat,
|
|
162
|
+
check_user_chat,
|
|
163
|
+
|
|
164
|
+
AnyAiMessage,
|
|
165
|
+
AiChat,
|
|
166
|
+
check_ai_chat,
|
|
167
|
+
|
|
159
168
|
SystemMessage,
|
|
160
|
-
ToolExecResultMessage,
|
|
161
169
|
UserMessage,
|
|
170
|
+
AiMessage,
|
|
171
|
+
ToolUseMessage,
|
|
172
|
+
ToolUseResultMessage,
|
|
162
173
|
)
|
|
163
174
|
|
|
164
175
|
from .chat.services import ( # noqa
|
|
@@ -197,8 +208,14 @@ with _lang.auto_proxy_init(
|
|
|
197
208
|
ImageContent,
|
|
198
209
|
)
|
|
199
210
|
|
|
211
|
+
from .content.json import ( # noqa
|
|
212
|
+
JsonContent,
|
|
213
|
+
)
|
|
214
|
+
|
|
200
215
|
from .content.materialize import ( # noqa
|
|
201
216
|
CanContent,
|
|
217
|
+
|
|
218
|
+
materialize_content,
|
|
202
219
|
)
|
|
203
220
|
|
|
204
221
|
from .content.metadata import ( # noqa
|
|
@@ -401,7 +418,8 @@ with _lang.auto_proxy_init(
|
|
|
401
418
|
|
|
402
419
|
ToolSpec,
|
|
403
420
|
|
|
404
|
-
|
|
421
|
+
ToolUse,
|
|
422
|
+
ToolUseResult,
|
|
405
423
|
)
|
|
406
424
|
|
|
407
425
|
##
|
|
@@ -493,6 +511,12 @@ with _lang.auto_proxy_init(
|
|
|
493
511
|
EnvKey,
|
|
494
512
|
)
|
|
495
513
|
|
|
514
|
+
from .json import ( # noqa
|
|
515
|
+
JsonSchema,
|
|
516
|
+
|
|
517
|
+
JsonValue,
|
|
518
|
+
)
|
|
519
|
+
|
|
496
520
|
from .metadata import ( # noqa
|
|
497
521
|
Metadata,
|
|
498
522
|
|
ommlds/minichain/_marshal.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
from omlish import dataclasses as dc
|
|
2
|
+
from omlish import lang
|
|
2
3
|
from omlish import marshal as msh
|
|
3
4
|
from omlish import reflect as rfl
|
|
4
5
|
from omlish.funcs import match as mfs
|
|
5
6
|
from omlish.typedvalues.marshal import build_typed_values_marshaler
|
|
6
7
|
from omlish.typedvalues.marshal import build_typed_values_unmarshaler
|
|
7
8
|
|
|
9
|
+
from .json import JsonValue
|
|
10
|
+
|
|
8
11
|
|
|
9
12
|
##
|
|
10
13
|
|
|
@@ -25,3 +28,39 @@ class _TypedValuesFieldUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
|
|
|
25
28
|
@mfs.simple(lambda _, ctx, rty: True)
|
|
26
29
|
def _build(self, ctx: msh.UnmarshalContext, rty: rfl.Type) -> msh.Unmarshaler:
|
|
27
30
|
return build_typed_values_unmarshaler(ctx, self.tvs_rty)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class MarshalJsonValue(lang.NotInstantiable, lang.Final):
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _JsonValueMarshalerFactory(msh.MarshalerFactoryMatchClass):
|
|
41
|
+
@mfs.simple(lambda _, ctx, rty: rty is MarshalJsonValue)
|
|
42
|
+
def _build(self, ctx: msh.MarshalContext, rty: rfl.Type) -> msh.Marshaler:
|
|
43
|
+
return msh.NopMarshalerUnmarshaler()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class _JsonValueUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
|
|
47
|
+
@mfs.simple(lambda _, ctx, rty: rty is MarshalJsonValue)
|
|
48
|
+
def _build(self, ctx: msh.UnmarshalContext, rty: rfl.Type) -> msh.Unmarshaler:
|
|
49
|
+
return msh.NopMarshalerUnmarshaler()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@lang.static_init
|
|
56
|
+
def _install_standard_marshaling() -> None:
|
|
57
|
+
msh.register_global_config(
|
|
58
|
+
JsonValue,
|
|
59
|
+
msh.ReflectOverride(MarshalJsonValue),
|
|
60
|
+
identity=True,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
msh.install_standard_factories(
|
|
64
|
+
_JsonValueMarshalerFactory(),
|
|
65
|
+
_JsonValueUnmarshalerFactory(),
|
|
66
|
+
)
|