ommlds 0.0.0.dev469__py3-none-any.whl → 0.0.0.dev471__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.

@@ -714,7 +714,7 @@
714
714
  "module": ".tools.git",
715
715
  "attr": null,
716
716
  "file": "ommlds/tools/git.py",
717
- "line": 186,
717
+ "line": 189,
718
718
  "value": {
719
719
  "!omdev.tools.git.messages.GitMessageGeneratorManifest": {
720
720
  "module": "ommlds.tools.git",
@@ -15,33 +15,38 @@ from .types import ServiceT
15
15
  ##
16
16
 
17
17
 
18
- class _CatalogBackendProvider(BackendProvider[ServiceT], lang.Abstract):
18
+ class CatalogBackendProvider(BackendProvider[ServiceT], lang.Abstract):
19
+ class Instantiator(lang.Func2['mc.BackendCatalog.Backend', BackendConfigs | None, ta.Awaitable[ta.Any]]):
20
+ pass
21
+
19
22
  def __init__(
20
23
  self,
21
24
  *,
22
25
  name: BackendName,
23
26
  catalog: 'mc.BackendCatalog',
24
27
  configs: BackendConfigs | None = None,
28
+ instantiator: Instantiator | None = None,
25
29
  ) -> None:
26
30
  super().__init__()
27
31
 
28
32
  self._name = name
29
33
  self._catalog = catalog
30
34
  self._configs = configs
35
+ if instantiator is None:
36
+ instantiator = CatalogBackendProvider.Instantiator(lang.as_async(lambda be, cfgs: be.factory(*cfgs or [])))
37
+ self._instantiator = instantiator
31
38
 
32
39
  @contextlib.asynccontextmanager
33
40
  async def _provide_backend(self, cls: type[ServiceT]) -> ta.AsyncIterator[ServiceT]:
41
+ be = self._catalog.get_backend(cls, self._name)
42
+
34
43
  service: ServiceT
35
- async with lang.async_or_sync_maybe_managing(self._catalog.new_backend(
36
- cls,
37
- self._name,
38
- *(self._configs or []),
39
- )) as service:
44
+ async with lang.async_or_sync_maybe_managing(await self._instantiator(be, self._configs)) as service:
40
45
  yield service
41
46
 
42
47
 
43
48
  class CatalogChatChoicesServiceBackendProvider(
44
- _CatalogBackendProvider['mc.ChatChoicesService'],
49
+ CatalogBackendProvider['mc.ChatChoicesService'],
45
50
  ChatChoicesServiceBackendProvider,
46
51
  ):
47
52
  def provide_backend(self) -> ta.AsyncContextManager['mc.ChatChoicesService']:
@@ -49,7 +54,7 @@ class CatalogChatChoicesServiceBackendProvider(
49
54
 
50
55
 
51
56
  class CatalogChatChoicesStreamServiceBackendProvider(
52
- _CatalogBackendProvider['mc.ChatChoicesStreamService'],
57
+ CatalogBackendProvider['mc.ChatChoicesStreamService'],
53
58
  ChatChoicesStreamServiceBackendProvider,
54
59
  ):
55
60
  def provide_backend(self) -> ta.AsyncContextManager['mc.ChatChoicesStreamService']:
@@ -1,6 +1,9 @@
1
+ import typing as ta
2
+
1
3
  from omlish import inject as inj
2
4
  from omlish import lang
3
5
 
6
+ from ..... import minichain as mc
4
7
  from .injection import backend_configs
5
8
 
6
9
 
@@ -34,4 +37,16 @@ def bind_backends(
34
37
 
35
38
  #
36
39
 
40
+ async def catalog_backend_instantiator_provider(injector: inj.AsyncInjector) -> _catalog.CatalogBackendProvider.Instantiator: # noqa
41
+ async def inner(be: 'mc.BackendCatalog.Backend', cfgs: _types.BackendConfigs | None) -> ta.Any:
42
+ kwt = inj.build_kwargs_target(be.factory, non_strict=True)
43
+ kw = await injector.provide_kwargs(kwt)
44
+ return be.factory(*cfgs or [], **kw)
45
+
46
+ return _catalog.CatalogBackendProvider.Instantiator(inner)
47
+
48
+ els.append(inj.bind(_catalog.CatalogBackendProvider.Instantiator, to_async_fn=catalog_backend_instantiator_provider)) # noqa
49
+
50
+ #
51
+
37
52
  return inj.as_elements(*els)
@@ -21,7 +21,13 @@ class BackendCatalog(lang.Abstract):
21
21
  def get_backend(self, service_cls: type[T], name: str) -> Backend:
22
22
  raise NotImplementedError
23
23
 
24
- def new_backend(self, service_cls: ta.Any, name: str, *args: ta.Any, **kwargs: ta.Any) -> ta.Any:
24
+ def new_backend(
25
+ self,
26
+ service_cls: ta.Any,
27
+ name: str,
28
+ *args: ta.Any,
29
+ **kwargs: ta.Any,
30
+ ) -> ta.Any:
25
31
  be = self.get_backend(service_cls, name)
26
32
  return be.factory(*be.configs or [], *args, **kwargs)
27
33
 
@@ -46,9 +46,12 @@ class AnthropicChatChoicesService:
46
46
  def __init__(
47
47
  self,
48
48
  *configs: ApiKey | ModelName,
49
+ http_client: http.AsyncHttpClient | None = None,
49
50
  ) -> None:
50
51
  super().__init__()
51
52
 
53
+ self._http_client = http_client
54
+
52
55
  with tv.consume(*configs) as cc:
53
56
  self._api_key = check.not_none(ApiKey.pop_secret(cc, env='ANTHROPIC_API_KEY'))
54
57
  self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
@@ -88,7 +91,7 @@ class AnthropicChatChoicesService:
88
91
 
89
92
  raw_request = msh.marshal(a_req)
90
93
 
91
- raw_response = http.request(
94
+ raw_response = await http.async_request(
92
95
  'https://api.anthropic.com/v1/messages',
93
96
  headers={
94
97
  http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_JSON,
@@ -96,6 +99,7 @@ class AnthropicChatChoicesService:
96
99
  b'anthropic-version': b'2023-06-01',
97
100
  },
98
101
  data=json.dumps(raw_request).encode('utf-8'),
102
+ client=self._http_client,
99
103
  )
100
104
 
101
105
  response = json.loads(check.not_none(raw_response.data).decode('utf-8'))
@@ -39,9 +39,15 @@ from .protocol import build_protocol_tool
39
39
  # )
40
40
  @static_check_is_chat_choices_stream_service
41
41
  class AnthropicChatChoicesStreamService:
42
- def __init__(self, *configs: Config) -> None:
42
+ def __init__(
43
+ self,
44
+ *configs: Config,
45
+ http_client: http.AsyncHttpClient | None = None,
46
+ ) -> None:
43
47
  super().__init__()
44
48
 
49
+ self._http_client = http_client
50
+
45
51
  with tv.consume(*configs) as cc:
46
52
  self._model_name = cc.pop(AnthropicChatChoicesService.DEFAULT_MODEL_NAME)
47
53
  self._api_key = check.not_none(ApiKey.pop_secret(cc, env='ANTHROPIC_API_KEY'))
@@ -84,8 +90,8 @@ class AnthropicChatChoicesStreamService:
84
90
  )
85
91
 
86
92
  async with UseResources.or_new(request.options) as rs:
87
- http_client = rs.enter_context(http.client())
88
- http_response = rs.enter_context(http_client.stream_request(http_request))
93
+ http_client = await rs.enter_async_context(http.manage_async_client(self._http_client))
94
+ http_response = await rs.enter_async_context(await http_client.stream_request(http_request))
89
95
 
90
96
  async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs] | None:
91
97
  msg_start: AnthropicSseDecoderEvents.MessageStart | None = None
@@ -95,7 +101,7 @@ class AnthropicChatChoicesStreamService:
95
101
  db = DelimitingBuffer([b'\r', b'\n', b'\r\n'])
96
102
  sd = sse.SseDecoder()
97
103
  while True:
98
- b = http_response.stream.read1(self.READ_CHUNK_SIZE)
104
+ b = await http_response.stream.read1(self.READ_CHUNK_SIZE)
99
105
  for l in db.feed(b):
100
106
  if isinstance(l, DelimitingBuffer.Incomplete):
101
107
  # FIXME: handle
@@ -40,9 +40,15 @@ from .tools import build_tool_spec_schema
40
40
  class GoogleChatChoicesService:
41
41
  DEFAULT_MODEL_NAME: ta.ClassVar[ModelName] = ModelName(check.not_none(MODEL_NAMES.default))
42
42
 
43
- def __init__(self, *configs: ApiKey | ModelName) -> None:
43
+ def __init__(
44
+ self,
45
+ *configs: ApiKey | ModelName,
46
+ http_client: http.AsyncHttpClient | None = None,
47
+ ) -> None:
44
48
  super().__init__()
45
49
 
50
+ self._http_client = http_client
51
+
46
52
  with tv.consume(*configs) as cc:
47
53
  self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
48
54
  self._api_key = ApiKey.pop_secret(cc, env='GEMINI_API_KEY')
@@ -149,11 +155,12 @@ class GoogleChatChoicesService:
149
155
 
150
156
  model_name = MODEL_NAMES.resolve(self._model_name.v)
151
157
 
152
- resp = http.request(
158
+ resp = await http.async_request(
153
159
  f'{self.BASE_URL.rstrip("/")}/{model_name}:generateContent?key={key}',
154
160
  headers={'Content-Type': 'application/json'},
155
161
  data=json.dumps_compact(req_dct).encode('utf-8'),
156
162
  method='POST',
163
+ client=self._http_client,
157
164
  )
158
165
 
159
166
  resp_dct = json.loads(check.not_none(resp.data).decode('utf-8'))
@@ -82,12 +82,16 @@ class CseSearchService:
82
82
  self,
83
83
  cse_id: str | None = None,
84
84
  cse_api_key: str | None = None,
85
+ *,
86
+ http_client: http.AsyncHttpClient | None = None,
85
87
  ) -> None:
86
88
  super().__init__()
87
89
 
88
90
  self._cse_id = cse_id
89
91
  self._cse_api_key = cse_api_key
90
92
 
93
+ self._http_client = http_client
94
+
91
95
  async def invoke(
92
96
  self,
93
97
  request: SearchRequest,
@@ -97,8 +101,9 @@ class CseSearchService:
97
101
  cx=check.non_empty_str(self._cse_id),
98
102
  q=request.v,
99
103
  ))
100
- resp = http.request(
104
+ resp = await http.async_request(
101
105
  f'https://www.googleapis.com/customsearch/v1?{qs}',
106
+ client=self._http_client,
102
107
  )
103
108
  out = check.not_none(resp.data)
104
109
 
@@ -46,9 +46,15 @@ from .tools import build_tool_spec_schema
46
46
  class GoogleChatChoicesStreamService:
47
47
  DEFAULT_MODEL_NAME: ta.ClassVar[ModelName] = ModelName(check.not_none(MODEL_NAMES.default))
48
48
 
49
- def __init__(self, *configs: ApiKey | ModelName) -> None:
49
+ def __init__(
50
+ self,
51
+ *configs: ApiKey | ModelName,
52
+ http_client: http.AsyncHttpClient | None = None,
53
+ ) -> None:
50
54
  super().__init__()
51
55
 
56
+ self._http_client = http_client
57
+
52
58
  with tv.consume(*configs) as cc:
53
59
  self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
54
60
  self._api_key = ApiKey.pop_secret(cc, env='GEMINI_API_KEY')
@@ -163,13 +169,13 @@ class GoogleChatChoicesStreamService:
163
169
  )
164
170
 
165
171
  async with UseResources.or_new(request.options) as rs:
166
- http_client = rs.enter_context(http.client())
167
- http_response = rs.enter_context(http_client.stream_request(http_request))
172
+ http_client = await rs.enter_async_context(http.manage_async_client(self._http_client))
173
+ http_response = await rs.enter_async_context(await http_client.stream_request(http_request))
168
174
 
169
175
  async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs] | None:
170
176
  db = DelimitingBuffer([b'\r', b'\n', b'\r\n'])
171
177
  while True:
172
- b = http_response.stream.read1(self.READ_CHUNK_SIZE)
178
+ b = await http_response.stream.read1(self.READ_CHUNK_SIZE)
173
179
  for bl in db.feed(b):
174
180
  if isinstance(bl, DelimitingBuffer.Incomplete):
175
181
  # FIXME: handle
@@ -40,10 +40,16 @@ class MistralChatChoicesService:
40
40
  AiMessage: 'assistant',
41
41
  }
