ommlds 0.0.0.dev475__py3-none-any.whl → 0.0.0.dev477__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 +85 -1
- ommlds/__about__.py +1 -1
- ommlds/backends/groq/_marshal.py +23 -0
- ommlds/backends/groq/protocol.py +249 -0
- ommlds/cli/{sessions/chat/backends → backends}/catalog.py +35 -3
- ommlds/cli/backends/configs.py +9 -0
- ommlds/cli/backends/inject.py +31 -36
- ommlds/cli/{sessions/chat/backends → backends}/injection.py +1 -1
- ommlds/cli/{sessions/chat/backends → backends}/types.py +11 -1
- ommlds/cli/{sessions/chat/content → content}/messages.py +1 -1
- ommlds/cli/{sessions/chat/content → content}/strings.py +1 -1
- ommlds/cli/inject.py +0 -6
- ommlds/cli/inputs/asyncs.py +32 -0
- ommlds/cli/{sessions/chat/chat/user/inputs.py → inputs/sync.py} +0 -30
- ommlds/cli/main.py +267 -113
- ommlds/cli/rendering/__init__.py +0 -0
- ommlds/cli/rendering/configs.py +9 -0
- ommlds/cli/{sessions/chat/rendering → rendering}/inject.py +4 -5
- ommlds/cli/{sessions/chat/rendering → rendering}/markdown.py +1 -1
- ommlds/cli/{sessions/chat/rendering → rendering}/raw.py +1 -1
- ommlds/cli/{sessions/chat/rendering → rendering}/types.py +1 -1
- ommlds/cli/secrets.py +21 -0
- ommlds/cli/sessions/base.py +1 -1
- ommlds/cli/sessions/chat/chat/ai/configs.py +11 -0
- ommlds/cli/sessions/chat/chat/ai/inject.py +7 -11
- ommlds/cli/sessions/chat/chat/ai/rendering.py +4 -4
- ommlds/cli/sessions/chat/chat/ai/services.py +2 -2
- ommlds/cli/sessions/chat/chat/state/configs.py +11 -0
- ommlds/cli/sessions/chat/chat/state/inject.py +6 -10
- ommlds/cli/sessions/chat/chat/state/inmemory.py +1 -2
- ommlds/cli/sessions/chat/chat/state/storage.py +1 -2
- ommlds/cli/sessions/chat/chat/state/types.py +1 -1
- ommlds/cli/sessions/chat/chat/user/configs.py +17 -0
- ommlds/cli/sessions/chat/chat/user/inject.py +13 -19
- ommlds/cli/sessions/chat/chat/user/interactive.py +3 -3
- ommlds/cli/sessions/chat/configs.py +15 -26
- ommlds/cli/sessions/chat/inject.py +18 -35
- ommlds/cli/sessions/chat/session.py +1 -1
- ommlds/cli/sessions/chat/tools/configs.py +22 -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 +17 -74
- ommlds/cli/sessions/chat/tools/injection.py +15 -0
- ommlds/cli/sessions/chat/tools/rendering.py +1 -1
- 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/sessions/chat/tools/{weather.py → weather/tools.py} +1 -1
- ommlds/cli/sessions/completion/configs.py +2 -2
- ommlds/cli/sessions/completion/inject.py +14 -0
- ommlds/cli/sessions/completion/session.py +7 -11
- ommlds/cli/sessions/embedding/configs.py +2 -2
- ommlds/cli/sessions/embedding/inject.py +14 -0
- ommlds/cli/sessions/embedding/session.py +7 -11
- ommlds/cli/state/storage.py +1 -1
- ommlds/minichain/backends/catalogs/strings.py +1 -1
- 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/openai/chat.py +3 -3
- ommlds/minichain/backends/impls/openai/names.py +27 -3
- ommlds/minichain/backends/impls/openai/stream.py +2 -2
- ommlds/minichain/chat/stream/joining.py +1 -0
- ommlds/minichain/tools/reflect.py +5 -1
- ommlds/wiki/utils/xml.py +5 -5
- {ommlds-0.0.0.dev475.dist-info → ommlds-0.0.0.dev477.dist-info}/METADATA +5 -5
- {ommlds-0.0.0.dev475.dist-info → ommlds-0.0.0.dev477.dist-info}/RECORD +80 -58
- ommlds/cli/backends/standard.py +0 -20
- ommlds/cli/main2.py +0 -220
- ommlds/cli/sessions/chat/backends/inject.py +0 -53
- /ommlds/{cli/sessions/chat/backends → backends/groq}/__init__.py +0 -0
- /ommlds/cli/{sessions/chat/content → content}/__init__.py +0 -0
- /ommlds/cli/{sessions/chat/rendering → inputs}/__init__.py +0 -0
- {ommlds-0.0.0.dev475.dist-info → ommlds-0.0.0.dev477.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev475.dist-info → ommlds-0.0.0.dev477.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev475.dist-info → ommlds-0.0.0.dev477.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev475.dist-info → ommlds-0.0.0.dev477.dist-info}/top_level.txt +0 -0
|
@@ -2,6 +2,7 @@ from omlish import inject as inj
|
|
|
2
2
|
from omlish import lang
|
|
3
3
|
|
|
4
4
|
from ...... import minichain as mc
|
|
5
|
+
from .configs import AiConfig
|
|
5
6
|
from .injection import chat_options_providers
|
|
6
7
|
|
|
7
8
|
|
|
@@ -15,12 +16,7 @@ with lang.auto_proxy_import(globals()):
|
|
|
15
16
|
##
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def bind_ai(
|
|
19
|
-
*,
|
|
20
|
-
stream: bool = False,
|
|
21
|
-
silent: bool = False,
|
|
22
|
-
enable_tools: bool = False,
|
|
23
|
-
) -> inj.Elements:
|
|
19
|
+
def bind_ai(cfg: AiConfig = AiConfig()) -> inj.Elements:
|
|
24
20
|
els: list[inj.Elemental] = []
|
|
25
21
|
|
|
26
22
|
#
|
|
@@ -38,12 +34,12 @@ def bind_ai(
|
|
|
38
34
|
|
|
39
35
|
ai_stack = inj.wrapper_binder_helper(_types.AiChatGenerator)
|
|
40
36
|
|
|
41
|
-
if stream:
|
|
37
|
+
if cfg.stream:
|
|
42
38
|
stream_ai_stack = inj.wrapper_binder_helper(_types.StreamAiChatGenerator)
|
|
43
39
|
|
|
44
40
|
els.append(stream_ai_stack.push_bind(to_ctor=_services.ChatChoicesStreamServiceStreamAiChatGenerator, singleton=True)) # noqa
|
|
45
41
|
|
|
46
|
-
if not silent:
|
|
42
|
+
if not cfg.silent:
|
|
47
43
|
els.append(stream_ai_stack.push_bind(to_ctor=_rendering.RenderingStreamAiChatGenerator, singleton=True))
|
|
48
44
|
|
|
49
45
|
els.extend([
|
|
@@ -54,17 +50,17 @@ def bind_ai(
|
|
|
54
50
|
else:
|
|
55
51
|
els.append(ai_stack.push_bind(to_ctor=_services.ChatChoicesServiceAiChatGenerator, singleton=True))
|
|
56
52
|
|
|
57
|
-
if not silent:
|
|
53
|
+
if not cfg.silent:
|
|
58
54
|
els.append(ai_stack.push_bind(to_ctor=_rendering.RenderingAiChatGenerator, singleton=True))
|
|
59
55
|
|
|
60
|
-
if enable_tools:
|
|
56
|
+
if cfg.enable_tools:
|
|
61
57
|
els.append(ai_stack.push_bind(to_ctor=_tools.ToolExecutingAiChatGenerator, singleton=True))
|
|
62
58
|
|
|
63
59
|
els.append(inj.bind(_types.AiChatGenerator, to_key=ai_stack.top))
|
|
64
60
|
|
|
65
61
|
#
|
|
66
62
|
|
|
67
|
-
if enable_tools:
|
|
63
|
+
if cfg.enable_tools:
|
|
68
64
|
def _provide_tools_chat_choices_options_provider(tc: mc.ToolCatalog) -> _services.ChatChoicesServiceOptionsProvider: # noqa
|
|
69
65
|
return _services.ChatChoicesServiceOptionsProvider(lambda: [
|
|
70
66
|
mc.Tool(tce.spec)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import typing as ta
|
|
2
2
|
|
|
3
3
|
from ...... import minichain as mc
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
4
|
+
from .....content.messages import MessageContentExtractor
|
|
5
|
+
from .....content.messages import MessageContentExtractorImpl
|
|
6
|
+
from .....rendering.types import ContentRendering
|
|
7
|
+
from .....rendering.types import StreamContentRendering
|
|
8
8
|
from .types import AiChatGenerator
|
|
9
9
|
from .types import StreamAiChatGenerator
|
|
10
10
|
|
|
@@ -4,8 +4,8 @@ from omlish import check
|
|
|
4
4
|
from omlish import lang
|
|
5
5
|
|
|
6
6
|
from ...... import minichain as mc
|
|
7
|
-
from
|
|
8
|
-
from
|
|
7
|
+
from .....backends.types import ChatChoicesServiceBackendProvider
|
|
8
|
+
from .....backends.types import ChatChoicesStreamServiceBackendProvider
|
|
9
9
|
from .types import AiChatGenerator
|
|
10
10
|
from .types import StreamAiChatGenerator
|
|
11
11
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
1
|
from omlish import inject as inj
|
|
4
2
|
from omlish import lang
|
|
5
3
|
|
|
6
4
|
from ...phases.injection import phase_callbacks
|
|
7
5
|
from ...phases.types import ChatPhase
|
|
8
6
|
from ...phases.types import ChatPhaseCallback
|
|
7
|
+
from .configs import StateConfig
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
with lang.auto_proxy_import(globals()):
|
|
@@ -17,24 +16,21 @@ with lang.auto_proxy_import(globals()):
|
|
|
17
16
|
##
|
|
18
17
|
|
|
19
18
|
|
|
20
|
-
def bind_state(
|
|
21
|
-
*,
|
|
22
|
-
state: ta.Literal['new', 'continue', 'ephemeral'] = 'continue',
|
|
23
|
-
) -> inj.Elements:
|
|
19
|
+
def bind_state(cfg: StateConfig = StateConfig()) -> inj.Elements:
|
|
24
20
|
els: list[inj.Elemental] = []
|
|
25
21
|
|
|
26
|
-
if state in ('continue', 'new'):
|
|
22
|
+
if cfg.state in ('continue', 'new'):
|
|
27
23
|
els.append(inj.bind(_types.ChatStateManager, to_ctor=_storage.StateStorageChatStateManager, singleton=True))
|
|
28
24
|
|
|
29
|
-
if state == 'new':
|
|
25
|
+
if cfg.state == 'new':
|
|
30
26
|
els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_types.ChatStateManager)(
|
|
31
27
|
lambda cm: ChatPhaseCallback(ChatPhase.STARTING, cm.clear_state),
|
|
32
28
|
)))
|
|
33
29
|
|
|
34
|
-
elif state == 'ephemeral':
|
|
30
|
+
elif cfg.state == 'ephemeral':
|
|
35
31
|
els.append(inj.bind(_types.ChatStateManager, to_ctor=_inmemory.InMemoryChatStateManager, singleton=True))
|
|
36
32
|
|
|
37
33
|
else:
|
|
38
|
-
raise TypeError(state)
|
|
34
|
+
raise TypeError(cfg.state)
|
|
39
35
|
|
|
40
36
|
return inj.as_elements(*els)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import dataclasses as dc
|
|
4
|
+
|
|
5
|
+
from ...... import minichain as mc
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
12
|
+
class UserConfig:
|
|
13
|
+
initial_system_content: ta.Optional['mc.Content'] = None
|
|
14
|
+
initial_user_content: ta.Optional['mc.Content'] = None
|
|
15
|
+
|
|
16
|
+
interactive: bool = False
|
|
17
|
+
use_readline: bool | ta.Literal['auto'] = 'auto'
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import typing as ta
|
|
2
|
-
|
|
3
1
|
from omlish import inject as inj
|
|
4
2
|
from omlish import lang
|
|
5
3
|
|
|
@@ -7,11 +5,13 @@ from ...... import minichain as mc
|
|
|
7
5
|
from ...phases.injection import phase_callbacks
|
|
8
6
|
from ...phases.types import ChatPhase
|
|
9
7
|
from ...phases.types import ChatPhaseCallback
|
|
8
|
+
from .configs import UserConfig
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
with lang.auto_proxy_import(globals()):
|
|
12
|
+
from .....inputs import asyncs as _inputs_asyncs
|
|
13
|
+
from .....inputs import sync as _inputs_sync
|
|
13
14
|
from ..state import types as _state
|
|
14
|
-
from . import inputs as _inputs
|
|
15
15
|
from . import interactive as _interactive
|
|
16
16
|
from . import oneshot as _oneshot
|
|
17
17
|
from . import types as _types
|
|
@@ -20,28 +20,22 @@ with lang.auto_proxy_import(globals()):
|
|
|
20
20
|
##
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def bind_user(
|
|
24
|
-
*,
|
|
25
|
-
initial_system_content: ta.Optional['mc.Content'] = None,
|
|
26
|
-
initial_user_content: ta.Optional['mc.Content'] = None,
|
|
27
|
-
interactive: bool = False,
|
|
28
|
-
use_readline: bool | ta.Literal['auto'] = False,
|
|
29
|
-
) -> inj.Elements:
|
|
23
|
+
def bind_user(cfg: UserConfig = UserConfig()) -> inj.Elements:
|
|
30
24
|
els: list[inj.Elemental] = []
|
|
31
25
|
|
|
32
26
|
# FIXME: barf
|
|
33
|
-
if initial_system_content is not None:
|
|
27
|
+
if cfg.initial_system_content is not None:
|
|
34
28
|
async def add_initial_system_content(cm: '_state.ChatStateManager') -> None:
|
|
35
|
-
await cm.extend_chat([mc.SystemMessage(initial_system_content)])
|
|
29
|
+
await cm.extend_chat([mc.SystemMessage(cfg.initial_system_content)])
|
|
36
30
|
|
|
37
31
|
els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_state.ChatStateManager)(
|
|
38
32
|
lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_system_content(cm)),
|
|
39
33
|
)))
|
|
40
34
|
|
|
41
|
-
if interactive:
|
|
42
|
-
if initial_user_content is not None:
|
|
35
|
+
if cfg.interactive:
|
|
36
|
+
if cfg.initial_user_content is not None:
|
|
43
37
|
async def add_initial_user_content(cm: '_state.ChatStateManager') -> None:
|
|
44
|
-
await cm.extend_chat([mc.UserMessage(initial_user_content)])
|
|
38
|
+
await cm.extend_chat([mc.UserMessage(cfg.initial_user_content)])
|
|
45
39
|
|
|
46
40
|
els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_state.ChatStateManager)(
|
|
47
41
|
lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_user_content(cm)),
|
|
@@ -52,16 +46,16 @@ def bind_user(
|
|
|
52
46
|
els.append(inj.bind(_types.UserChatInput, to_ctor=_interactive.InteractiveUserChatInput, singleton=True))
|
|
53
47
|
|
|
54
48
|
els.extend([
|
|
55
|
-
inj.bind(
|
|
56
|
-
inj.bind(
|
|
49
|
+
inj.bind(_inputs_sync.SyncStringInput, to_const=_inputs_sync.InputSyncStringInput(use_readline=cfg.use_readline)), # noqa
|
|
50
|
+
inj.bind(_inputs_asyncs.AsyncStringInput, to_ctor=_inputs_asyncs.ThreadAsyncStringInput, singleton=True),
|
|
57
51
|
])
|
|
58
52
|
|
|
59
53
|
else:
|
|
60
|
-
if initial_user_content is None:
|
|
54
|
+
if cfg.initial_user_content is None:
|
|
61
55
|
raise ValueError('Initial user content is required for non-interactive chat')
|
|
62
56
|
|
|
63
57
|
els.extend([
|
|
64
|
-
inj.bind(_oneshot.OneshotUserChatInputInitialChat, to_const=[mc.UserMessage(initial_user_content)]),
|
|
58
|
+
inj.bind(_oneshot.OneshotUserChatInputInitialChat, to_const=[mc.UserMessage(cfg.initial_user_content)]),
|
|
65
59
|
inj.bind(_types.UserChatInput, to_ctor=_oneshot.OneshotUserChatInput, singleton=True),
|
|
66
60
|
])
|
|
67
61
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import typing as ta
|
|
2
2
|
|
|
3
3
|
from ...... import minichain as mc
|
|
4
|
-
from .
|
|
5
|
-
from .
|
|
6
|
-
from .
|
|
4
|
+
from .....inputs.asyncs import AsyncStringInput
|
|
5
|
+
from .....inputs.asyncs import SyncAsyncStringInput
|
|
6
|
+
from .....inputs.sync import InputSyncStringInput
|
|
7
7
|
from .types import UserChatInput
|
|
8
8
|
|
|
9
9
|
|
|
@@ -1,38 +1,27 @@
|
|
|
1
|
-
import dataclasses as dc
|
|
2
|
-
import typing as ta
|
|
1
|
+
from omlish import dataclasses as dc
|
|
3
2
|
|
|
4
|
-
from
|
|
3
|
+
from ...backends.configs import BackendConfig
|
|
4
|
+
from ...rendering.configs import RenderingConfig
|
|
5
|
+
from .chat.ai.configs import AiConfig
|
|
6
|
+
from .chat.state.configs import StateConfig
|
|
7
|
+
from .chat.user.configs import UserConfig
|
|
8
|
+
from .tools.configs import ToolsConfig
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
##
|
|
8
12
|
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
DEFAULT_BACKEND = 'openai'
|
|
11
15
|
|
|
12
16
|
|
|
13
17
|
##
|
|
14
18
|
|
|
15
19
|
|
|
16
|
-
@dc.dataclass(frozen=True)
|
|
20
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
17
21
|
class ChatConfig:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
initial_system_content: ta.Optional['mc.Content'] = None
|
|
26
|
-
initial_user_content: ta.Optional['mc.Content'] = None
|
|
27
|
-
|
|
28
|
-
interactive: bool = False
|
|
29
|
-
use_readline: bool | ta.Literal['auto'] = 'auto'
|
|
30
|
-
|
|
31
|
-
silent: bool = False
|
|
32
|
-
markdown: bool = False
|
|
33
|
-
|
|
34
|
-
stream: bool = False
|
|
35
|
-
|
|
36
|
-
enable_tools: bool = False
|
|
37
|
-
enabled_tools: ta.AbstractSet[str] | None = None
|
|
38
|
-
dangerous_no_tool_confirmation: bool = False
|
|
22
|
+
backend: BackendConfig = BackendConfig()
|
|
23
|
+
ai: AiConfig = AiConfig()
|
|
24
|
+
state: StateConfig = StateConfig()
|
|
25
|
+
user: UserConfig = UserConfig()
|
|
26
|
+
rendering: RenderingConfig = RenderingConfig()
|
|
27
|
+
tools: ToolsConfig = ToolsConfig()
|
|
@@ -2,20 +2,21 @@ from omlish import dataclasses as dc
|
|
|
2
2
|
from omlish import inject as inj
|
|
3
3
|
from omlish import lang
|
|
4
4
|
|
|
5
|
+
from ...backends.types import DefaultBackendName
|
|
5
6
|
from ..base import Session
|
|
6
|
-
from .configs import
|
|
7
|
+
from .configs import DEFAULT_BACKEND
|
|
7
8
|
from .configs import ChatConfig
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
with lang.auto_proxy_import(globals()):
|
|
12
|
+
from ...backends import inject as _backends
|
|
13
|
+
from ...rendering import inject as _rendering
|
|
11
14
|
from . import driver as _driver
|
|
12
15
|
from . import session as _session
|
|
13
|
-
from .backends import inject as _backends
|
|
14
16
|
from .chat.ai import inject as _chat_ai
|
|
15
17
|
from .chat.state import inject as _chat_state
|
|
16
18
|
from .chat.user import inject as _chat_user
|
|
17
19
|
from .phases import inject as _phases
|
|
18
|
-
from .rendering import inject as _rendering
|
|
19
20
|
from .tools import inject as _tools
|
|
20
21
|
|
|
21
22
|
|
|
@@ -28,42 +29,20 @@ def bind_chat(cfg: ChatConfig) -> inj.Elements:
|
|
|
28
29
|
#
|
|
29
30
|
|
|
30
31
|
els.extend([
|
|
31
|
-
_backends.bind_backends(
|
|
32
|
-
backend=cfg.backend or DEFAULT_CHAT_MODEL_BACKEND,
|
|
33
|
-
),
|
|
34
|
-
|
|
35
|
-
_chat_ai.bind_ai(
|
|
36
|
-
stream=cfg.stream,
|
|
37
|
-
silent=cfg.silent,
|
|
38
|
-
enable_tools=cfg.enable_tools,
|
|
39
|
-
),
|
|
40
|
-
|
|
41
|
-
_chat_user.bind_user(
|
|
42
|
-
initial_system_content=cfg.initial_system_content,
|
|
43
|
-
initial_user_content=cfg.initial_user_content,
|
|
44
|
-
interactive=cfg.interactive,
|
|
45
|
-
use_readline=cfg.use_readline,
|
|
46
|
-
),
|
|
47
|
-
|
|
48
|
-
_chat_state.bind_state(
|
|
49
|
-
state=cfg.state,
|
|
50
|
-
),
|
|
32
|
+
_backends.bind_backends(cfg.backend),
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
_chat_ai.bind_ai(cfg.ai),
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
markdown=cfg.markdown,
|
|
56
|
-
),
|
|
57
|
-
])
|
|
36
|
+
_chat_user.bind_user(cfg.user),
|
|
58
37
|
|
|
59
|
-
|
|
38
|
+
_chat_state.bind_state(cfg.state),
|
|
39
|
+
|
|
40
|
+
_phases.bind_phases(),
|
|
60
41
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
enabled_tools=cfg.enabled_tools,
|
|
66
|
-
))
|
|
42
|
+
_rendering.bind_rendering(cfg.rendering),
|
|
43
|
+
|
|
44
|
+
_tools.bind_tools(cfg.tools),
|
|
45
|
+
])
|
|
67
46
|
|
|
68
47
|
#
|
|
69
48
|
|
|
@@ -80,4 +59,8 @@ def bind_chat(cfg: ChatConfig) -> inj.Elements:
|
|
|
80
59
|
|
|
81
60
|
#
|
|
82
61
|
|
|
62
|
+
els.append(inj.bind(DefaultBackendName, to_const=DEFAULT_BACKEND))
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
|
|
83
66
|
return inj.as_elements(*els)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import dataclasses as dc
|
|
4
|
+
from omlish import lang
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
11
|
+
class ToolsConfig:
|
|
12
|
+
silent: bool = False
|
|
13
|
+
dangerous_no_confirmation: bool = False
|
|
14
|
+
enabled_tools: ta.Iterable[str] | None = None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
21
|
+
class ToolSetConfig(lang.Abstract):
|
|
22
|
+
pass
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from omlish import inject as inj
|
|
4
|
+
|
|
5
|
+
from ..injection import ToolSetBinder
|
|
6
|
+
from ..injection import bind_tool_context_provider_to_key
|
|
7
|
+
from ..injection import tool_catalog_entries
|
|
8
|
+
from .configs import FsToolSetConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def bind_fs_tools(cfg: FsToolSetConfig) -> inj.Elements:
|
|
15
|
+
from ......minichain.lib.fs.context import FsContext
|
|
16
|
+
from ......minichain.lib.fs.tools.ls import ls_tool
|
|
17
|
+
from ......minichain.lib.fs.tools.read import read_tool
|
|
18
|
+
|
|
19
|
+
return inj.as_elements(
|
|
20
|
+
tool_catalog_entries().bind_item_consts(
|
|
21
|
+
ls_tool(),
|
|
22
|
+
read_tool(),
|
|
23
|
+
),
|
|
24
|
+
|
|
25
|
+
inj.bind(FsContext(
|
|
26
|
+
root_dir=os.getcwd(),
|
|
27
|
+
)),
|
|
28
|
+
bind_tool_context_provider_to_key(FsContext),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
FS_TOOL_SET_BINDER = ToolSetBinder(FsToolSetConfig, bind_fs_tools)
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import typing as ta
|
|
3
|
-
|
|
4
1
|
from omlish import check
|
|
5
2
|
from omlish import inject as inj
|
|
6
3
|
from omlish import lang
|
|
7
4
|
|
|
8
5
|
from ..... import minichain as mc
|
|
9
|
-
from .
|
|
6
|
+
from .configs import ToolsConfig
|
|
7
|
+
from .injection import ToolSetBinder
|
|
10
8
|
from .injection import tool_catalog_entries
|
|
11
9
|
from .injection import tool_context_providers
|
|
12
10
|
|
|
@@ -20,65 +18,6 @@ with lang.auto_proxy_import(globals()):
|
|
|
20
18
|
##
|
|
21
19
|
|
|
22
20
|
|
|
23
|
-
_TOOL_BINDERS: dict[str, ta.Callable[[], inj.Elements]] = {}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _tool_binder(name: str) -> ta.Callable[[ta.Callable[[], inj.Elements]], ta.Callable[[], inj.Elements]]:
|
|
27
|
-
def inner(fn):
|
|
28
|
-
check.not_in(name, _TOOL_BINDERS)
|
|
29
|
-
_TOOL_BINDERS[name] = fn
|
|
30
|
-
return fn
|
|
31
|
-
return inner
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
@_tool_binder('weather')
|
|
38
|
-
def _bind_weather_tool() -> inj.Elements:
|
|
39
|
-
from .weather import WEATHER_TOOL
|
|
40
|
-
|
|
41
|
-
return inj.as_elements(
|
|
42
|
-
tool_catalog_entries().bind_item_consts(WEATHER_TOOL),
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@_tool_binder('todo')
|
|
47
|
-
def _bind_todo_tools() -> inj.Elements:
|
|
48
|
-
from .....minichain.lib.todo.context import TodoContext
|
|
49
|
-
from .....minichain.lib.todo.tools.read import todo_read_tool
|
|
50
|
-
from .....minichain.lib.todo.tools.write import todo_write_tool
|
|
51
|
-
|
|
52
|
-
return inj.as_elements(
|
|
53
|
-
tool_catalog_entries().bind_item_consts(
|
|
54
|
-
todo_read_tool(),
|
|
55
|
-
todo_write_tool(),
|
|
56
|
-
),
|
|
57
|
-
|
|
58
|
-
inj.bind(TodoContext()),
|
|
59
|
-
bind_tool_context_provider_to_key(TodoContext),
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@_tool_binder('fs')
|
|
64
|
-
def _bind_fs_tools() -> inj.Elements:
|
|
65
|
-
from .....minichain.lib.fs.context import FsContext
|
|
66
|
-
from .....minichain.lib.fs.tools.ls import ls_tool
|
|
67
|
-
from .....minichain.lib.fs.tools.read import read_tool
|
|
68
|
-
|
|
69
|
-
return inj.as_elements(
|
|
70
|
-
tool_catalog_entries().bind_item_consts(
|
|
71
|
-
ls_tool(),
|
|
72
|
-
read_tool(),
|
|
73
|
-
),
|
|
74
|
-
|
|
75
|
-
inj.bind(FsContext(
|
|
76
|
-
root_dir=os.getcwd(),
|
|
77
|
-
)),
|
|
78
|
-
bind_tool_context_provider_to_key(FsContext),
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
|
|
82
21
|
# if tools_config.enable_unsafe_tools_do_not_use_lol:
|
|
83
22
|
# from ...minichain.lib.bash import bash_tool
|
|
84
23
|
# els.append(bind_tool(bash_tool()))
|
|
@@ -90,12 +29,7 @@ def _bind_fs_tools() -> inj.Elements:
|
|
|
90
29
|
##
|
|
91
30
|
|
|
92
31
|
|
|
93
|
-
def bind_tools(
|
|
94
|
-
*,
|
|
95
|
-
silent: bool = False,
|
|
96
|
-
dangerous_no_confirmation: bool = False,
|
|
97
|
-
enabled_tools: ta.Iterable[str] | None = None,
|
|
98
|
-
) -> inj.Elements:
|
|
32
|
+
def bind_tools(cfg: ToolsConfig = ToolsConfig()) -> inj.Elements:
|
|
99
33
|
els: list[inj.Elemental] = []
|
|
100
34
|
|
|
101
35
|
#
|
|
@@ -106,8 +40,17 @@ def bind_tools(
|
|
|
106
40
|
|
|
107
41
|
els.append(tool_catalog_entries().bind_items_provider(singleton=True))
|
|
108
42
|
|
|
109
|
-
for etn in check.not_isinstance(enabled_tools or [], str):
|
|
110
|
-
|
|
43
|
+
for etn in check.not_isinstance(cfg.enabled_tools or [], str):
|
|
44
|
+
from .fs.inject import FS_TOOL_SET_BINDER
|
|
45
|
+
from .todo.inject import TODO_TOOL_SET_BINDER
|
|
46
|
+
from .weather.inject import WEATHER_TOOL_SET_BINDER
|
|
47
|
+
ts_binder: ToolSetBinder = { # type: ignore[assignment] # FIXME: placeholder obviously lol
|
|
48
|
+
'fs': FS_TOOL_SET_BINDER,
|
|
49
|
+
'todo': TODO_TOOL_SET_BINDER,
|
|
50
|
+
'weather': WEATHER_TOOL_SET_BINDER,
|
|
51
|
+
}[etn]
|
|
52
|
+
|
|
53
|
+
els.append(ts_binder.fn(ts_binder.cfg_cls()))
|
|
111
54
|
|
|
112
55
|
#
|
|
113
56
|
|
|
@@ -115,10 +58,10 @@ def bind_tools(
|
|
|
115
58
|
|
|
116
59
|
els.append(exec_stack.push_bind(to_ctor=_execution.ToolUseExecutorImpl, singleton=True))
|
|
117
60
|
|
|
118
|
-
if not silent:
|
|
61
|
+
if not cfg.silent:
|
|
119
62
|
els.append(exec_stack.push_bind(to_ctor=_rendering.ResultRenderingToolUseExecutor, singleton=True))
|
|
120
63
|
|
|
121
|
-
if dangerous_no_confirmation:
|
|
64
|
+
if cfg.dangerous_no_confirmation:
|
|
122
65
|
els.append(exec_stack.push_bind(to_ctor=_rendering.ArgsRenderingToolUseExecutor, singleton=True))
|
|
123
66
|
|
|
124
67
|
els.extend([
|
|
@@ -127,7 +70,7 @@ def bind_tools(
|
|
|
127
70
|
|
|
128
71
|
#
|
|
129
72
|
|
|
130
|
-
if not dangerous_no_confirmation:
|
|
73
|
+
if not cfg.dangerous_no_confirmation:
|
|
131
74
|
els.append(inj.bind(_confirmation.ToolExecutionConfirmation, to_ctor=_confirmation.InteractiveToolExecutionConfirmation, singleton=True)) # noqa
|
|
132
75
|
|
|
133
76
|
#
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import typing as ta
|
|
2
2
|
|
|
3
|
+
from omlish import dataclasses as dc
|
|
3
4
|
from omlish import inject as inj
|
|
4
5
|
from omlish import lang
|
|
5
6
|
|
|
6
7
|
from ..... import minichain as mc
|
|
8
|
+
from .configs import ToolSetConfig
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
with lang.auto_proxy_import(globals()):
|
|
10
12
|
from . import execution as _execution
|
|
11
13
|
|
|
14
|
+
|
|
15
|
+
ToolSetConfigT = ta.TypeVar('ToolSetConfigT', bound='ToolSetConfig')
|
|
16
|
+
|
|
17
|
+
|
|
12
18
|
##
|
|
13
19
|
|
|
14
20
|
|
|
@@ -27,3 +33,12 @@ def bind_tool_context_provider_to_key(key: ta.Any) -> inj.Elements:
|
|
|
27
33
|
lambda v: _execution.ToolContextProvider(lambda: [v]),
|
|
28
34
|
v=key,
|
|
29
35
|
), singleton=True)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dc.dataclass(frozen=True)
|
|
42
|
+
class ToolSetBinder(lang.Final, ta.Generic[ToolSetConfigT]):
|
|
43
|
+
cfg_cls: type[ToolSetConfig]
|
|
44
|
+
fn: ta.Callable[[ToolSetConfigT], inj.Elements]
|
|
File without changes
|