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
@@ -91,6 +91,52 @@
91
91
  }
92
92
  }
93
93
  },
94
+ {
95
+ "module": ".minichain.backends.impls.dummy.chat",
96
+ "attr": null,
97
+ "file": "ommlds/minichain/backends/impls/dummy/chat.py",
98
+ "line": 26,
99
+ "value": {
100
+ "!.minichain.registries.manifests.RegistryManifest": {
101
+ "module": "ommlds.minichain.backends.impls.dummy.chat",
102
+ "attr": "DummyChatChoicesService",
103
+ "name": "dummy",
104
+ "aliases": null,
105
+ "type": "ChatChoicesService"
106
+ }
107
+ }
108
+ },
109
+ {
110
+ "module": ".minichain.backends.impls.dummy.chat",
111
+ "attr": null,
112
+ "file": "ommlds/minichain/backends/impls/dummy/chat.py",
113
+ "line": 39,
114
+ "value": {
115
+ "!.minichain.registries.manifests.RegistryManifest": {
116
+ "module": "ommlds.minichain.backends.impls.dummy.chat",
117
+ "attr": "DummyChatChoicesStreamService",
118
+ "name": "dummy",
119
+ "aliases": null,
120
+ "type": "ChatChoicesStreamService"
121
+ }
122
+ }
123
+ },
124
+ {
125
+ "module": ".minichain.backends.impls.dummy.chat",
126
+ "attr": null,
127
+ "file": "ommlds/minichain/backends/impls/dummy/chat.py",
128
+ "line": 63,
129
+ "value": {
130
+ "!.minichain.backends.strings.manifests.BackendStringsManifest": {
131
+ "service_cls_names": [
132
+ "ChatChoicesService",
133
+ "ChatChoicesStreamService"
134
+ ],
135
+ "backend_name": "dummy",
136
+ "model_names": null
137
+ }
138
+ }
139
+ },
94
140
  {
95
141
  "module": ".minichain.backends.impls.google.chat",
96
142
  "attr": null,
@@ -148,6 +194,60 @@
148
194
  }
149
195
  }
150
196
  },
197
+ {
198
+ "module": ".minichain.backends.impls.groq.chat",
199
+ "attr": null,
200
+ "file": "ommlds/minichain/backends/impls/groq/chat.py",
201
+ "line": 24,
202
+ "value": {
203
+ "!.minichain.registries.manifests.RegistryManifest": {
204
+ "module": "ommlds.minichain.backends.impls.groq.chat",
205
+ "attr": "GroqChatChoicesService",
206
+ "name": "groq",
207
+ "aliases": null,
208
+ "type": "ChatChoicesService"
209
+ }
210
+ }
211
+ },
212
+ {
213
+ "module": ".minichain.backends.impls.groq.names",
214
+ "attr": "_BACKEND_STRINGS_MANIFEST",
215
+ "file": "ommlds/minichain/backends/impls/groq/names.py",
216
+ "line": 27,
217
+ "value": {
218
+ "!.minichain.backends.strings.manifests.BackendStringsManifest": {
219
+ "service_cls_names": [
220
+ "ChatChoicesService",
221
+ "ChatChoicesStreamService"
222
+ ],
223
+ "backend_name": "groq",
224
+ "model_names": {
225
+ "default": "gpt-oss-120b",
226
+ "aliases": {
227
+ "gpt-oss-120b": "openai/gpt-oss-120b",
228
+ "openai/gpt-oss-120b": null,
229
+ "gpt-oss-20b": "openai/gpt-oss-20b",
230
+ "openai/gpt-oss-20b": null
231
+ }
232
+ }
233
+ }
234
+ }
235
+ },
236
+ {
237
+ "module": ".minichain.backends.impls.groq.stream",
238
+ "attr": null,
239
+ "file": "ommlds/minichain/backends/impls/groq/stream.py",
240
+ "line": 31,
241
+ "value": {
242
+ "!.minichain.registries.manifests.RegistryManifest": {
243
+ "module": "ommlds.minichain.backends.impls.groq.stream",
244
+ "attr": "GroqChatChoicesStreamService",
245
+ "name": "groq",
246
+ "aliases": null,
247
+ "type": "ChatChoicesStreamService"
248
+ }
249
+ }
250
+ },
151
251
  {
152
252
  "module": ".minichain.backends.impls.huggingface.repos",
153
253
  "attr": null,
@@ -394,7 +494,7 @@
394
494
  },
