ommlds 0.0.0.dev474__py3-none-any.whl → 0.0.0.dev476__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.
Files changed (75) hide show
  1. ommlds/.omlish-manifests.json +131 -1
  2. ommlds/__about__.py +1 -1
  3. ommlds/backends/groq/_marshal.py +23 -0
  4. ommlds/backends/groq/protocol.py +184 -0
  5. ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
  6. ommlds/cli/asyncs.py +30 -0
  7. ommlds/cli/{sessions/chat/backends → backends}/catalog.py +35 -3
  8. ommlds/cli/backends/configs.py +9 -0
  9. ommlds/cli/backends/inject.py +31 -36
  10. ommlds/cli/{sessions/chat/backends → backends}/injection.py +1 -1
  11. ommlds/cli/{sessions/chat/backends → backends}/types.py +11 -1
  12. ommlds/cli/{sessions/chat/content → content}/messages.py +1 -1
  13. ommlds/cli/{sessions/chat/content → content}/strings.py +1 -1
  14. ommlds/cli/inject.py +7 -6
  15. ommlds/cli/inputs/asyncs.py +32 -0
  16. ommlds/cli/inputs/sync.py +75 -0
  17. ommlds/cli/main.py +266 -124
  18. ommlds/cli/rendering/__init__.py +0 -0
  19. ommlds/cli/rendering/configs.py +9 -0
  20. ommlds/cli/{sessions/chat/rendering → rendering}/inject.py +4 -5
  21. ommlds/cli/{sessions/chat/rendering → rendering}/markdown.py +1 -1
  22. ommlds/cli/{sessions/chat/rendering → rendering}/raw.py +1 -1
  23. ommlds/cli/{sessions/chat/rendering → rendering}/types.py +1 -1
  24. ommlds/cli/secrets.py +21 -0
  25. ommlds/cli/sessions/base.py +1 -1
  26. ommlds/cli/sessions/chat/chat/ai/configs.py +11 -0
  27. ommlds/cli/sessions/chat/chat/ai/inject.py +7 -11
  28. ommlds/cli/sessions/chat/chat/ai/rendering.py +4 -4
  29. ommlds/cli/sessions/chat/chat/ai/services.py +2 -2
  30. ommlds/cli/sessions/chat/chat/state/configs.py +11 -0
  31. ommlds/cli/sessions/chat/chat/state/inject.py +6 -10
  32. ommlds/cli/sessions/chat/chat/state/inmemory.py +1 -2
  33. ommlds/cli/sessions/chat/chat/state/storage.py +1 -2
  34. ommlds/cli/sessions/chat/chat/state/types.py +1 -1
  35. ommlds/cli/sessions/chat/chat/user/configs.py +17 -0
  36. ommlds/cli/sessions/chat/chat/user/inject.py +16 -15
  37. ommlds/cli/sessions/chat/chat/user/interactive.py +7 -5
  38. ommlds/cli/sessions/chat/configs.py +15 -24
  39. ommlds/cli/sessions/chat/inject.py +18 -34
  40. ommlds/cli/sessions/chat/session.py +1 -1
  41. ommlds/cli/sessions/chat/tools/configs.py +13 -0
  42. ommlds/cli/sessions/chat/tools/inject.py +6 -10
  43. ommlds/cli/sessions/chat/tools/injection.py +1 -0
  44. ommlds/cli/sessions/chat/tools/rendering.py +1 -1
  45. ommlds/cli/sessions/completion/configs.py +2 -2
  46. ommlds/cli/sessions/completion/inject.py +14 -0
  47. ommlds/cli/sessions/completion/session.py +7 -11
  48. ommlds/cli/sessions/embedding/configs.py +2 -2
  49. ommlds/cli/sessions/embedding/inject.py +14 -0
  50. ommlds/cli/sessions/embedding/session.py +7 -11
  51. ommlds/cli/state/storage.py +1 -1
  52. ommlds/minichain/backends/catalogs/strings.py +1 -1
  53. ommlds/minichain/backends/impls/dummy/__init__.py +0 -0
  54. ommlds/minichain/backends/impls/dummy/chat.py +69 -0
  55. ommlds/minichain/backends/impls/groq/__init__.py +0 -0
  56. ommlds/minichain/backends/impls/groq/chat.py +69 -0
  57. ommlds/minichain/backends/impls/groq/names.py +35 -0
  58. ommlds/minichain/backends/impls/groq/protocol.py +46 -0
  59. ommlds/minichain/backends/impls/groq/stream.py +121 -0
  60. ommlds/minichain/backends/impls/openai/chat.py +3 -3
  61. ommlds/minichain/backends/impls/openai/names.py +27 -3
  62. ommlds/minichain/backends/impls/openai/stream.py +2 -2
  63. ommlds/wiki/analyze.py +2 -2
  64. ommlds/wiki/utils/xml.py +5 -5
  65. {ommlds-0.0.0.dev474.dist-info → ommlds-0.0.0.dev476.dist-info}/METADATA +5 -5
  66. {ommlds-0.0.0.dev474.dist-info → ommlds-0.0.0.dev476.dist-info}/RECORD +73 -55
  67. ommlds/cli/backends/standard.py +0 -20
  68. ommlds/cli/sessions/chat/backends/inject.py +0 -53
  69. /ommlds/{cli/sessions/chat/backends → backends/groq}/__init__.py +0 -0
  70. /ommlds/cli/{sessions/chat/content → content}/__init__.py +0 -0
  71. /ommlds/cli/{sessions/chat/rendering → inputs}/__init__.py +0 -0
  72. {ommlds-0.0.0.dev474.dist-info → ommlds-0.0.0.dev476.dist-info}/WHEEL +0 -0
  73. {ommlds-0.0.0.dev474.dist-info → ommlds-0.0.0.dev476.dist-info}/entry_points.txt +0 -0
  74. {ommlds-0.0.0.dev474.dist-info → ommlds-0.0.0.dev476.dist-info}/licenses/LICENSE +0 -0
  75. {ommlds-0.0.0.dev474.dist-info → ommlds-0.0.0.dev476.dist-info}/top_level.txt +0 -0