42
42
 
43
- def __init__(self, *, api_key: str | None = None) -> None:
43
+ def __init__(
44
+ self,
45
+ *,
46
+ api_key: str | None = None,
47
+ http_client: http.AsyncHttpClient | None = None,
48
+ ) -> None:
44
49
  super().__init__()
45
50
 
46
51
  self._api_key = api_key
52
+ self._http_client = http_client
47
53
 
48
54
  def _get_msg_content(self, m: Message) -> str | None:
49
55
  if isinstance(m, AiMessage):
@@ -73,7 +79,7 @@ class MistralChatChoicesService:
73
79
  ],
74
80
  }
75
81
 
76
- resp = http.request(
82
+ resp = await http.async_request(
77
83
  'https://api.mistral.ai/v1/chat/completions',
78
84
  method='POST',
79
85
  data=json.dumps_compact(req_dct).encode('utf-8'),
@@ -82,6 +88,7 @@ class MistralChatChoicesService:
82
88
  'Accept': 'application/json',
83
89
  'Authorization': f'Bearer {key}',
84
90
  },
91
+ client=self._http_client,
85
92
  )
86
93
 
87
94
  if resp.status == 429:
@@ -66,7 +66,7 @@ class BaseOllamaChatChoicesService(lang.Abstract):
66
66
 