395
495
  {
396
496
  "module": ".minichain.backends.impls.openai.names",
397
- "attr": "_BACKEND_STRINGS_MANIFEST",
497
+ "attr": "_CHAT_BACKEND_STRINGS_MANIFEST",
398
498
  "file": "ommlds/minichain/backends/impls/openai/names.py",
399
499
  "line": 63,
400
500
  "value": {
@@ -444,6 +544,36 @@
444
544
  }
445
545
  }
446
546
  },
547
+ {
548
+ "module": ".minichain.backends.impls.openai.names",
549
+ "attr": "_COMPLETION_BACKEND_STRINGS_MANIFEST",
550
+ "file": "ommlds/minichain/backends/impls/openai/names.py",
551
+ "line": 77,
552
+ "value": {
553
+ "!.minichain.backends.strings.manifests.BackendStringsManifest": {
554
+ "service_cls_names": [
555
+ "CompletionService"
556
+ ],
557
+ "backend_name": "openai",
558
+ "model_names": null
559
+ }
560
+ }
561
+ },
562
+ {
563
+ "module": ".minichain.backends.impls.openai.names",
564
+ "attr": "_EMBEDDING_BACKEND_STRINGS_MANIFEST",
565
+ "file": "ommlds/minichain/backends/impls/openai/names.py",
566
+ "line": 89,
567
+ "value": {
568
+ "!.minichain.backends.strings.manifests.BackendStringsManifest": {
569
+ "service_cls_names": [
570
+ "EmbeddingService"
571
+ ],
572
+ "backend_name": "openai",
573
+ "model_names": null
574
+ }
575
+ }
576
+ },
447
577
  {
448
578
  "module": ".minichain.backends.impls.openai.stream",
449
579
  "attr": null,
ommlds/__about__.py CHANGED
@@ -60,7 +60,7 @@ class Project(ProjectBase):
60
60
  ],
61
61
 
62
62
  'search': [
63
- 'ddgs ~= 9.7',
63
+ 'ddgs ~= 9.9',
64
64
  ],
65
65
 