ommlds/cli/secrets.py ADDED
@@ -0,0 +1,21 @@
1
+ import os
2
+
3
+ from omdev.home.secrets import load_secrets
4
+
5
+
6
+ ##
7
+
8
+
9
+ def install_secrets() -> None:
10
+ # FIXME: lol garbage
11
+ for key in [
12
+ 'ANTHROPIC_API_KEY',
13
+ 'GEMINI_API_KEY',
14
+ 'GROQ_API_KEY',
15
+ 'HUGGINGFACE_TOKEN',
16
+ 'MISTRAL_API_KEY',
17
+ 'OPENAI_API_KEY',
18
+ 'TAVILY_API_KEY',
19
+ ]:
20
+ if (sec := load_secrets().try_get(key.lower())) is not None:
21
+ os.environ[key] = sec.reveal()
@@ -1,7 +1,7 @@
1
1
  import abc
2
- import dataclasses as dc
3
2
  import typing as ta
4
3
 
4
+ from omlish import dataclasses as dc
5
5
  from omlish import lang
6
6
  from omlish.configs import all as cfgs
7
7
 
@@ -0,0 +1,11 @@
1
+ from omlish import dataclasses as dc
2
+
3
+
4
+ ##
5
+
6
+
7
+ @dc.dataclass(frozen=True, kw_only=True)
8
+ class AiConfig:
9
+ stream: bool = False
10
+ silent: bool = False
11
+ enable_tools: bool = False
@@ -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 ...content.messages import MessageContentExtractor
5
- from ...content.messages import MessageContentExtractorImpl
6
- from ...rendering.types import ContentRendering
7
- from ...rendering.types import StreamContentRendering
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 ...backends.types import ChatChoicesServiceBackendProvider
8
- from ...backends.types import ChatChoicesStreamServiceBackendProvider
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
 
@@ -0,0 +1,11 @@
1
+ import typing as ta
2
+
3
+ from omlish import dataclasses as dc
4
+
5
+
6
+ ##
7
+
8
+
9
+ @dc.dataclass(frozen=True, kw_only=True)
10
+ class StateConfig:
11
+ state: ta.Literal['new', 'continue', 'ephemeral'] = 'continue'
@@ -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)
@@ -1,5 +1,4 @@
1
- import dataclasses as dc
2
-
1
+ from omlish import dataclasses as dc
3
2
  from omlish import lang
4
3
 
5
4
  from ...... import minichain as mc
@@ -1,6 +1,5 @@
1
- import dataclasses as dc
2
-
3
1
  from omlish import check
2
+ from omlish import dataclasses as dc
4
3
  from omlish import lang
5
4
 
6
5
  from ...... import minichain as mc
@@ -1,8 +1,8 @@
1
1
  import abc
2
- import dataclasses as dc
3
2
  import datetime
4
3
  import typing as ta
