ommlds 0.0.0.dev463__py3-none-any.whl → 0.0.0.dev465__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 +2 -2
- ommlds/cli/inject.py +14 -32
- ommlds/cli/main.py +34 -59
- ommlds/cli/sessions/{chat2 → chat}/backends/catalog.py +5 -5
- ommlds/cli/sessions/chat/backends/inject.py +37 -0
- ommlds/cli/sessions/chat/backends/injection.py +16 -0
- ommlds/cli/sessions/{chat2 → chat}/backends/types.py +3 -3
- ommlds/cli/sessions/chat/chat/ai/inject.py +78 -0
- ommlds/cli/sessions/chat/chat/ai/injection.py +14 -0
- ommlds/cli/sessions/{chat2 → chat}/chat/ai/rendering.py +13 -10
- ommlds/cli/sessions/chat/chat/ai/services.py +81 -0
- ommlds/cli/sessions/chat/chat/ai/tools.py +44 -0
- ommlds/cli/sessions/{chat2 → chat}/chat/ai/types.py +5 -5
- ommlds/cli/sessions/chat/chat/state/inject.py +40 -0
- ommlds/cli/sessions/{chat2 → chat}/chat/state/inmemory.py +1 -1
- ommlds/cli/sessions/{chat2 → chat}/chat/state/storage.py +2 -2
- ommlds/cli/sessions/{chat2 → chat}/chat/state/types.py +1 -1
- ommlds/cli/sessions/chat/chat/user/inject.py +61 -0
- ommlds/cli/sessions/{chat2 → chat}/chat/user/interactive.py +1 -1
- ommlds/cli/sessions/{chat2 → chat}/chat/user/oneshot.py +1 -1
- ommlds/cli/sessions/{chat2 → chat}/chat/user/types.py +1 -1
- ommlds/cli/sessions/{chat2 → chat}/configs.py +4 -1
- ommlds/cli/sessions/{chat2 → chat}/content/messages.py +6 -2
- ommlds/cli/sessions/{chat2 → chat}/content/strings.py +2 -2
- ommlds/cli/sessions/{chat2 → chat}/driver.py +2 -2
- ommlds/cli/sessions/chat/inject.py +47 -63
- ommlds/cli/sessions/chat/phases/inject.py +27 -0
- ommlds/cli/sessions/chat/phases/injection.py +14 -0
- ommlds/cli/sessions/{chat2/phases.py → chat/phases/manager.py} +2 -28
- ommlds/cli/sessions/chat/phases/types.py +29 -0
- ommlds/cli/sessions/chat/rendering/inject.py +32 -0
- ommlds/cli/sessions/{chat2 → chat}/rendering/markdown.py +2 -2
- ommlds/cli/sessions/{chat2 → chat}/rendering/raw.py +6 -6
- ommlds/cli/sessions/{chat2 → chat}/rendering/types.py +1 -1
- ommlds/cli/sessions/{chat2 → chat}/session.py +1 -1
- ommlds/cli/sessions/{chat2 → chat}/tools/confirmation.py +4 -4
- ommlds/cli/sessions/{chat2 → chat}/tools/execution.py +18 -5
- ommlds/cli/sessions/chat/tools/inject.py +145 -0
- ommlds/cli/sessions/chat/tools/injection.py +29 -0
- ommlds/cli/sessions/chat/tools/rendering.py +58 -0
- ommlds/cli/{tools → sessions/chat/tools}/weather.py +1 -1
- ommlds/cli/sessions/completion/configs.py +21 -0
- ommlds/cli/sessions/completion/inject.py +28 -0
- ommlds/cli/sessions/completion/{completion.py → session.py} +4 -9
- ommlds/cli/sessions/embedding/configs.py +21 -0
- ommlds/cli/sessions/embedding/inject.py +28 -0
- ommlds/cli/sessions/embedding/{embedding.py → session.py} +4 -9
- ommlds/cli/sessions/inject.py +27 -15
- ommlds/cli/state/inject.py +28 -0
- ommlds/minichain/backends/impls/anthropic/chat.py +4 -61
- ommlds/minichain/backends/impls/anthropic/protocol.py +109 -0
- ommlds/minichain/backends/impls/anthropic/stream.py +17 -17
- {ommlds-0.0.0.dev463.dist-info → ommlds-0.0.0.dev465.dist-info}/METADATA +3 -3
- {ommlds-0.0.0.dev463.dist-info → ommlds-0.0.0.dev465.dist-info}/RECORD +69 -60
- ommlds/cli/sessions/chat/base.py +0 -42
- ommlds/cli/sessions/chat/code.py +0 -125
- ommlds/cli/sessions/chat/interactive.py +0 -70
- ommlds/cli/sessions/chat/printing.py +0 -126
- ommlds/cli/sessions/chat/prompt.py +0 -161
- ommlds/cli/sessions/chat/state.py +0 -110
- ommlds/cli/sessions/chat/tools.py +0 -97
- ommlds/cli/sessions/chat2/_inject.py +0 -105
- ommlds/cli/sessions/chat2/chat/ai/services.py +0 -70
- ommlds/cli/sessions/chat2/inject.py +0 -143
- ommlds/cli/tools/config.py +0 -14
- ommlds/cli/tools/inject.py +0 -75
- /ommlds/cli/sessions/{chat2 → chat/backends}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2/backends → chat/chat}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2/chat → chat/chat/ai}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2/chat/ai → chat/chat/state}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2/chat/state → chat/chat/user}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2/chat/user → chat/content}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2/content → chat/phases}/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2 → chat}/rendering/__init__.py +0 -0
- /ommlds/cli/sessions/{chat2 → chat}/tools/__init__.py +0 -0
- /ommlds/cli/{tools → state}/__init__.py +0 -0
- /ommlds/cli/{state.py → state/storage.py} +0 -0
- {ommlds-0.0.0.dev463.dist-info → ommlds-0.0.0.dev465.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev463.dist-info → ommlds-0.0.0.dev465.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev463.dist-info → ommlds-0.0.0.dev465.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev463.dist-info → ommlds-0.0.0.dev465.dist-info}/top_level.txt +0 -0
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import dataclasses as dc
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
from omlish import check
|
|
5
|
-
from omlish import lang
|
|
6
|
-
|
|
7
|
-
from .... import minichain as mc
|
|
8
|
-
from .base import DEFAULT_CHAT_MODEL_BACKEND
|
|
9
|
-
from .base import ChatOptions
|
|
10
|
-
from .base import ChatSession
|
|
11
|
-
from .printing import ChatSessionPrinter
|
|
12
|
-
from .printing import MarkdownStreamPrinter
|
|
13
|
-
from .printing import SimpleStreamPrinter
|
|
14
|
-
from .printing import StreamPrinter
|
|
15
|
-
from .state import ChatStateManager
|
|
16
|
-
from .tools import ToolUseExecutor
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class ToolExecutionRequestDeniedError(Exception):
|
|
23
|
-
pass
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class PromptChatSession(ChatSession['PromptChatSession.Config']):
|
|
27
|
-
@dc.dataclass(frozen=True)
|
|
28
|
-
class Config(ChatSession.Config): # noqa
|
|
29
|
-
content: mc.Content
|
|
30
|
-
|
|
31
|
-
_: dc.KW_ONLY
|
|
32
|
-
|
|
33
|
-
new: bool = False
|
|
34
|
-
|
|
35
|
-
backend: str | None = None
|
|
36
|
-
model_name: str | None = None
|
|
37
|
-
|
|
38
|
-
stream: bool = False
|
|
39
|
-
|
|
40
|
-
def __init__(
|
|
41
|
-
self,
|
|
42
|
-
config: Config,
|
|
43
|
-
*,
|
|
44
|
-
state_manager: ChatStateManager,
|
|
45
|
-
chat_options: ChatOptions | None = None,
|
|
46
|
-
printer: ChatSessionPrinter,
|
|
47
|
-
backend_catalog: mc.BackendCatalog,
|
|
48
|
-
tool_exec_request_executor: ToolUseExecutor,
|
|
49
|
-
) -> None:
|
|
50
|
-
super().__init__(config)
|
|
51
|
-
|
|
52
|
-
self._state_manager = state_manager
|
|
53
|
-
self._chat_options = chat_options
|
|
54
|
-
self._printer = printer
|
|
55
|
-
self._backend_catalog = backend_catalog
|
|
56
|
-
self._tool_exec_request_executor = tool_exec_request_executor
|
|
57
|
-
|
|
58
|
-
async def run(self) -> None:
|
|
59
|
-
if self._config.stream:
|
|
60
|
-
await self._run_stream()
|
|
61
|
-
else:
|
|
62
|
-
await self._run_immediate()
|
|
63
|
-
|
|
64
|
-
async def _run_stream(self) -> None:
|
|
65
|
-
prompt = check.isinstance(self._config.content, str)
|
|
66
|
-
|
|
67
|
-
if self._config.new:
|
|
68
|
-
state = self._state_manager.clear_state()
|
|
69
|
-
else:
|
|
70
|
-
state = self._state_manager.get_state()
|
|
71
|
-
|
|
72
|
-
new_chat: list[mc.Message] = [
|
|
73
|
-
mc.UserMessage(prompt),
|
|
74
|
-
]
|
|
75
|
-
|
|
76
|
-
mdl: mc.ChatChoicesStreamService
|
|
77
|
-
async with lang.async_maybe_managing(self._backend_catalog.get_backend(
|
|
78
|
-
mc.ChatChoicesStreamService,
|
|
79
|
-
self._config.backend or DEFAULT_CHAT_MODEL_BACKEND,
|
|
80
|
-
*([mc.ModelName(mn)] if (mn := self._config.model_name) is not None else []),
|
|
81
|
-
)) as mdl:
|
|
82
|
-
async with (await mdl.invoke(mc.ChatChoicesStreamRequest(
|
|
83
|
-
[*state.chat, *new_chat],
|
|
84
|
-
(self._chat_options or []),
|
|
85
|
-
))).v as st_resp:
|
|
86
|
-
lst: list[str] = []
|
|
87
|
-
|
|
88
|
-
sp_cls: type[StreamPrinter]
|
|
89
|
-
if self._config.markdown:
|
|
90
|
-
sp_cls = MarkdownStreamPrinter
|
|
91
|
-
else:
|
|
92
|
-
sp_cls = SimpleStreamPrinter
|
|
93
|
-
with sp_cls() as sp:
|
|
94
|
-
async for o in st_resp:
|
|
95
|
-
if o:
|
|
96
|
-
c = check.isinstance(check.single(check.single(o.choices).deltas), mc.ContentAiChoiceDelta).c # noqa
|
|
97
|
-
if c is not None:
|
|
98
|
-
s = check.isinstance(c, str)
|
|
99
|
-
sp.feed(s)
|
|
100
|
-
lst.append(s)
|
|
101
|
-
|
|
102
|
-
resp_m = mc.AiMessage(''.join(lst))
|
|
103
|
-
new_chat.append(resp_m)
|
|
104
|
-
|
|
105
|
-
self._state_manager.extend_chat(new_chat)
|
|
106
|
-
|
|
107
|
-
async def _run_immediate(self) -> None:
|
|
108
|
-
prompt = check.isinstance(self._config.content, str)
|
|
109
|
-
|
|
110
|
-
if self._config.new:
|
|
111
|
-
state = self._state_manager.clear_state()
|
|
112
|
-
else:
|
|
113
|
-
state = self._state_manager.get_state()
|
|
114
|
-
|
|
115
|
-
new_chat: list[mc.Message] = [
|
|
116
|
-
mc.UserMessage(prompt),
|
|
117
|
-
]
|
|
118
|
-
|
|
119
|
-
mdl: mc.ChatChoicesService
|
|
120
|
-
async with lang.async_maybe_managing(self._backend_catalog.get_backend(
|
|
121
|
-
mc.ChatChoicesService,
|
|
122
|
-
self._config.backend or DEFAULT_CHAT_MODEL_BACKEND,
|
|
123
|
-
*([mc.ModelName(mn)] if (mn := self._config.model_name) is not None else []),
|
|
124
|
-
)) as mdl:
|
|
125
|
-
response: mc.ChatChoicesResponse = await mdl.invoke(mc.ChatChoicesRequest(
|
|
126
|
-
[*state.chat, *new_chat],
|
|
127
|
-
(self._chat_options or []),
|
|
128
|
-
))
|
|
129
|
-
|
|
130
|
-
for resp_m in response.v[0].ms:
|
|
131
|
-
new_chat.append(resp_m)
|
|
132
|
-
|
|
133
|
-
if isinstance(resp_m, mc.AiMessage):
|
|
134
|
-
self._printer.print(resp_m)
|
|
135
|
-
|
|
136
|
-
elif isinstance(resp_m, mc.ToolUseMessage):
|
|
137
|
-
tr: mc.ToolUse = resp_m.tu
|
|
138
|
-
|
|
139
|
-
# FIXME: lol
|
|
140
|
-
from ....minichain.lib.fs.context import FsContext
|
|
141
|
-
|
|
142
|
-
trm = await self._tool_exec_request_executor.execute_tool_use(
|
|
143
|
-
tr,
|
|
144
|
-
FsContext(root_dir=os.getcwd()),
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
print(trm.tur.c)
|
|
148
|
-
new_chat.append(trm)
|
|
149
|
-
|
|
150
|
-
response = await mdl.invoke(mc.ChatChoicesRequest(
|
|
151
|
-
[*state.chat, *new_chat],
|
|
152
|
-
(self._chat_options or []),
|
|
153
|
-
))
|
|
154
|
-
|
|
155
|
-
resp_m = check.isinstance(check.single(response.v[0].ms), mc.AiMessage)
|
|
156
|
-
new_chat.append(resp_m)
|
|
157
|
-
|
|
158
|
-
else:
|
|
159
|
-
raise TypeError(resp_m)
|
|
160
|
-
|
|
161
|
-
self._state_manager.extend_chat(new_chat)
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import abc
|
|
2
|
-
import dataclasses as dc
|
|
3
|
-
import datetime
|
|
4
|
-
|
|
5
|
-
from omlish import check
|
|
6
|
-
from omlish import lang
|
|
7
|
-
|
|
8
|
-
from .... import minichain as mc
|
|
9
|
-
from ...state import StateStorage
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@dc.dataclass(frozen=True)
|
|
16
|
-
class ChatState:
|
|
17
|
-
name: str | None = None
|
|
18
|
-
|
|
19
|
-
created_at: datetime.datetime = dc.field(default_factory=lang.utcnow)
|
|
20
|
-
updated_at: datetime.datetime = dc.field(default_factory=lang.utcnow)
|
|
21
|
-
|
|
22
|
-
chat: mc.Chat = ()
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
##
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class ChatStateManager(lang.Abstract):
|
|
29
|
-
@abc.abstractmethod
|
|
30
|
-
def get_state(self) -> ChatState:
|
|
31
|
-
raise NotImplementedError
|
|
32
|
-
|
|
33
|
-
@abc.abstractmethod
|
|
34
|
-
def clear_state(self) -> ChatState:
|
|
35
|
-
raise NotImplementedError
|
|
36
|
-
|
|
37
|
-
@abc.abstractmethod
|
|
38
|
-
def extend_chat(self, chat_additions: mc.Chat) -> ChatState:
|
|
39
|
-
raise NotImplementedError
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
##
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class InMemoryChatStateManager(ChatStateManager):
|
|
46
|
-
def __init__(self, initial_state: ChatState | None = None) -> None:
|
|
47
|
-
super().__init__()
|
|
48
|
-
|
|
49
|
-
if initial_state is None:
|
|
50
|
-
initial_state = ChatState()
|
|
51
|
-
self._state = initial_state
|
|
52
|
-
|
|
53
|
-
def get_state(self) -> ChatState:
|
|
54
|
-
return self._state
|
|
55
|
-
|
|
56
|
-
def clear_state(self) -> ChatState:
|
|
57
|
-
self._state = ChatState()
|
|
58
|
-
return self._state
|
|
59
|
-
|
|
60
|
-
def extend_chat(self, chat_additions: mc.Chat) -> ChatState:
|
|
61
|
-
self._state = dc.replace(
|
|
62
|
-
self._state,
|
|
63
|
-
chat=[*self._state.chat, *chat_additions],
|
|
64
|
-
updated_at=lang.utcnow(),
|
|
65
|
-
)
|
|
66
|
-
return self._state
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
##
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
class StateStorageChatStateManager(ChatStateManager):
|
|
73
|
-
def __init__(
|
|
74
|
-
self,
|
|
75
|
-
*,
|
|
76
|
-
storage: StateStorage,
|
|
77
|
-
key: str = 'chat',
|
|
78
|
-
) -> None:
|
|
79
|
-
super().__init__()
|
|
80
|
-
|
|
81
|
-
self._storage = storage
|
|
82
|
-
self._key = check.non_empty_str(key)
|
|
83
|
-
|
|
84
|
-
self._state: ChatState | None = None
|
|
85
|
-
|
|
86
|
-
def get_state(self) -> ChatState:
|
|
87
|
-
if self._state is not None:
|
|
88
|
-
return self._state
|
|
89
|
-
state: ChatState | None = lang.sync_await(self._storage.load_state(self._key, ChatState))
|
|
90
|
-
if state is None:
|
|
91
|
-
state = ChatState()
|
|
92
|
-
self._state = state
|
|
93
|
-
return state
|
|
94
|
-
|
|
95
|
-
def clear_state(self) -> ChatState:
|
|
96
|
-
state = ChatState()
|
|
97
|
-
lang.sync_await(self._storage.save_state(self._key, state, ChatState))
|
|
98
|
-
self._state = state
|
|
99
|
-
return state
|
|
100
|
-
|
|
101
|
-
def extend_chat(self, chat_additions: mc.Chat) -> ChatState:
|
|
102
|
-
state = self.get_state()
|
|
103
|
-
state = dc.replace(
|
|
104
|
-
state,
|
|
105
|
-
chat=[*state.chat, *chat_additions],
|
|
106
|
-
updated_at=lang.utcnow(),
|
|
107
|
-
)
|
|
108
|
-
lang.sync_await(self._storage.save_state(self._key, state, ChatState))
|
|
109
|
-
self._state = state
|
|
110
|
-
return state
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import abc
|
|
2
|
-
import typing as ta
|
|
3
|
-
|
|
4
|
-
from omlish import check
|
|
5
|
-
from omlish import lang
|
|
6
|
-
from omlish.formats import json
|
|
7
|
-
from omlish.term.confirm import confirm_action
|
|
8
|
-
|
|
9
|
-
from .... import minichain as mc
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ToolExecutionRequestDeniedError(Exception):
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ToolExecutionConfirmation(lang.Abstract):
|
|
20
|
-
@abc.abstractmethod
|
|
21
|
-
def confirm_tool_execution_or_raise(
|
|
22
|
-
self,
|
|
23
|
-
tr: mc.ToolUse,
|
|
24
|
-
tce: mc.ToolCatalogEntry,
|
|
25
|
-
) -> ta.Awaitable[None]:
|
|
26
|
-
raise NotImplementedError
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class NopToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
30
|
-
async def confirm_tool_execution_or_raise(
|
|
31
|
-
self,
|
|
32
|
-
tr: mc.ToolUse,
|
|
33
|
-
tce: mc.ToolCatalogEntry,
|
|
34
|
-
) -> None:
|
|
35
|
-
pass
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class AskingToolExecutionConfirmation(ToolExecutionConfirmation):
|
|
39
|
-
async def confirm_tool_execution_or_raise(
|
|
40
|
-
self,
|
|
41
|
-
tr: mc.ToolUse,
|
|
42
|
-
tce: mc.ToolCatalogEntry,
|
|
43
|
-
) -> None:
|
|
44
|
-
tr_dct = dict(
|
|
45
|
-
id=tr.id,
|
|
46
|
-
name=tce.spec.name,
|
|
47
|
-
args=tr.args,
|
|
48
|
-
# spec=msh.marshal(tce.spec),
|
|
49
|
-
)
|
|
50
|
-
cr = confirm_action(f'Execute requested tool?\n\n{json.dumps_pretty(tr_dct)}') # FIXME: async lol
|
|
51
|
-
|
|
52
|
-
if not cr:
|
|
53
|
-
raise ToolExecutionRequestDeniedError
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
##
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class ToolUseExecutor(lang.Abstract):
|
|
60
|
-
@abc.abstractmethod
|
|
61
|
-
def execute_tool_use(
|
|
62
|
-
self,
|
|
63
|
-
tr: mc.ToolUse,
|
|
64
|
-
*ctx_items: ta.Any,
|
|
65
|
-
) -> ta.Awaitable[mc.ToolUseResultMessage]:
|
|
66
|
-
raise NotImplementedError
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class ToolUseExecutorImpl(ToolUseExecutor):
|
|
70
|
-
def __init__(
|
|
71
|
-
self,
|
|
72
|
-
*,
|
|
73
|
-
catalog: mc.ToolCatalog,
|
|
74
|
-
confirmation: ToolExecutionConfirmation,
|
|
75
|
-
) -> None:
|
|
76
|
-
super().__init__()
|
|
77
|
-
|
|
78
|
-
self._catalog = catalog
|
|
79
|
-
self._confirmation = confirmation
|
|
80
|
-
|
|
81
|
-
async def execute_tool_use(
|
|
82
|
-
self,
|
|
83
|
-
tr: mc.ToolUse,
|
|
84
|
-
*ctx_items: ta.Any,
|
|
85
|
-
) -> mc.ToolUseResultMessage:
|
|
86
|
-
tce = self._catalog.by_name[check.non_empty_str(tr.name)]
|
|
87
|
-
|
|
88
|
-
await self._confirmation.confirm_tool_execution_or_raise(tr, tce)
|
|
89
|
-
|
|
90
|
-
return await mc.execute_tool_use(
|
|
91
|
-
mc.ToolContext(
|
|
92
|
-
tr,
|
|
93
|
-
*ctx_items,
|
|
94
|
-
),
|
|
95
|
-
tce.executor(),
|
|
96
|
-
tr,
|
|
97
|
-
)
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
from omlish import lang
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
with lang.auto_proxy_init(globals()):
|
|
5
|
-
from .backends.catalog import ( # noqa
|
|
6
|
-
CatalogChatChoicesServiceBackendProvider,
|
|
7
|
-
CatalogChatChoicesStreamServiceBackendProvider,
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
from .backends.types import ( # noqa
|
|
11
|
-
BackendName,
|
|
12
|
-
BackendConfigs,
|
|
13
|
-
BackendProvider,
|
|
14
|
-
ChatChoicesServiceBackendProvider,
|
|
15
|
-
ChatChoicesStreamServiceBackendProvider,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
from .chat.ai.rendering import ( # noqa
|
|
19
|
-
RenderingAiChatGenerator,
|
|
20
|
-
RenderingStreamAiChatGenerator,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
from .chat.ai.services import ( # noqa
|
|
24
|
-
ChatChoicesServiceOptions,
|
|
25
|
-
ChatChoicesServiceAiChatGenerator,
|
|
26
|
-
ChatChoicesStreamServiceStreamAiChatGenerator,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
from .chat.ai.types import ( # noqa
|
|
30
|
-
AiChatGenerator,
|
|
31
|
-
StreamAiChatGenerator,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
from .chat.state.inmemory import ( # noqa
|
|
35
|
-
InMemoryChatStateManager,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
from .chat.state.storage import ( # noqa
|
|
39
|
-
StateStorageChatStateManager,
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
from .chat.state.types import ( # noqa
|
|
43
|
-
ChatState,
|
|
44
|
-
ChatStateManager,
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
from .chat.user.interactive import ( # noqa
|
|
48
|
-
InteractiveUserChatInput,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
from .chat.user.oneshot import ( # noqa
|
|
52
|
-
OneshotUserChatInputInitialChat,
|
|
53
|
-
OneshotUserChatInput,
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
from .chat.user.types import ( # noqa
|
|
57
|
-
UserChatInput,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
from .content.messages import ( # noqa
|
|
61
|
-
MessageContentExtractor,
|
|
62
|
-
MessageContentExtractorImpl,
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
from .content.strings import ( # noqa
|
|
66
|
-
ContentStringifier,
|
|
67
|
-
ContentStringifierImpl,
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
from .rendering.markdown import ( # noqa
|
|
71
|
-
MarkdownContentRendering,
|
|
72
|
-
MarkdownStreamContentRendering,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
from .rendering.raw import ( # noqa
|
|
76
|
-
RawContentRendering,
|
|
77
|
-
RawContentStreamRendering,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
from .rendering.types import ( # noqa
|
|
81
|
-
ContentRendering,
|
|
82
|
-
StreamContentRendering,
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
from .tools.confirmation import ( # noqa
|
|
86
|
-
ToolExecutionRequestDeniedError,
|
|
87
|
-
ToolExecutionConfirmation,
|
|
88
|
-
InteractiveToolExecutionConfirmation,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
from .tools.execution import ( # noqa
|
|
92
|
-
ToolUseExecutor,
|
|
93
|
-
ToolUseExecutorImpl,
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
from .driver import ( # noqa
|
|
97
|
-
ChatDriver,
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
from .phases import ( # noqa
|
|
101
|
-
ChatPhase,
|
|
102
|
-
ChatPhaseCallback,
|
|
103
|
-
ChatPhaseCallbacks,
|
|
104
|
-
ChatPhaseManager,
|
|
105
|
-
)
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import check
|
|
4
|
-
|
|
5
|
-
from ...... import minichain as mc
|
|
6
|
-
from ...backends.types import ChatChoicesServiceBackendProvider
|
|
7
|
-
from .types import AiChatGenerator
|
|
8
|
-
from .types import StreamAiChatGenerator
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ChatChoicesServiceOptions = ta.NewType('ChatChoicesServiceOptions', ta.Sequence[mc.ChatChoicesOptions])
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class ChatChoicesServiceAiChatGenerator(AiChatGenerator):
|
|
21
|
-
def __init__(
|
|
22
|
-
self,
|
|
23
|
-
service_provider: ChatChoicesServiceBackendProvider,
|
|
24
|
-
*,
|
|
25
|
-
options: ChatChoicesServiceOptions | None = None,
|
|
26
|
-
) -> None:
|
|
27
|
-
super().__init__()
|
|
28
|
-
|
|
29
|
-
self._service_provider = service_provider
|
|
30
|
-
self._options = options
|
|
31
|
-
|
|
32
|
-
async def get_next_ai_messages(self, chat: mc.Chat) -> mc.AiChat:
|
|
33
|
-
async with self._service_provider.provide_backend() as service:
|
|
34
|
-
resp = await service.invoke(mc.ChatChoicesRequest(chat, self._options or []))
|
|
35
|
-
|
|
36
|
-
return check.single(resp.v).ms
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class ChatChoicesStreamServiceStreamAiChatGenerator(StreamAiChatGenerator):
|
|
40
|
-
def __init__(
|
|
41
|
-
self,
|
|
42
|
-
service: mc.ChatChoicesStreamService,
|
|
43
|
-
*,
|
|
44
|
-
options: ChatChoicesServiceOptions | None = None,
|
|
45
|
-
) -> None:
|
|
46
|
-
super().__init__()
|
|
47
|
-
|
|
48
|
-
self._service = service
|
|
49
|
-
self._options = options
|
|
50
|
-
|
|
51
|
-
async def get_next_ai_messages_streamed(
|
|
52
|
-
self,
|
|
53
|
-
chat: mc.Chat,
|
|
54
|
-
delta_callback: ta.Callable[[mc.AiChoiceDelta], ta.Awaitable[None]] | None = None,
|
|
55
|
-
) -> mc.AiChat:
|
|
56
|
-
lst: list[str] = []
|
|
57
|
-
|
|
58
|
-
async with (await self._service.invoke(mc.ChatChoicesStreamRequest(chat, self._options or []))).v as st_resp:
|
|
59
|
-
async for o in st_resp:
|
|
60
|
-
choice = check.single(o.choices)
|
|
61
|
-
|
|
62
|
-
for delta in choice.deltas:
|
|
63
|
-
if delta_callback is not None:
|
|
64
|
-
await delta_callback(delta)
|
|
65
|
-
|
|
66
|
-
c = check.isinstance(delta, mc.ContentAiChoiceDelta).c # noqa
|
|
67
|
-
if c is not None:
|
|
68
|
-
lst.append(check.isinstance(c, str))
|
|
69
|
-
|
|
70
|
-
return [mc.AiMessage(''.join(lst))]
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
|
-
from omlish import inject as inj
|
|
4
|
-
from omlish import lang
|
|
5
|
-
|
|
6
|
-
from .... import minichain as mc
|
|
7
|
-
from . import _inject as _inj
|
|
8
|
-
from .configs import DEFAULT_CHAT_MODEL_BACKEND
|
|
9
|
-
from .configs import ChatConfig
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ItemT = ta.TypeVar('ItemT')
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
CHAT_OPTIONS = inj.items_binder_helper[mc.ChatChoicesOption](_inj.ChatChoicesServiceOptions)
|
|
19
|
-
BACKEND_CONFIGS = inj.items_binder_helper[mc.Config](_inj.BackendConfigs)
|
|
20
|
-
PHASE_CALLBACKS = inj.items_binder_helper[_inj.ChatPhaseCallback](_inj.ChatPhaseCallbacks)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def bind_chat(cfg: ChatConfig) -> inj.Elements:
|
|
27
|
-
els: list[inj.Elemental] = []
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
els.extend([
|
|
32
|
-
CHAT_OPTIONS.bind_items_provider(singleton=True),
|
|
33
|
-
BACKEND_CONFIGS.bind_items_provider(singleton=True),
|
|
34
|
-
PHASE_CALLBACKS.bind_items_provider(singleton=True),
|
|
35
|
-
])
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
if cfg.state in ('continue', 'new'):
|
|
40
|
-
els.extend([
|
|
41
|
-
inj.bind(_inj.StateStorageChatStateManager, singleton=True),
|
|
42
|
-
inj.bind(_inj.ChatStateManager, to_key=_inj.StateStorageChatStateManager),
|
|
43
|
-
])
|
|
44
|
-
|
|
45
|
-
if cfg.state == 'new':
|
|
46
|
-
els.append(PHASE_CALLBACKS.bind_item(to_fn=lang.typed_lambda(cm=_inj.ChatStateManager)(
|
|
47
|
-
lambda cm: _inj.ChatPhaseCallback(_inj.ChatPhase.STARTING, cm.clear_state),
|
|
48
|
-
)))
|
|
49
|
-
|
|
50
|
-
elif cfg.state == 'ephemeral':
|
|
51
|
-
els.extend([
|
|
52
|
-
inj.bind(_inj.InMemoryChatStateManager, singleton=True),
|
|
53
|
-
inj.bind(_inj.ChatStateManager, to_key=_inj.InMemoryChatStateManager),
|
|
54
|
-
])
|
|
55
|
-
|
|
56
|
-
else:
|
|
57
|
-
raise TypeError(cfg.state)
|
|
58
|
-
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
if cfg.interactive:
|
|
62
|
-
if cfg.initial_content is not None:
|
|
63
|
-
async def add_initial_content(cm: '_inj.ChatStateManager') -> None:
|
|
64
|
-
await cm.extend_chat([mc.UserMessage(cfg.initial_content)])
|
|
65
|
-
|
|
66
|
-
els.append(PHASE_CALLBACKS.bind_item(to_fn=lang.typed_lambda(cm=_inj.ChatStateManager)(
|
|
67
|
-
lambda cm: _inj.ChatPhaseCallback(_inj.ChatPhase.STARTED, lambda: add_initial_content(cm)),
|
|
68
|
-
)))
|
|
69
|
-
|
|
70
|
-
raise NotImplementedError
|
|
71
|
-
|
|
72
|
-
els.extend([
|
|
73
|
-
inj.bind(_inj.InteractiveUserChatInput, singleton=True),
|
|
74
|
-
inj.bind(_inj.UserChatInput, to_key=_inj.InteractiveUserChatInput),
|
|
75
|
-
])
|
|
76
|
-
|
|
77
|
-
else:
|
|
78
|
-
if cfg.initial_content is None:
|
|
79
|
-
raise ValueError('Initial content is required for non-interactive chat')
|
|
80
|
-
|
|
81
|
-
els.extend([
|
|
82
|
-
inj.bind(_inj.OneshotUserChatInputInitialChat, to_const=[mc.UserMessage(cfg.initial_content)]),
|
|
83
|
-
inj.bind(_inj.OneshotUserChatInput, singleton=True),
|
|
84
|
-
inj.bind(_inj.UserChatInput, to_key=_inj.OneshotUserChatInput),
|
|
85
|
-
])
|
|
86
|
-
|
|
87
|
-
#
|
|
88
|
-
|
|
89
|
-
if cfg.stream:
|
|
90
|
-
raise NotImplementedError
|
|
91
|
-
|
|
92
|
-
else:
|
|
93
|
-
ai_stack = inj.wrapper_binder_helper(_inj.AiChatGenerator)
|
|
94
|
-
|
|
95
|
-
els.append(ai_stack.push_bind(to_ctor=_inj.ChatChoicesServiceAiChatGenerator, singleton=True))
|
|
96
|
-
|
|
97
|
-
if not cfg.silent:
|
|
98
|
-
if cfg.markdown:
|
|
99
|
-
els.extend([
|
|
100
|
-
inj.bind(_inj.MarkdownContentRendering, singleton=True),
|
|
101
|
-
inj.bind(_inj.ContentRendering, to_key=_inj.MarkdownContentRendering),
|
|
102
|
-
])
|
|
103
|
-
else:
|
|
104
|
-
els.extend([
|
|
105
|
-
inj.bind(_inj.RawContentRendering, singleton=True),
|
|
106
|
-
inj.bind(_inj.ContentRendering, to_key=_inj.RawContentRendering),
|
|
107
|
-
])
|
|
108
|
-
|
|
109
|
-
els.append(ai_stack.push_bind(to_ctor=_inj.RenderingAiChatGenerator, singleton=True))
|
|
110
|
-
|
|
111
|
-
els.append(inj.bind(_inj.AiChatGenerator, to_key=ai_stack.top))
|
|
112
|
-
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
els.append(inj.bind(_inj.BackendName, to_const=cfg.backend or DEFAULT_CHAT_MODEL_BACKEND))
|
|
116
|
-
|
|
117
|
-
els.extend([
|
|
118
|
-
inj.bind(_inj.CatalogChatChoicesServiceBackendProvider),
|
|
119
|
-
inj.bind(_inj.ChatChoicesServiceBackendProvider, to_key=_inj.CatalogChatChoicesServiceBackendProvider),
|
|
120
|
-
])
|
|
121
|
-
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
els.extend([
|
|
125
|
-
inj.bind(_inj.ToolUseExecutorImpl, singleton=True),
|
|
126
|
-
inj.bind(_inj.ToolUseExecutor, to_key=_inj.ToolUseExecutorImpl),
|
|
127
|
-
])
|
|
128
|
-
|
|
129
|
-
#
|
|
130
|
-
|
|
131
|
-
els.extend([
|
|
132
|
-
inj.bind(_inj.ChatPhaseManager, singleton=True),
|
|
133
|
-
])
|
|
134
|
-
|
|
135
|
-
#
|
|
136
|
-
|
|
137
|
-
els.extend([
|
|
138
|
-
inj.bind(_inj.ChatDriver, singleton=True),
|
|
139
|
-
])
|
|
140
|
-
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
return inj.as_elements(*els)
|
ommlds/cli/tools/config.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
from omlish import dataclasses as dc
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
##
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@dc.dataclass(frozen=True, kw_only=True)
|
|
8
|
-
class ToolsConfig:
|
|
9
|
-
enable_fs_tools: bool = False
|
|
10
|
-
enable_todo_tools: bool = False
|
|
11
|
-
|
|
12
|
-
enable_unsafe_tools_do_not_use_lol: bool = False
|
|
13
|
-
|
|
14
|
-
enable_test_weather_tool: bool = False
|