66
66
  'wiki': [
@@ -0,0 +1,23 @@
1
+ from omlish import lang
2
+ from omlish import marshal as msh
3
+
4
+ from .protocol import ChatCompletionRequest
5
+
6
+
7
+ ##
8
+
9
+
10
+ @lang.static_init
11
+ def _install_standard_marshaling() -> None:
12
+ for root_cls, tag_field in [
13
+ (ChatCompletionRequest.Message, 'role'),
14
+ ]:
15
+ msh.install_standard_factories(*msh.standard_polymorphism_factories(
16
+ msh.polymorphism_from_subclasses(
17
+ root_cls,
18
+ naming=msh.Naming.SNAKE,
19
+ strip_suffix=msh.AutoStripSuffix,
20
+ ),
21
+ msh.FieldTypeTagging(tag_field),
22
+ unions='partial',
23
+ ))
@@ -0,0 +1,184 @@
1
+ """
2
+ https://console.groq.com/docs/api-reference#chat-create
3
+ """
4
+ import typing as ta
5
+
6
+ from omlish import dataclasses as dc
7
+ from omlish import lang
8
+ from omlish import marshal as msh
9
+
10
+
11
+ ##
12
+
13
+
14
+ def _set_class_marshal_options(cls):
15
+ msh.update_object_metadata(
16
+ cls,
17
+ field_defaults=msh.FieldMetadata(
18
+ options=msh.FieldOptions(
19
+ omit_if=lang.is_none,
20
+ ),
21
+ ),
22
+ )
23
+
24
+ return cls
25
+
26
+
27
+ ##
28
+
29
+
30
+ @dc.dataclass(frozen=True, kw_only=True)
31
+ @_set_class_marshal_options
32
+ class ChatCompletionRequest(lang.Final):
33
+ @dc.dataclass(frozen=True, kw_only=True)
34
+ class Message(lang.Sealed, lang.Abstract):
35
+ pass
36
+
37
+ @dc.dataclass(frozen=True, kw_only=True)
38
+ @_set_class_marshal_options
39
+ class SystemMessage(Message, lang.Final):
40
+ content: str | ta.Sequence[str]
41
+ name: str | None = None
42
+ role: ta.Literal['system'] = 'system'
43
+
44
+ @dc.dataclass(frozen=True, kw_only=True)
45
+ @_set_class_marshal_options
46
+ class UserMessage(Message, lang.Final):
47
+ content: str | ta.Sequence[str]
48
+ name: str | None = None
49
+ role: ta.Literal['user'] = 'user'
50
+
51
+ @dc.dataclass(frozen=True, kw_only=True)
52
+ @_set_class_marshal_options
53
+ class AssistantMessage(Message, lang.Final):
54
+ content: str | ta.Sequence[str] | None = None
55
+ name: str | None = None
56
+ reasoning: str | None = None
57
+ role: ta.Literal['assistant'] = 'assistant'
58
+
59
+ @dc.dataclass(frozen=True, kw_only=True)
60
+ @_set_class_marshal_options
61
+ class ToolCall(lang.Final):
62
+ @dc.dataclass(frozen=True, kw_only=True)
63
+ @_set_class_marshal_options
64
+ class Function(lang.Final):
65
+ arguments: str
66
+ name: str
67
+
68
+ function: Function
69
+ id: str
70
+ type: ta.Literal['function'] = 'function'
71
+
72
+ tool_calls: ta.Sequence[ToolCall] | None = None
73
+
74
+ @dc.dataclass(frozen=True, kw_only=True)
75
+ @_set_class_marshal_options
76
+ class ToolMessage(Message, lang.Final):
77
+ content: str | ta.Sequence[str]
78
+ role: ta.Literal['tool'] = 'tool'
79
+ tool_call_id: str
80
+
81
+ messages: ta.Sequence[Message]
82
+ model: str
83
+ citation_options: ta.Literal['enabled', 'disabled'] | None = None
84
+ compound_custom: ta.Mapping[str, ta.Any] | None = None
85
+ disable_tool_validation: bool | None = None
86
+ documents: ta.Sequence[ta.Mapping[str, ta.Any]] | None = None
87
+ frequency_penalty: float | None = None
88
+ include_reasoning: bool | None = None
89
+ logit_bias: ta.Mapping[str, ta.Any] | None = None
90
+ logprobs: bool | None = None
91
+ max_completion_tokens: int | None = None
92
+ n: int | None = None
93
+ parallel_tool_calls: bool | None = None
94
+ presence_penalty: float | None = None
95
+ reasoning_effort: ta.Literal['none', 'default', 'low', 'medium', 'high'] | None = None
96
+ reasoning_format: ta.Literal['hidden', 'raw', 'parsed'] | None = None
97
+ response_format: ta.Any | None = None
98
+ search_settings: ta.Mapping[str, ta.Any] | None = None
99
+ seed: int | None = None
100
+ service_tier: ta.Literal['auto', 'on_demand', 'flex', 'performance', 'null'] | None = None
101
+ stop: str | ta.Sequence[str] | None = None
102
+ store: bool | None = None
103
+ stream: bool | None = None
104
+ stream_options: ta.Mapping[str, ta.Any] | None = None
105
+ temperature: float | None = None
106
+ tool_choice: str | None = None
107
+ tools: ta.Sequence[ta.Mapping[str, ta.Any]] | None = None
108
+ top_logprobs: int | None = None
109
+ top_p: float | None = None
110
+ user: str | None = None
111
+
112
+
113
+ @dc.dataclass(frozen=True, kw_only=True)
114
+ @_set_class_marshal_options
115
+ class ChatCompletionResponse(lang.Final):
116
+ @dc.dataclass(frozen=True, kw_only=True)
117
+ @_set_class_marshal_options
118
+ class Choice(lang.Final):
119
+ finish_reason: ta.Literal['stop', 'length', 'tool_calls', 'function_call']
120
+ index: int
121
+ logprobs: ta.Mapping[str, ta.Any] | None = None
122
+
123
+ @dc.dataclass(frozen=True, kw_only=True)
124
+ @_set_class_marshal_options
125
+ class Message(lang.Final):
126
+ annotations: ta.Sequence[ta.Mapping[str, ta.Any]] | None = None
127
+ content: str | None = None
128
+ executed_tools: ta.Sequence[ta.Mapping[str, ta.Any]] | None = None
129
+ reasoning: str | None = None
130
+ role: ta.Literal['assistant'] = 'assistant'
131
+ tool_calls: ta.Sequence[ta.Mapping[str, ta.Any]] | None = None
132
+
133
+ message: Message
134
+
135
+ choices: ta.Sequence[Choice]
136
+ created: int
137
+ id: str
138
+ model: str
139
+ object: ta.Literal['chat.completion'] = 'chat.completion'
140
+ system_fingerprint: str
141
+ usage: ta.Mapping[str, ta.Any] | None = None
142
+ usage_breakdown: ta.Mapping[str, ta.Any] | None = None
143
+ x_groq: ta.Mapping[str, ta.Any] | None = None
144
+ service_tier: str | None = None
145
+
146
+
147
+ @dc.dataclass(frozen=True, kw_only=True)
148
+ @_set_class_marshal_options
149
+ class ChatCompletionChunk(lang.Final):
150
+ id: str
151
+ object: ta.Literal['chat.completion.chunk'] = 'chat.completion.chunk'
152
+ created: int
153
+ model: str
154
+ system_fingerprint: str
155
+
156
+ @dc.dataclass(frozen=True, kw_only=True)
157
+ @_set_class_marshal_options
158
+ class Choice(lang.Final):
159
+ index: int
160
+
161
+ @dc.dataclass(frozen=True, kw_only=True)
162
+ @_set_class_marshal_options
163
+ class Delta(lang.Final):
164
+ role: str | None = None
165
+ content: str | None = None
166
+
167
+ channel: str | None = None
168
+ reasoning: str | None = None
169
+
170
+ delta: Delta
171
+ logprobs: ta.Mapping[str, ta.Any] | None = None
172
+ finish_reason: ta.Literal['stop', 'length', 'tool_calls', 'function_call'] | None = None
173
+
174
+ choices: ta.Sequence[Choice]
175
+
176
+ x_groq: ta.Mapping[str, ta.Any] | None = None
177
+ service_tier: str | None = None
178
+ usage: ta.Mapping[str, ta.Any] | None = None
179
+
180
+
181
+ ##
182
+
183
+
184
+ msh.register_global_module_import('._marshal', __package__)
@@ -4,17 +4,25 @@
4
4
  # https://github.com/tinygrad/tinygrad/blob/ef17af85c6d3f84d1e1cc084d6dee8ced3d1a33e/extra/models/llama.py
5
5
 
6
6
 
7
- from .llm import ( # noqa
8
- Llama3Llm,
9
- run_llm,
10
- run_llm_to_stop,
11
- RunLlmToStopResult,
12
- )
13
-
14
- from .tokenization import ( # noqa
15
- Tokenizer,
16
- )
17
-
18
- from .transformer import ( # noqa
19
- Transformer,
20
- )
7
+ from omlish import lang as _lang
8
+
9
+
10
+ with _lang.auto_proxy_init(globals()):
11
+ from .fetch import ( # noqa
12
+ fetch_model,
13
+ )
14
+
15
+ from .llm import ( # noqa
16
+ Llama3Llm,
17
+ run_llm,
18
+ run_llm_to_stop,
19
+ RunLlmToStopResult,
20
+ )
21
+
22
+ from .tokenization import ( # noqa
23
+ Tokenizer,
24
+ )
25
+
26
+ from .transformer import ( # noqa
27
+ Transformer,
28
+ )
ommlds/cli/asyncs.py ADDED
@@ -0,0 +1,30 @@
1
+ import abc
2
+ import functools
3
+ import typing as ta
4
+
5
+ from omlish import lang
6
+
7
+
8
+ with lang.auto_proxy_import(globals()):
9
+ import anyio
10
+
11
+
12
+ T = ta.TypeVar('T')
13
+ P = ta.ParamSpec('P')
14
+
15
+
16
+ ##
17
+
18
+
19
+ class AsyncThreadRunner(lang.Abstract):
20
+ @abc.abstractmethod
21
+ def run_in_thread(self, fn: ta.Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> ta.Awaitable[T]:
22
+ raise NotImplementedError
23
+
24
+
25
+ ##
26
+
27
+
28
+ class AnyioAsyncThreadRunner(AsyncThreadRunner):
29
+ def run_in_thread(self, fn: ta.Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> ta.Awaitable[T]:
30
+ return anyio.to_thread.run_sync(functools.partial(fn, *args, **kwargs))
@@ -3,12 +3,15 @@ import typing as ta
3
3
 
4
4
  from omlish import lang
5
5
 
6
- from ..... import minichain as mc
6
+ from ... import minichain as mc
7
7
  from .types import BackendConfigs
8
8
  from .types import BackendName
9
9
  from .types import BackendProvider
10
10
  from .types import ChatChoicesServiceBackendProvider
11
11
  from .types import ChatChoicesStreamServiceBackendProvider
12
+ from .types import CompletionServiceBackendProvider
13
+ from .types import DefaultBackendName
14
+ from .types import EmbeddingServiceBackendProvider
12
15
  from .types import ServiceT
13
16
 
14
17
 
@@ -22,7 +25,8 @@ class CatalogBackendProvider(BackendProvider[ServiceT], lang.Abstract):
22
25
  def __init__(
23
26
  self,
24
27
  *,
25
- name: BackendName,
28
+ name: BackendName | None = None,
29
+ default_name: DefaultBackendName | None = None,
26
30
  catalog: 'mc.BackendCatalog',
27
31
  configs: BackendConfigs | None = None,
28
32
  instantiator: Instantiator | None = None,
@@ -30,6 +34,7 @@ class CatalogBackendProvider(BackendProvider[ServiceT], lang.Abstract):
30
34
  super().__init__()
31
35
 
32
36
  self._name = name
37
+ self._default_name = default_name
33
38
  self._catalog = catalog
34
39
  self._configs = configs
35
40
  if instantiator is None:
@@ -38,13 +43,24 @@ class CatalogBackendProvider(BackendProvider[ServiceT], lang.Abstract):
38
43
 
39
44
  @contextlib.asynccontextmanager
40
45
  async def _provide_backend(self, cls: type[ServiceT]) -> ta.AsyncIterator[ServiceT]:
41
- be = self._catalog.get_backend(cls, self._name)
46
+ name: str
47
+ if self._name is not None:
48
+ name = self._name
49
+ elif self._default_name is not None:
50
+ name = self._default_name
51
+ else:
52
+ raise RuntimeError('No backend name specified')
53
+
54
+ be = self._catalog.get_backend(cls, name)
42
55
 
43
56
  service: ServiceT
44
57
  async with lang.async_or_sync_maybe_managing(await self._instantiator(be, self._configs)) as service:
45
58
  yield service
46
59
 
47
60
 
61
+ ##
62
+
63
+
48
64
  class CatalogChatChoicesServiceBackendProvider(
49
65
  CatalogBackendProvider['mc.ChatChoicesService'],
50
66
  ChatChoicesServiceBackendProvider,
@@ -59,3 +75,19 @@ class CatalogChatChoicesStreamServiceBackendProvider(
59
75
  ):
60
76
  def provide_backend(self) -> ta.AsyncContextManager['mc.ChatChoicesStreamService']:
61
77
  return self._provide_backend(mc.ChatChoicesStreamService) # type: ignore[type-abstract]
78
+
79
+
80
+ class CatalogCompletionServiceBackendProvider(
81
+ CatalogBackendProvider['mc.CompletionService'],
82
+ CompletionServiceBackendProvider,
83
+ ):
84
+ def provide_backend(self) -> ta.AsyncContextManager['mc.CompletionService']:
85
+ return self._provide_backend(mc.CompletionService) # type: ignore[type-abstract]
86
+
87
+
88
+ class CatalogEmbeddingServiceBackendProvider(
89
+ CatalogBackendProvider['mc.EmbeddingService'],
90
+ EmbeddingServiceBackendProvider,
91
+ ):
92
+ def provide_backend(self) -> ta.AsyncContextManager['mc.EmbeddingService']:
93
+ return self._provide_backend(mc.EmbeddingService) # type: ignore[type-abstract]
@@ -0,0 +1,9 @@
1
+ from omlish import dataclasses as dc
2
+
3
+
4
+ ##
5
+
6
+
7
+ @dc.dataclass(frozen=True, kw_only=True)
8
+ class BackendConfig:
9
+ backend: str | None = None
@@ -2,69 +2,64 @@ import typing as ta
2
2
 
3
3
  from omlish import inject as inj
4
4
  from omlish import lang
5
+ from omlish import typedvalues as tv
5
6
 
6
7
  from ... import minichain as mc
8
+ from .configs import BackendConfig
9
+ from .injection import backend_configs
10
+
11
+
12
+ with lang.auto_proxy_import(globals()):
13
+ from ...minichain.backends.impls.huggingface import repos as hf_repos
14
+ from . import catalog as _catalog
15
+ from . import types as _types
7
16
 
8
17
 
9
18
  ##
10
19
 
11
20
 
12
- def bind_strings_backends() -> inj.Elements:
21
+ def bind_backends(cfg: BackendConfig = BackendConfig()) -> inj.Elements:
13
22
  lst: list[inj.Elemental] = []
14
23
 
24
+ #
25
+
15
26
  lst.extend([
16
27
  inj.bind(mc.BackendStringBackendCatalog, singleton=True),
17
28
  inj.bind(mc.BackendCatalog, to_key=mc.BackendStringBackendCatalog),
18
29
  ])
19
30
 
20
- from ...minichain.backends.impls.huggingface.repos import HuggingfaceModelRepoResolver
21
-
22
31
  lst.extend([
23
- inj.bind(HuggingfaceModelRepoResolver, singleton=True),
24
- inj.bind(mc.ModelRepoResolver, to_key=HuggingfaceModelRepoResolver),
32
+ inj.bind(hf_repos.HuggingfaceModelRepoResolver, singleton=True),
33
+ inj.bind(mc.ModelRepoResolver, to_key=hf_repos.HuggingfaceModelRepoResolver),
25
34
 
26
35
  ])
27
36
 
28
- return inj.as_elements(*lst)
29
-
30
-
31
- def bind_simple_backends() -> inj.Elements:
32
- lst: list[inj.Elemental] = []
37
+ #
33
38
 
34
- lst.extend([
35
- inj.set_binder[mc.SimpleBackendCatalogEntry](),
36
- inj.bind(
37
- lang.typed_lambda(mc.SimpleBackendCatalogEntries, s=ta.AbstractSet[mc.SimpleBackendCatalogEntry])(
38
- lambda s: list(s),
39
- ),
40
- singleton=True,
41
- ),
42
- ])
39
+ lst.append(backend_configs().bind_items_provider(singleton=True))
43
40
 
44
- lst.extend([
45
- inj.bind(mc.SimpleBackendCatalog, singleton=True),
46
- inj.bind(mc.BackendCatalog, to_key=mc.SimpleBackendCatalog),
47
- ])
41
+ #
48
42
 
49
- from .standard import STANDARD_BACKEND_CATALOG_ENTRIES
43
+ if cfg.backend is not None:
44
+ lst.append(inj.bind(_types.BackendName, to_const=cfg.backend))
50
45
 
51
46
  lst.extend([
52
- inj.bind_set_entry_const(ta.AbstractSet[mc.SimpleBackendCatalogEntry], e)
53
- for e in STANDARD_BACKEND_CATALOG_ENTRIES
47
+ inj.bind(_types.ChatChoicesServiceBackendProvider, to_ctor=_catalog.CatalogChatChoicesServiceBackendProvider, singleton=True), # noqa
48
+ inj.bind(_types.ChatChoicesStreamServiceBackendProvider, to_ctor=_catalog.CatalogChatChoicesStreamServiceBackendProvider, singleton=True), # noqa
49
+ inj.bind(_types.CompletionServiceBackendProvider, to_ctor=_catalog.CatalogCompletionServiceBackendProvider, singleton=True), # noqa
50
+ inj.bind(_types.EmbeddingServiceBackendProvider, to_ctor=_catalog.CatalogEmbeddingServiceBackendProvider, singleton=True), # noqa
54
51
  ])
55
52
 
56
- return inj.as_elements(*lst)
53
+ #
57
54
 
55
+ async def catalog_backend_instantiator_provider(injector: inj.AsyncInjector) -> _catalog.CatalogBackendProvider.Instantiator: # noqa
56
+ async def inner(be: 'mc.BackendCatalog.Backend', cfgs: _types.BackendConfigs | None) -> ta.Any:
57
+ kwt = inj.build_kwargs_target(be.factory, non_strict=True)
58
+ kw = await injector.provide_kwargs(kwt)
59
+ return be.factory(*tv.collect(*(be.configs or []), *(cfgs or []), override=True), **kw)
58
60
 
59
- def bind_backends(
60
- *,
61
- enable_backend_strings: bool = False,
62
- ) -> inj.Elements:
63
- lst: list[inj.Elemental] = []
61
+ return _catalog.CatalogBackendProvider.Instantiator(inner)
64
62
 
65
- if enable_backend_strings:
66
- lst.append(bind_strings_backends())
67
- else:
68
- lst.append(bind_simple_backends())
63
+ lst.append(inj.bind(_catalog.CatalogBackendProvider.Instantiator, to_async_fn=catalog_backend_instantiator_provider)) # noqa
69
64
 
70
65
  return inj.as_elements(*lst)
@@ -1,7 +1,7 @@
1
1
  from omlish import inject as inj
2
2
  from omlish import lang
3
3
 
4
- from ..... import minichain as mc
4
+ from ... import minichain as mc
5
5
 
6
6
 
7
7
  with lang.auto_proxy_import(globals()):
@@ -3,7 +3,7 @@ import typing as ta
3
3
 
4
4
  from omlish import lang
5
5
 
6
- from ..... import minichain as mc
6
+ from ... import minichain as mc
7
7
 
8
8
 
9
9
  ServiceT = ta.TypeVar('ServiceT', bound=mc.Service)
@@ -13,6 +13,8 @@ ServiceT = ta.TypeVar('ServiceT', bound=mc.Service)
13
13
 
14
14
 
15
15
  BackendName = ta.NewType('BackendName', str)
16
+ DefaultBackendName = ta.NewType('DefaultBackendName', str)
17
+
16
18
  BackendConfigs = ta.NewType('BackendConfigs', ta.Sequence['mc.Config'])
17
19
 
18
20
 
@@ -34,3 +36,11 @@ class ChatChoicesServiceBackendProvider(BackendProvider['mc.ChatChoicesService']
34
36
 
35
37
  class ChatChoicesStreamServiceBackendProvider(BackendProvider['mc.ChatChoicesStreamService'], lang.Abstract):
36
38
  pass
39
+
40
+
41
+ class CompletionServiceBackendProvider(BackendProvider['mc.CompletionService'], lang.Abstract):
42
+ pass
43
+
44
+
45
+ class EmbeddingServiceBackendProvider(BackendProvider['mc.EmbeddingService'], lang.Abstract):
46
+ pass
@@ -4,7 +4,7 @@ import typing as ta
4
4
  from omlish import check
5
5
  from omlish import lang
6
6
 
7
- from ..... import minichain as mc
7
+ from ... import minichain as mc
8
8
 
9
9
 
10
10
  ##