5
4
 
5
+ from omlish import dataclasses as dc
6
6
  from omlish import lang
7
7
 
8
8
  from ...... import minichain as mc
@@ -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,9 +5,12 @@ 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
15
  from . import interactive as _interactive
15
16
  from . import oneshot as _oneshot
@@ -19,27 +20,22 @@ with lang.auto_proxy_import(globals()):
19
20
  ##
20
21
 
21
22
 
22
- def bind_user(
23
- *,
24
- initial_system_content: ta.Optional['mc.Content'] = None,
25
- initial_user_content: ta.Optional['mc.Content'] = None,
26
- interactive: bool = False,
27
- ) -> inj.Elements:
23
+ def bind_user(cfg: UserConfig = UserConfig()) -> inj.Elements:
28
24
  els: list[inj.Elemental] = []
29
25
 
30
26
  # FIXME: barf
31
- if initial_system_content is not None:
27
+ if cfg.initial_system_content is not None:
32
28
  async def add_initial_system_content(cm: '_state.ChatStateManager') -> None:
33
- await cm.extend_chat([mc.SystemMessage(initial_system_content)])
29
+ await cm.extend_chat([mc.SystemMessage(cfg.initial_system_content)])
34
30
 
35
31
  els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_state.ChatStateManager)(
36
32
  lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_system_content(cm)),
37
33
  )))
38
34
 
39
- if interactive:
40
- if initial_user_content is not None:
35
+ if cfg.interactive:
36
+ if cfg.initial_user_content is not None:
41
37
  async def add_initial_user_content(cm: '_state.ChatStateManager') -> None:
42
- await cm.extend_chat([mc.UserMessage(initial_user_content)])
38
+ await cm.extend_chat([mc.UserMessage(cfg.initial_user_content)])
43
39
 
44
40
  els.append(phase_callbacks().bind_item(to_fn=lang.typed_lambda(cm=_state.ChatStateManager)(
45
41
  lambda cm: ChatPhaseCallback(ChatPhase.STARTED, lambda: add_initial_user_content(cm)),
@@ -49,12 +45,17 @@ def bind_user(
49
45
 
50
46
  els.append(inj.bind(_types.UserChatInput, to_ctor=_interactive.InteractiveUserChatInput, singleton=True))
51
47
 
48
+ els.extend([
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),
51
+ ])
52
+
52
53
  else:
53
- if initial_user_content is None:
54
+ if cfg.initial_user_content is None:
54
55
  raise ValueError('Initial user content is required for non-interactive chat')
55
56
 
56
57
  els.extend([
57
- inj.bind(_oneshot.OneshotUserChatInputInitialChat, to_const=[mc.UserMessage(initial_user_content)]),
58
+ inj.bind(_oneshot.OneshotUserChatInputInitialChat, to_const=[mc.UserMessage(cfg.initial_user_content)]),
58
59
  inj.bind(_types.UserChatInput, to_ctor=_oneshot.OneshotUserChatInput, singleton=True),
59
60
  ])
60
61
 
@@ -1,9 +1,9 @@
1
- import functools
2
1
  import typing as ta
3
2
 
4
- from omlish import lang
5
-
6
3
  from ...... import minichain as mc
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
 
@@ -11,14 +11,16 @@ from .types import UserChatInput
11
11
 
12
12
 
13
13
  class InteractiveUserChatInput(UserChatInput):
14
+ DEFAULT_STRING_INPUT: ta.ClassVar[AsyncStringInput] = SyncAsyncStringInput(InputSyncStringInput())
15
+
14
16
  def __init__(
15
17
  self,
16
- string_input: ta.Callable[[], ta.Awaitable[str]] | None = None,
18
+ string_input: AsyncStringInput | None = None,
17
19
  ) -> None:
18
20
  super().__init__()
19
21
 
20
22
  if string_input is None:
21
- string_input = lang.as_async(functools.partial(input, '> '))
23
+ string_input = self.DEFAULT_STRING_INPUT
22
24
  self._string_input = string_input
23
25
 
24
26
  async def get_next_user_messages(self) -> 'mc.UserChat':
@@ -1,36 +1,27 @@
1
- import dataclasses as dc
2
- import typing as ta
1
+ from omlish import dataclasses as dc
3
2
 
4
- from .... import minichain as mc
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
- DEFAULT_CHAT_MODEL_BACKEND = 'openai'
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
- _: dc.KW_ONLY
19
-
20
- backend: str | None = None
21
- model_name: str | None = None
22
-
23
- state: ta.Literal['new', 'continue', 'ephemeral'] = 'continue'
24
-
25
- initial_system_content: ta.Optional['mc.Content'] = None
26
- initial_user_content: ta.Optional['mc.Content'] = None
27
- interactive: bool = False
28
-
29
- silent: bool = False
30
- markdown: bool = False
31
-
32
- stream: bool = False
33
-
34
- enable_tools: bool = False
35
- enabled_tools: ta.AbstractSet[str] | None = None
36
- 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 DEFAULT_CHAT_MODEL_BACKEND
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,41 +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
- ),
46
-
47
- _chat_state.bind_state(
48
- state=cfg.state,
49
- ),
32
+ _backends.bind_backends(cfg.backend),
50
33
 
51
- _phases.bind_phases(),
34
+ _chat_ai.bind_ai(cfg.ai),
52
35
 
53
- _rendering.bind_rendering(
54
- markdown=cfg.markdown,
55
- ),
56
- ])
36
+ _chat_user.bind_user(cfg.user),
57
37
 