67
67
  #
68
68
 
69
- ROLE_MAP: ta.ClassVar[ta.Mapping[type[Message], pt.Role]] = {
69
+ ROLE_MAP: ta.ClassVar[ta.Mapping[type[Message], pt.Role]] = { # noqa
70
70
  SystemMessage: 'system',
71
71
  UserMessage: 'user',
72
72
  AiMessage: 'assistant',
@@ -42,9 +42,15 @@ from .names import MODEL_NAMES
42
42
  class OpenaiChatChoicesService:
43
43
  DEFAULT_MODEL_NAME: ta.ClassVar[ModelName] = ModelName(check.not_none(MODEL_NAMES.default))
44
44
 
45
- def __init__(self, *configs: ApiKey | ModelName | DefaultOptions) -> None:
45
+ def __init__(
46
+ self,
47
+ *configs: ApiKey | ModelName | DefaultOptions,
48
+ http_client: http.AsyncHttpClient | None = None,
49
+ ) -> None:
46
50
  super().__init__()
47
51
 
52
+ self._http_client = http_client
53
+
48
54
  with tv.consume(*configs) as cc:
49
55
  self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
50
56
  self._api_key = ApiKey.pop_secret(cc, env='OPENAI_API_KEY')
@@ -68,13 +74,14 @@ class OpenaiChatChoicesService:
68
74
 
69
75
  raw_request = msh.marshal(rh.oai_request())
70
76
 
71
- http_response = http.request(
77
+ http_response = await http.async_request(
72
78
  'https://api.openai.com/v1/chat/completions',
73
79
  headers={
74
80
  http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_JSON,
75
81
  http.consts.HEADER_AUTH: http.consts.format_bearer_auth_header(check.not_none(self._api_key).reveal()),
76
82
  },
77
83
  data=json.dumps(raw_request).encode('utf-8'),
84
+ client=self._http_client,
78
85
  )
79
86
 
80
87
  raw_response = json.loads(check.not_none(http_response.data).decode('utf-8'))
@@ -23,9 +23,15 @@ from ....standard import ApiKey
23
23
  class OpenaiCompletionService:
24
24
  DEFAULT_MODEL_NAME: ta.ClassVar[str] = 'gpt-3.5-turbo-instruct'
25
25
 
26
- def __init__(self, *configs: Config) -> None:
26
+ def __init__(
27
+ self,
28
+ *configs: Config,
29
+ http_client: http.AsyncHttpClient | None = None,
30
+ ) -> None:
27
31
  super().__init__()
28
32
 
33
+ self._http_client = http_client
34
+
29
35
  with tv.consume(*configs) as cc:
30
36
  self._api_key = ApiKey.pop_secret(cc, env='OPENAI_API_KEY')
31
37
 
@@ -41,13 +47,14 @@ class OpenaiCompletionService:
41
47
  stream=False,
42
48
  )
43
49
 
44
- raw_response = http.request(
50
+ raw_response = await http.async_request(
45
51
  'https://api.openai.com/v1/completions',
46
52
  headers={
47
53
  http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_JSON,
48
54
  http.consts.HEADER_AUTH: http.consts.format_bearer_auth_header(check.not_none(self._api_key).reveal()),
49
55
  },
50
56
  data=json.dumps(raw_request).encode('utf-8'),
57
+ client=self._http_client,
51
58
  )
52
59
 
53
60
  response = json.loads(check.not_none(raw_response.data).decode('utf-8'))
@@ -22,9 +22,15 @@ from ....vectors.types import Vector
22
22
  class OpenaiEmbeddingService:
23
23
  model = 'text-embedding-3-small'
24
24
 
25
- def __init__(self, *configs: Config) -> None:
25
+ def __init__(
26
+ self,
27
+ *configs: Config,
28
+ http_client: http.AsyncHttpClient | None = None,
29
+ ) -> None:
26
30
  super().__init__()
27
31
 
32
+ self._http_client = http_client
33
+
28
34
  with tv.consume(*configs) as cc:
29
35
  self._api_key = ApiKey.pop_secret(cc, env='OPENAI_API_KEY')
30
36
 
@@ -34,13 +40,14 @@ class OpenaiEmbeddingService:
34
40
  input=check.isinstance(request.v, str),
35
41
  )
36
42
 
37
- raw_response = http.request(
43
+ raw_response = await http.async_request(
38
44
  'https://api.openai.com/v1/embeddings',
39
45
  headers={
40
46
  http.consts.HEADER_CONTENT_TYPE: http.consts.CONTENT_TYPE_JSON,
41
47
  http.consts.HEADER_AUTH: http.consts.format_bearer_auth_header(check.not_none(self._api_key).reveal()),
42
48
  },
43
49
  data=json.dumps(raw_request).encode('utf-8'),
50
+ client=self._http_client,
44
51
  )
45
52
 
46
53
  response = json.loads(check.not_none(raw_response.data).decode('utf-8'))
@@ -41,9 +41,15 @@ from .names import MODEL_NAMES
41
41
  # )
42
42
  @static_check_is_chat_choices_stream_service
43
43
  class OpenaiChatChoicesStreamService:
44
- def __init__(self, *configs: Config) -> None:
44
+ def __init__(
45
+ self,
46
+ *configs: Config,
47
+ http_client: http.AsyncHttpClient | None = None,
48
+ ) -> None:
45
49
  super().__init__()
46
50
 
51
+ self._http_client = http_client
52
+
47
53
  with tv.consume(*configs) as cc:
48
54
  self._model_name = cc.pop(OpenaiChatChoicesService.DEFAULT_MODEL_NAME)
49
55
  self._api_key = ApiKey.pop_secret(cc, env='OPENAI_API_KEY')
@@ -81,14 +87,14 @@ class OpenaiChatChoicesStreamService:
81
87
  )
82
88
 
83
89
  async with UseResources.or_new(request.options) as rs:
84
- http_client = rs.enter_context(http.client())
85
- http_response = rs.enter_context(http_client.stream_request(http_request))
90
+ http_client = await rs.enter_async_context(http.manage_async_client(self._http_client))
91
+ http_response = await rs.enter_async_context(await http_client.stream_request(http_request))
86
92
 
87
93
  async def inner(sink: StreamResponseSink[AiChoicesDeltas]) -> ta.Sequence[ChatChoicesOutputs]:
88
94
  db = DelimitingBuffer([b'\r', b'\n', b'\r\n'])
89
95
  sd = sse.SseDecoder()
90
96
  while True:
91
- b = http_response.stream.read1(self.READ_CHUNK_SIZE)
97
+ b = await http_response.stream.read1(self.READ_CHUNK_SIZE)
92
98
  for l in db.feed(b):
93
99
  if isinstance(l, DelimitingBuffer.Incomplete):
94
100
  # FIXME: handle
ommlds/tools/git.py CHANGED
@@ -16,6 +16,7 @@ from omdev.tools.git.messages import GitMessageGenerator
16
16
  from omlish import check
17
17
  from omlish import lang
18
18
  from omlish.configs.classes import Configurable
19
+ from omlish.http import all as http
19
20
  from omlish.subprocesses.sync import subprocesses
20
21
 
21
22
  from .. import minichain as mc
@@ -76,7 +77,9 @@ class OpenaiGitAiBackend(GitAiBackend['OpenaiGitAiBackend.Config']):
76
77
  if (sec := load_secrets().try_get(key.lower())) is not None:
77
78
  os.environ[key] = sec.reveal()
78
79
 
79
- llm = OpenaiChatChoicesService()
80
+ llm = OpenaiChatChoicesService(
81
+ http_client=http.SyncAsyncHttpClient(http.client()),
82
+ )
80
83
 
81
84
  resp = lang.sync_await(llm.invoke(mc.ChatChoicesRequest(
82
85
  [mc.UserMessage(prompt)],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommlds
3
- Version: 0.0.0.dev469
3
+ Version: 0.0.0.dev471
4
4
  Summary: ommlds
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,8 +14,8 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: omdev==0.0.0.dev469
18
- Requires-Dist: omlish==0.0.0.dev469
17
+ Requires-Dist: omdev==0.0.0.dev471
18
+ Requires-Dist: omlish==0.0.0.dev471
19
19
  Provides-Extra: all
20
20
  Requires-Dist: llama-cpp-python~=0.3; extra == "all"
21
21
  Requires-Dist: mlx~=0.29; extra == "all"
@@ -1,13 +1,13 @@
1
- ommlds/.omlish-manifests.json,sha256=K1CQFRaaQ43_zlr1ekl2h-CMXQ_U9zA0xBIOB-e_u-8,21555
1
+ ommlds/.omlish-manifests.json,sha256=nVhqSv9iQ2zu3MpOtJC2mFH5ORyzIC2K8kCAwDEdzGE,21555
2
2
  ommlds/__about__.py,sha256=t2rQF0yXpWFcCb2dvgzGR3I35HKGvGSn-EfhaUWVl5s,1759
3
3
  ommlds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- ommlds/huggingface.py,sha256=JfEyfKOxU3-SY_ojtXBJFNeD-NIuKjvMe3GL3e93wNA,1175
5
4
  ommlds/_hacks/__init__.py,sha256=ajfw7dMKH8UuloeQ5MSxWwgAmdWf2v8gm-K3uLP9wtY,196
6
5
  ommlds/_hacks/funcs.py,sha256=8XseIblP7yolDUD7WQSGn1LP90IQzByVejSzphAPDyM,2861
7
6
  ommlds/_hacks/names.py,sha256=01XSF-Rd0nLGb7oA0Jg1R9MtkOk0jfUhIO5CPyA-s6M,4690
8
7
  ommlds/_hacks/params.py,sha256=FihwXN6RAvQR1HqEemTRL_ivEr8WOlirH1sZ-lM3vgM,1725
9
8
  ommlds/_hacks/patches.py,sha256=Dsz4GcgRXd1zi18jiDO2C_8IF12VTsysjthiOQz-h80,1871
10
9
  ommlds/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ ommlds/backends/huggingface.py,sha256=JfEyfKOxU3-SY_ojtXBJFNeD-NIuKjvMe3GL3e93wNA,1175
11
11
  ommlds/backends/anthropic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  ommlds/backends/anthropic/protocol/__init__.py,sha256=bWNQbfEt7jLss6s03c0sBRCsx32POdgkO5VeNe0K3SU,132
13
13
  ommlds/backends/anthropic/protocol/_marshal.py,sha256=RHbwekaw21lTS_1KBX9z6dLpbmWmyYUE5j6Uyq1tn0w,539
@@ -99,8 +99,8 @@ ommlds/cli/sessions/chat/driver.py,sha256=ddnCYTKqWiPxV8U4UbFwb7E3yi81ItjZ9j3AJd
99
99
  ommlds/cli/sessions/chat/inject.py,sha256=7Yg6wUs2Oej4UjNZCAWCJCEsDJZWvT4G8XvkvVUMC7U,1928
100
100
  ommlds/cli/sessions/chat/session.py,sha256=eqwelLE74JFC-fBpk_hdwMD2nP4pLv3ZPwUn99200B8,521
101
101
  ommlds/cli/sessions/chat/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
- ommlds/cli/sessions/chat/backends/catalog.py,sha256=-mth_gw2MTnlClGVIdjiOJn1g4B6G9SqZDsmg5Rg70Y,1764
103
- ommlds/cli/sessions/chat/backends/inject.py,sha256=VbZ-Fb679kTItRpAhIYCqSM8vXUFeRDQWssUfrFgGi8,882
102
+ ommlds/cli/sessions/chat/backends/catalog.py,sha256=hIY0L1zewuJX0_xxcMcy4gylSLiQENB3YxgYJEoKgrU,2109
103
+ ommlds/cli/sessions/chat/backends/inject.py,sha256=v_kw6lOMo5XoAf2dyIld2oBjg7lVbS2ndmdPQv4F464,1558
104
104
  ommlds/cli/sessions/chat/backends/injection.py,sha256=GCn5OvNIEowgB70kQVuU84z3i8lLA4vOVkTZlQG8s0o,327
105
105
  ommlds/cli/sessions/chat/backends/types.py,sha256=5eImYHXLKqbC5MDrN443eMGamP9snCmV1n7LtAsqgPk,696
106
106
  ommlds/cli/sessions/chat/chat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -170,24 +170,24 @@ ommlds/minichain/types.py,sha256=K6RRjpUi17UEG0cqPrrvbVANU0iRVh3WLiH-y6oEWFI,414
170
170
  ommlds/minichain/utils.py,sha256=NTsBu_pSZnLdZc1R1Se70rb_9J-IoB6VRwjhwzh3PwY,490
171
171
  ommlds/minichain/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
172
  ommlds/minichain/backends/catalogs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- ommlds/minichain/backends/catalogs/base.py,sha256=TNdFrYYFEwp-rbmp-VHxUKIFCiVYhFPcu4PNhSaEHMA,1239
173
+ ommlds/minichain/backends/catalogs/base.py,sha256=6ThxF-OozMm0aGHAo3UyKUcNA3TVda0w_QLpbz7XmEU,1306
174
174
  ommlds/minichain/backends/catalogs/simple.py,sha256=T6GeY902XPRjNnwX1AivunpkirLyxFg5rG2V2LA0Puo,1501
175
175
  ommlds/minichain/backends/catalogs/strings.py,sha256=IHid5yRbHvkU5O5ypSMWAPcETLlvj1CXeIJ3mHrDyi8,1768
176
176
  ommlds/minichain/backends/impls/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
- ommlds/minichain/backends/impls/mistral.py,sha256=I_HTwXqAoQi2xyw_nLTeUamtOZLLl-oQZ234AVJZZLA,2649
177
+ ommlds/minichain/backends/impls/mistral.py,sha256=nC0aqabg-I7JJyxHHMZASASksqV1at7nJWZHGtCwfio,2843
178
178
  ommlds/minichain/backends/impls/sqlite.py,sha256=NOFm_fgr-OZ8mo7etj0zwvxsDnidRwKzhdDom58e6ks,2157
179
179
  ommlds/minichain/backends/impls/anthropic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
180
- ommlds/minichain/backends/impls/anthropic/chat.py,sha256=LVaRP_Pbz4UghSHD8GZ22hMWE4Rsd_6bSysgl2BR_AM,4166
180
+ ommlds/minichain/backends/impls/anthropic/chat.py,sha256=-qGr_DZgGe-dr1AKb6WLtCq_I2E9635X1rQZSJqOb04,4318
181
181
  ommlds/minichain/backends/impls/anthropic/names.py,sha256=GPPeYt0CcDcDCR8I6BMd7bMjC_Zk_bjnLLpF9ClwXcg,1099
182
182
  ommlds/minichain/backends/impls/anthropic/protocol.py,sha256=whPVYuKShKiMCzasHl77sCIiymhzXj8mFZXEyhZvld8,3292
183
- ommlds/minichain/backends/impls/anthropic/stream.py,sha256=4xa1LYsa1LLGYWlP2-RMk1ll4eyikkjlfJZ1fU5EEPM,8580
183
+ ommlds/minichain/backends/impls/anthropic/stream.py,sha256=ePgAz1QyuUcqSLiJTmP2IeW7jZagOMYceWmnvTTHBa8,8779
184
184
  ommlds/minichain/backends/impls/duckduckgo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
185
  ommlds/minichain/backends/impls/duckduckgo/search.py,sha256=igzeU9P9b1MMiu4KAJVS9H6KLIoPm68wXi4Kx3_DHyQ,940
186
186
  ommlds/minichain/backends/impls/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
187
- ommlds/minichain/backends/impls/google/chat.py,sha256=q6LasmAh3Xn78kNlgpgwoKhdTj3o76j0X3_xitdyAE0,6316
187
+ ommlds/minichain/backends/impls/google/chat.py,sha256=lGb5blGLlcBlt9xeDZJvbh5SlV7fgfezd5_As_SPBXo,6499
188
188
  ommlds/minichain/backends/impls/google/names.py,sha256=HxHJ31HeKZg6aW1C_Anqp-gamCXpq9pOdKj8_yVgE8Y,871
189
- ommlds/minichain/backends/impls/google/search.py,sha256=5-2nAZ1QmbqHSQcwWnqqcgCM-Duy2ryctJEIv2tcpZg,3260
190
- ommlds/minichain/backends/impls/google/stream.py,sha256=8k-8OfX4EuGtRewKx7VFLVeH3YAuF5t6EWVSoH8-VPU,7803
189
+ ommlds/minichain/backends/impls/google/search.py,sha256=y5_6seSRU8CFnLA_Ja8XEMbIBWSgwBzE1iBf-qyz0tA,3427
190
+ ommlds/minichain/backends/impls/google/stream.py,sha256=lAxPZkFLkeBB8rNvnv5wEvK6aPqAfyAssukMA8QQz7s,8002
191
191
  ommlds/minichain/backends/impls/google/tools.py,sha256=Tty0gsyx7-PbeoNqMuql_ewQ6q-ZsDaDdsD5ShinGVY,5089
192
192
  ommlds/minichain/backends/impls/huggingface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
193
193
  ommlds/minichain/backends/impls/huggingface/configs.py,sha256=6jsBtPNXOP57PcpxNTVLGWLc-18Iwn_lDbGouwCJTIQ,258
@@ -200,14 +200,14 @@ ommlds/minichain/backends/impls/llamacpp/stream.py,sha256=uzrXr2HhshgFe3Z0g8KTPc
200
200
  ommlds/minichain/backends/impls/mlx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  ommlds/minichain/backends/impls/mlx/chat.py,sha256=sMlhgiFZrxAC-kKkLSJ6c-2uJn0IHZXH4EiPET_-CKI,7458
202
202
  ommlds/minichain/backends/impls/ollama/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
- ommlds/minichain/backends/impls/ollama/chat.py,sha256=l9agVFvVmB0j8SaE62Yx2ItiR55HOVnKDrFPTXltP9E,6590
203
+ ommlds/minichain/backends/impls/ollama/chat.py,sha256=3fuIAsIW20aEAOLLfM21d5ju27igr6N-3Lf9nNUWcoY,6598
204
204
  ommlds/minichain/backends/impls/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
- ommlds/minichain/backends/impls/openai/chat.py,sha256=eMRjxPNrzrRjaw83LJuYzP9DGvwGyY2ObJSZub4Z9bY,2658
206
- ommlds/minichain/backends/impls/openai/completion.py,sha256=0XTC08mZzbW23Y2DNW2xfRR0eDX4nTyejF8CR1BdHZs,1756
207
- ommlds/minichain/backends/impls/openai/embedding.py,sha256=kkDJ3_0EqwQ_E0eXsSH1TuWXQmRqaijK8zG90fnlf3s,1582
205
+ ommlds/minichain/backends/impls/openai/chat.py,sha256=QcQZO78p4UUzI4QU1K-057OEZGKIYxjXENhkifsSuaI,2841
206
+ ommlds/minichain/backends/impls/openai/completion.py,sha256=4Mi4Zvrq5fCqUd0asL3WiCbCdmxOdo0NFkoZMfdsYXY,1939
207
+ ommlds/minichain/backends/impls/openai/embedding.py,sha256=BNtvKYLTsnQwQR9Tv3Fr8zCYN1kr1UNdJ15lcsjz6X0,1765
208
208
  ommlds/minichain/backends/impls/openai/format.py,sha256=teGX8mNU3sXNWP4YWGD8d59M4X9_r75ImSzfTJgtNCM,7351
209
209
  ommlds/minichain/backends/impls/openai/names.py,sha256=b74t8FwSbGEveVtVz4SqM5tiRDyTKNlUKlseV6AX3Yo,1211
210
- ommlds/minichain/backends/impls/openai/stream.py,sha256=AkALgjkALmWd3FaeXdLlPilI8JiW4lpJdknISt0gS-4,5200
210
+ ommlds/minichain/backends/impls/openai/stream.py,sha256=pm-iUNjw5o94LrnrbAWttfbpxStnq0vDvrE7FV9fdsM,5399
211
211
  ommlds/minichain/backends/impls/sentencepiece/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
212
212
  ommlds/minichain/backends/impls/sentencepiece/tokens.py,sha256=tUEBKyBgkTowssS_AdcAuPkyFzfyDfE935x4JG8PXM0,1602
213
213
  ommlds/minichain/backends/impls/tinygrad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -363,7 +363,7 @@ ommlds/server/client.py,sha256=4CeYj43nHwUmuxwD4lkAZjcaPlrWw7MDdenldj377IU,1735
363
363
  ommlds/server/server.py,sha256=8l6jPEvUMrTd7iLUOGcUUzXWYA7l1ZzI2lkA8XqGOBA,4205
364
364
  ommlds/server/service.py,sha256=WleUNyWqcnvZ_CNk6h1WVSTy1_xT9wJg4dduiJilGDY,2282
365
365
  ommlds/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
366
- ommlds/tools/git.py,sha256=3MWI5cZ9ZmsjNMEoQXwj-AZNYyzA2xp1srFjzUv7U1Y,8095
366
+ ommlds/tools/git.py,sha256=ILvsOFXbdDQvAHvGCSbd2fY4fswmDRXaB8yVDQymLY0,8205
367
367
  ommlds/tools/ocr.py,sha256=UP2XK4-ELyhK2BnuBr7-DwUbkDIcX9xdvfXVimM19Y8,1839
368
368
  ommlds/wiki/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
369
369
  ommlds/wiki/analyze.py,sha256=38SvHF0X_z8OkjvbBc5tLj35e9pvqi53yg9tls-ay5A,9544
@@ -377,9 +377,9 @@ ommlds/wiki/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
377
377
  ommlds/wiki/utils/io.py,sha256=UKgDJGtmpnWvIqVd2mJc2QNPOqlToEY1GEveNp6_pMo,7088
378
378
  ommlds/wiki/utils/progress.py,sha256=EhvKcMFYtsarCQhIahlO6f0SboyAKP3UwUyrnVnP-Vk,3222
379
379
  ommlds/wiki/utils/xml.py,sha256=vVV8Ctn13aaRM9eYfs9Wd6rHn5WOCEUzQ44fIhOvJdg,3754
380
- ommlds-0.0.0.dev469.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
381
- ommlds-0.0.0.dev469.dist-info/METADATA,sha256=DpB16y8YfJ2LGRK-RKtvFKjVZq0GVA4U1dd_eu2rUP4,3224
382
- ommlds-0.0.0.dev469.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
383
- ommlds-0.0.0.dev469.dist-info/entry_points.txt,sha256=Z5YWtX7ClfiCKdW-dd_CSVvM0h4yQpJPi-2G3q6gNFo,35
384
- ommlds-0.0.0.dev469.dist-info/top_level.txt,sha256=Rbnk5d5wi58vnAXx13WFZqdQ4VX8hBCS2hEL3WeXOhY,7
385
- ommlds-0.0.0.dev469.dist-info/RECORD,,
380
+ ommlds-0.0.0.dev471.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
381
+ ommlds-0.0.0.dev471.dist-info/METADATA,sha256=LkBuJPbOfsJ3uAgR2Gnf55KSQoyAXPWFRkUaWNGsBns,3224
382
+ ommlds-0.0.0.dev471.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
383
+ ommlds-0.0.0.dev471.dist-info/entry_points.txt,sha256=Z5YWtX7ClfiCKdW-dd_CSVvM0h4yQpJPi-2G3q6gNFo,35
384
+ ommlds-0.0.0.dev471.dist-info/top_level.txt,sha256=Rbnk5d5wi58vnAXx13WFZqdQ4VX8hBCS2hEL3WeXOhY,7
385
+ ommlds-0.0.0.dev471.dist-info/RECORD,,
File without changes