58
- #
38
+ _chat_state.bind_state(cfg.state),
39
+
40
+ _phases.bind_phases(),
59
41
 
60
- if cfg.enable_tools:
61
- els.append(_tools.bind_tools(
62
- silent=cfg.silent,
63
- dangerous_no_confirmation=cfg.dangerous_no_tool_confirmation,
64
- enabled_tools=cfg.enabled_tools,
65
- ))
42
+ _rendering.bind_rendering(cfg.rendering),
43
+
44
+ _tools.bind_tools(cfg.tools),
45
+ ])
66
46
 
67
47
  #
68
48
 
@@ -79,4 +59,8 @@ def bind_chat(cfg: ChatConfig) -> inj.Elements:
79
59
 
80
60
  #
81
61
 
62
+ els.append(inj.bind(DefaultBackendName, to_const=DEFAULT_BACKEND))
63
+
64
+ #
65
+
82
66
  return inj.as_elements(*els)
@@ -1,4 +1,4 @@
1
- import dataclasses as dc
1
+ from omlish import dataclasses as dc
2
2
 
3
3
  from ..base import Session
4
4
  from .configs import ChatConfig
@@ -0,0 +1,13 @@
1
+ import typing as ta
2
+
3
+ from omlish import dataclasses as dc
4
+
5
+
6
+ ##
7
+
8
+
9
+ @dc.dataclass(frozen=True, kw_only=True)
10
+ class ToolsConfig:
11
+ silent: bool = False
12
+ dangerous_no_confirmation: bool = False
13
+ enabled_tools: ta.Iterable[str] | None = None
@@ -6,6 +6,7 @@ from omlish import inject as inj
6
6
  from omlish import lang
7
7
 
8
8
  from ..... import minichain as mc
9
+ from .configs import ToolsConfig
9
10
  from .injection import bind_tool_context_provider_to_key
10
11
  from .injection import tool_catalog_entries
11
12
  from .injection import tool_context_providers
@@ -90,12 +91,7 @@ def _bind_fs_tools() -> inj.Elements:
90
91
  ##
91
92
 
92
93
 
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:
94
+ def bind_tools(cfg: ToolsConfig = ToolsConfig()) -> inj.Elements:
99
95
  els: list[inj.Elemental] = []
100
96
 
101
97
  #
@@ -106,7 +102,7 @@ def bind_tools(
106
102
 
107
103
  els.append(tool_catalog_entries().bind_items_provider(singleton=True))
108
104
 
109
- for etn in check.not_isinstance(enabled_tools or [], str):
105
+ for etn in check.not_isinstance(cfg.enabled_tools or [], str):
110
106
  els.append(_TOOL_BINDERS[etn]())
111
107
 
112
108
  #
@@ -115,10 +111,10 @@ def bind_tools(
115
111
 
116
112
  els.append(exec_stack.push_bind(to_ctor=_execution.ToolUseExecutorImpl, singleton=True))
117
113
 
118
- if not silent:
114
+ if not cfg.silent:
119
115
  els.append(exec_stack.push_bind(to_ctor=_rendering.ResultRenderingToolUseExecutor, singleton=True))
120
116
 
121
- if dangerous_no_confirmation:
117
+ if cfg.dangerous_no_confirmation:
122
118
  els.append(exec_stack.push_bind(to_ctor=_rendering.ArgsRenderingToolUseExecutor, singleton=True))
123
119
 
124
120
  els.extend([
@@ -127,7 +123,7 @@ def bind_tools(
127
123
 
128
124
  #
129
125
 
130
- if not dangerous_no_confirmation:
126
+ if not cfg.dangerous_no_confirmation:
131
127
  els.append(inj.bind(_confirmation.ToolExecutionConfirmation, to_ctor=_confirmation.InteractiveToolExecutionConfirmation, singleton=True)) # noqa
132
128
 
133
129
  #
@@ -9,6 +9,7 @@ from ..... import minichain as mc
9
9
  with lang.auto_proxy_import(globals()):
10
10
  from . import execution as _execution
11
11
 
12
+
12
13
  ##
13
14
 
14
15
 
@@ -1,7 +1,7 @@
1
1
  import typing as ta
2
2
 
3
3
  from ..... import minichain as mc
4
- from ..rendering.types import ContentRendering
4
+ from ....rendering.types import ContentRendering
5
5
  from .execution import ToolUseExecutor
6
6
 
7
7
 
@@ -1,4 +1,4 @@
1
- import dataclasses as dc
1
+ from omlish import dataclasses as dc
2
2
 
3
3
  from .... import minichain as mc
4
4
 
@@ -6,7 +6,7 @@ from .... import minichain as mc
6
6
  ##
7
7
 
8
8
 
9
- DEFAULT_COMPLETION_MODEL_BACKEND = 'openai'
9
+ DEFAULT_BACKEND = 'openai'
10
10
 
11
11
 
12
12
  ##
@@ -2,11 +2,15 @@ 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.configs import BackendConfig
6
+ from ...backends.types import DefaultBackendName
5
7
  from ..base import Session
8
+ from .configs import DEFAULT_BACKEND
6
9
  from .configs import CompletionConfig
7
10
 
8
11
 
9
12
  with lang.auto_proxy_import(globals()):
13
+ from ...backends import inject as _backends
10
14
  from . import session as _session
11
15
 
12
16
 
@@ -25,4 +29,14 @@ def bind_completion(cfg: CompletionConfig) -> inj.Elements:
25
29
 
26
30
  #
27
31
 
32
+ els.extend([
33
+ _backends.bind_backends(BackendConfig(
34
+ backend=cfg.backend,
35
+ )),
36
+
37
+ inj.bind(DefaultBackendName, to_const=DEFAULT_BACKEND),
38
+ ])
39
+
40
+ #
41
+
28
42
  return inj.as_elements(*els)
@@ -1,11 +1,9 @@
1
- import dataclasses as dc
2
-
3
1
  from omlish import check
4
- from omlish import lang
2
+ from omlish import dataclasses as dc
5
3
 
6
4
  from .... import minichain as mc
5
+ from ...backends.types import CompletionServiceBackendProvider
7
6
  from ..base import Session
8
- from .configs import DEFAULT_COMPLETION_MODEL_BACKEND
9
7
  from .configs import CompletionConfig
10
8
 
11
9
 
@@ -21,19 +19,17 @@ class CompletionSession(Session['CompletionSession.Config']):
21
19
  self,
22
20
  config: Config,
23
21
  *,
24
- backend_catalog: mc.BackendCatalog,
22
+ service_provider: CompletionServiceBackendProvider,
25
23
  ) -> None:
26
24
  super().__init__(config)
27
25
 
28
- self._backend_catalog = backend_catalog
26
+ self._service_provider = service_provider
29
27
 
30
28
  async def run(self) -> None:
31
29
  prompt = check.isinstance(self._config.content, str)
32
30
 
33
31
  mdl: mc.CompletionService
34
- async with lang.async_maybe_managing(self._backend_catalog.new_backend(
35
- mc.CompletionService,
36
- self._config.backend or DEFAULT_COMPLETION_MODEL_BACKEND,
37
- )) as mdl:
32
+ async with self._service_provider.provide_backend() as mdl:
38
33
  response = await mdl.invoke(mc.CompletionRequest(prompt))
39
- print(response.v.strip())
34
+
35
+ print(response.v.strip())
@@ -1,4 +1,4 @@
1
- import dataclasses as dc
1
+ from omlish import dataclasses as dc
2
2
 
3
3
  from .... import minichain as mc
4
4
 
@@ -6,7 +6,7 @@ from .... import minichain as mc
6
6
  ##
7
7
 
8
8
 
9
- DEFAULT_EMBEDDING_MODEL_BACKEND = 'openai'
9
+ DEFAULT_BACKEND = 'openai'
10
10
 
11
11
 
12
12
  ##