ommlds 0.0.0.dev465__py3-none-any.whl → 0.0.0.dev466__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.

@@ -63,7 +63,7 @@
63
63
  "module": ".minichain.backends.impls.anthropic.stream",
64
64
  "attr": null,
65
65
  "file": "ommlds/minichain/backends/impls/anthropic/stream.py",
66
- "line": 35,
66
+ "line": 36,
67
67
  "value": {
68
68
  "!.minichain.registries.manifests.RegistryManifest": {
69
69
  "module": "ommlds.minichain.backends.impls.anthropic.stream",
@@ -137,7 +137,7 @@
137
137
  "module": ".minichain.backends.impls.google.stream",
138
138
  "attr": null,
139
139
  "file": "ommlds/minichain/backends/impls/google/stream.py",
140
- "line": 36,
140
+ "line": 41,
141
141
  "value": {
142
142
  "!.minichain.registries.manifests.RegistryManifest": {
143
143
  "module": "ommlds.minichain.backends.impls.google.stream",
@@ -148,11 +148,14 @@ class Part(lang.Final):
148
148
  video_metadata: VideoMetadata | None = None
149
149
 
150
150
 
151
+ ContentRole: ta.TypeAlias = ta.Literal['user', 'model']
152
+
153
+
151
154
  @dc.dataclass(frozen=True, kw_only=True)
152
155
  @_set_class_marshal_options
153
156
  class Content(lang.Final):
154
157
  parts: ta.Sequence[Part] | None = None
155
- role: ta.Literal['user', 'model'] | None = None
158
+ role: ContentRole | None = None
156
159
 
157
160
 
158
161
  ##
@@ -63,19 +63,17 @@ class ChatChoicesStreamServiceStreamAiChatGenerator(StreamAiChatGenerator):
63
63
  ) -> mc.AiChat:
64
64
  opts = self._options() if self._options is not None else []
65
65
 
66
- lst: list[str] = []
67
-
68
66
  async with self._service_provider.provide_backend() as service:
67
+ joiner = mc.AiChoiceDeltaJoiner()
68
+
69
69
  async with (await service.invoke(mc.ChatChoicesStreamRequest(chat, opts))).v as st_resp:
70
70
  async for o in st_resp:
71
+ joiner.add(o.choices)
72
+
71
73
  choice = check.single(o.choices)
72
74
 
73
75
  for delta in choice.deltas:
74
76
  if delta_callback is not None:
75
77
  await delta_callback(delta)
76
78
 
77
- c = check.isinstance(delta, mc.ContentAiChoiceDelta).c # noqa
78
- if c is not None:
79
- lst.append(check.isinstance(c, str))
80
-
81
- return [mc.AiMessage(''.join(lst))]
79
+ return check.single(joiner.build())
@@ -92,6 +92,10 @@ with _lang.auto_proxy_init(
92
92
  ChatChoicesStreamServiceChatChoicesService,
93
93
  )
94
94
 
95
+ from .chat.stream.joining import ( # noqa
96
+ AiChoiceDeltaJoiner,
97
+ )
98
+
95
99
  from .chat.stream.services import ( # noqa
96
100
  ChatChoicesStreamRequest,
97
101
  ChatChoicesStreamResponse,
@@ -109,7 +113,9 @@ with _lang.auto_proxy_init(
109
113
 
110
114
  AiChoiceDelta,
111
115
  ContentAiChoiceDelta,
116
+ AnyToolUseAiChoiceDelta,
112
117
  ToolUseAiChoiceDelta,
118
+ PartialToolUseAiChoiceDelta,
113
119
 
114
120
  AiChoiceDeltas,
115
121
  AiChoicesDeltas,
@@ -17,6 +17,7 @@ from ....chat.stream.services import static_check_is_chat_choices_stream_service
17
17
  from ....chat.stream.types import AiChoiceDeltas
18
18
  from ....chat.stream.types import AiChoicesDeltas
19
19
  from ....chat.stream.types import ContentAiChoiceDelta
20
+ from ....chat.stream.types import PartialToolUseAiChoiceDelta
20
21
  from ....chat.tools.types import Tool
21
22
  from ....configs import Config
22
23
  from ....resources import UseResources
@@ -123,19 +124,35 @@ class AnthropicChatChoicesStreamService:
123
124
  check.not_none(msg_start)
124
125
  check.none(cbk_start)
125
126
  cbk_start = ae
127
+
126
128
  if isinstance(ae.content_block, AnthropicSseDecoderEvents.ContentBlockStart.Text): # noqa
127
129
  await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiChoiceDelta(
128
130
  ae.content_block.text,
129
131
  )])]))
132
+
133
+ elif isinstance(ae.content_block, AnthropicSseDecoderEvents.ContentBlockStart.ToolUse): # noqa
134
+ await sink.emit(AiChoicesDeltas([AiChoiceDeltas([PartialToolUseAiChoiceDelta( # noqa
135
+ id=ae.content_block.id,
136
+ name=ae.content_block.name,
137
+ raw_args=ae.content_block.input,
138
+ )])]))
139
+
130
140
  else:
131
141
  raise TypeError(ae.content_block)
132
142
 
133
143
  case AnthropicSseDecoderEvents.ContentBlockDelta():
134
144
  check.not_none(cbk_start)
145
+
135
146
  if isinstance(ae.delta, AnthropicSseDecoderEvents.ContentBlockDelta.TextDelta):
136
147
  await sink.emit(AiChoicesDeltas([AiChoiceDeltas([ContentAiChoiceDelta(
137
148
  ae.delta.text,
138
149
  )])]))
150
+
151
+ elif isinstance(ae.delta, AnthropicSseDecoderEvents.ContentBlockDelta.InputJsonDelta): # noqa
152
+ await sink.emit(AiChoicesDeltas([AiChoiceDeltas([PartialToolUseAiChoiceDelta( # noqa
153
+ raw_args=ae.delta.partial_json,
154
+ )])]))
155
+
139
156
  else:
140
157
  raise TypeError(ae.delta)
141
158
 
@@ -15,6 +15,8 @@ from ....chat.choices.types import ChatChoicesOutputs
15
15
  from ....chat.messages import AiMessage
16
16
  from ....chat.messages import Message
17
17
  from ....chat.messages import SystemMessage
18
+ from ....chat.messages import ToolUseMessage
19
+ from ....chat.messages import ToolUseResultMessage
18
20
  from ....chat.messages import UserMessage
19
21
  from ....chat.stream.services import ChatChoicesStreamRequest
20
22
  from ....chat.stream.services import ChatChoicesStreamResponse
@@ -22,12 +24,15 @@ from ....chat.stream.services import static_check_is_chat_choices_stream_service
22
24
  from ....chat.stream.types import AiChoiceDeltas
23
25
  from ....chat.stream.types import AiChoicesDeltas
24
26
  from ....chat.stream.types import ContentAiChoiceDelta
27
+ from ....chat.stream.types import ToolUseAiChoiceDelta
28
+ from ....chat.tools.types import Tool
25
29
  from ....models.configs import ModelName
26
30
  from ....resources import UseResources
27
31
  from ....standard import ApiKey
28
32
  from ....stream.services import StreamResponseSink
29
33
  from ....stream.services import new_stream_response
30
34
  from .names import MODEL_NAMES
35
+ from .tools import build_tool_spec_schema
31
36
 
32
37
 
33
38
  ##
@@ -48,22 +53,70 @@ class GoogleChatChoicesStreamService:
48
53
  self._model_name = cc.pop(self.DEFAULT_MODEL_NAME)
49
54
  self._api_key = ApiKey.pop_secret(cc, env='GEMINI_API_KEY')
50
55
 
51
- def _get_msg_content(self, m: Message) -> str | None:
52
- if isinstance(m, AiMessage):
53
- return check.isinstance(m.c, str)
56
+ def _make_str_content(
57
+ self,
58
+ s: str | None,
59
+ *,
60
+ role: pt.ContentRole | None = None,
61
+ ) -> pt.Content | None:
62
+ if s is None:
63
+ return None
64
+
65
+ return pt.Content(
66
+ parts=[pt.Part(
67
+ text=check.not_none(s),
68
+ )],
69
+ role=role,
70
+ )
54
71
 
55
- elif isinstance(m, (SystemMessage, UserMessage)):
56
- return check.isinstance(m.c, str)
72
+ def _make_msg_content(self, m: Message) -> pt.Content:
73
+ if isinstance(m, (AiMessage, SystemMessage, UserMessage)):
74
+ return check.not_none(self._make_str_content(
75
+ check.isinstance(m.c, str),
76
+ role=self.ROLES_MAP[type(m)],
77
+ ))
78
+
79
+ elif isinstance(m, ToolUseResultMessage):
80
+ tr_resp_val: pt.Value
81
+ if m.tur.c is None:
82
+ tr_resp_val = pt.NullValue() # type: ignore[unreachable]
83
+ elif isinstance(m.tur.c, str):
84
+ tr_resp_val = pt.StringValue(m.tur.c)
85
+ else:
86
+ raise TypeError(m.tur.c)
87
+ return pt.Content(
88
+ parts=[pt.Part(
89
+ function_response=pt.FunctionResponse(
90
+ id=m.tur.id,
91
+ name=m.tur.name,
92
+ response={
93
+ 'value': tr_resp_val,
94
+ },
95
+ ),
96
+ )],
97
+ )
98
+
99
+ elif isinstance(m, ToolUseMessage):
100
+ return pt.Content(
101
+ parts=[pt.Part(
102
+ function_call=pt.FunctionCall(
103
+ id=m.tu.id,
104
+ name=m.tu.name,
105
+ args=m.tu.args,
106
+ ),
107
+ )],
108
+ role='model',
109
+ )
57
110
 
58
111
  else:
59
112
  raise TypeError(m)
60
113
 
61
114
  BASE_URL: ta.ClassVar[str] = 'https://generativelanguage.googleapis.com/v1beta/models'
62
115
 
63
- ROLES_MAP: ta.ClassVar[ta.Mapping[type[Message], str]] = {
64
- SystemMessage: 'system',
116
+ ROLES_MAP: ta.ClassVar[ta.Mapping[type[Message], pt.ContentRole | None]] = { # noqa
117
+ SystemMessage: None,
65
118
  UserMessage: 'user',
66
- AiMessage: 'assistant',
119
+ AiMessage: 'model',
67
120
  }
68
121
 
69
122
  READ_CHUNK_SIZE = 64 * 1024
@@ -74,16 +127,28 @@ class GoogleChatChoicesStreamService:
74
127
  ) -> ChatChoicesStreamResponse:
75
128
  key = check.not_none(self._api_key).reveal()
76
129
 
130
+ msgs = list(request.v)
131
+
132
+ system_inst: pt.Content | None = None
133
+ if msgs and isinstance(m0 := msgs[0], SystemMessage):
134
+ system_inst = self._make_msg_content(m0)
135
+ msgs.pop(0)
136
+
137
+ g_tools: list[pt.Tool] = []
138
+ with tv.TypedValues(*request.options).consume() as oc:
139
+ t: Tool
140
+ for t in oc.pop(Tool, []):
141
+ g_tools.append(pt.Tool(
142
+ function_declarations=[build_tool_spec_schema(t.spec)],
143
+ ))
144
+
77
145
  g_req = pt.GenerateContentRequest(
78
146
  contents=[
79
- pt.Content(
80
- parts=[pt.Part(
81
- text=check.not_none(self._get_msg_content(m)),
82
- )],
83
- role=self.ROLES_MAP[type(m)], # type: ignore[arg-type]
84
- )
85
- for m in request.v
147
+ self._make_msg_content(m)
148
+ for m in msgs
86
149
  ],
150
+ tools=g_tools or None,
151
+ system_instruction=system_inst,
87
152
  )
88
153
 
89
154
  req_dct = msh.marshal(g_req)
@@ -110,18 +175,38 @@ class GoogleChatChoicesStreamService:
110
175
  if isinstance(bl, DelimitingBuffer.Incomplete):
111
176
  # FIXME: handle
112
177
  return []
178
+
113
179
  l = bl.decode('utf-8')
114
180
  if not l:
115
181
  continue
182
+
116
183
  if l.startswith('data: '):
117
184
  gcr = msh.unmarshal(json.loads(l[6:]), pt.GenerateContentResponse) # noqa
118
185
  cnd = check.single(check.not_none(gcr.candidates))
186
+
119
187
  for p in check.not_none(cnd.content).parts or []:
120
- await sink.emit(AiChoicesDeltas([
121
- AiChoiceDeltas([
122
- ContentAiChoiceDelta(check.not_none(p.text)),
123
- ]),
124
- ]))
188
+ if (txt := p.text) is not None:
189
+ check.none(p.function_call)
190
+ await sink.emit(AiChoicesDeltas([
191
+ AiChoiceDeltas([
192
+ ContentAiChoiceDelta(check.not_none(txt)),
193
+ ]),
194
+ ]))
195
+
196
+ elif (fc := p.function_call) is not None:
197
+ check.none(p.text)
198
+ await sink.emit(AiChoicesDeltas([
199
+ AiChoiceDeltas([
200
+ ToolUseAiChoiceDelta(
201
+ id=fc.id,
202
+ name=fc.name,
203
+ args=fc.args,
204
+ ),
205
+ ]),
206
+ ]))
207
+
208
+ else:
209
+ raise ValueError(p)
125
210
 
126
211
  if not b:
127
212
  return []
@@ -18,7 +18,9 @@ from ....chat.messages import SystemMessage
18
18
  from ....chat.messages import ToolUseMessage
19
19
  from ....chat.messages import ToolUseResultMessage
20
20
  from ....chat.messages import UserMessage
21
+ from ....chat.stream.types import AiChoiceDelta
21
22
  from ....chat.stream.types import ContentAiChoiceDelta
23
+ from ....chat.stream.types import PartialToolUseAiChoiceDelta
22
24
  from ....chat.tools.types import Tool
23
25
  from ....content.json import JsonContent
24
26
  from ....content.prepare import prepare_content_str
@@ -212,17 +214,20 @@ class OpenaiChatRequestHandler:
212
214
  ),
213
215
  )
214
216
 
215
- def build_ai_choice_delta(self, delta: ta.Mapping[str, ta.Any]) -> ContentAiChoiceDelta:
216
- return ContentAiChoiceDelta(
217
- check.not_none(delta.get('content')),
218
- # FIXME:
219
- # tool_exec_requests=[
220
- # ToolUse(
221
- # id=tc['id'],
222
- # spec=self._process_options().tools_by_name[tc['function']['name']],
223
- # args=json.loads(tc['function']['arguments'] or '{}'),
224
- # raw_args=tc['function']['arguments'],
225
- # )
226
- # for tc in message_or_delta.get('tool_calls', [])
227
- # ] or None,
228
- )
217
+ def build_ai_choice_delta(self, delta: ta.Mapping[str, ta.Any]) -> AiChoiceDelta:
218
+ if (c := delta.get('content')) is not None:
219
+ check.state(not delta.get('tool_calls'))
220
+ return ContentAiChoiceDelta(c)
221
+
222
+ elif (tcs := delta.get('tool_calls')) is not None: # noqa
223
+ check.state(delta.get('content') is None)
224
+ tc = check.single(tcs)
225
+ tc_fn = tc['function']
226
+ return PartialToolUseAiChoiceDelta(
227
+ id=tc.get('id'),
228
+ name=tc_fn.get('name'),
229
+ raw_args=tc_fn.get('arguments'),
230
+ )
231
+
232
+ else:
233
+ raise ValueError(delta)
@@ -1,22 +1,14 @@
1
- from omlish import check
2
1
  from omlish import dataclasses as dc
3
- from omlish import lang
4
2
 
5
3
  from ...services import Response
6
- from ...tools.types import ToolUse
7
4
  from ..choices.services import ChatChoicesRequest
8
5
  from ..choices.services import static_check_is_chat_choices_service
9
6
  from ..choices.types import AiChoice
10
7
  from ..choices.types import AiChoices
11
- from ..messages import AiMessage
12
- from ..messages import AnyAiMessage
13
- from ..messages import ToolUseMessage
8
+ from .joining import AiChoiceDeltaJoiner
14
9
  from .services import ChatChoicesOutputs
15
10
  from .services import ChatChoicesStreamOutputs
16
11
  from .services import ChatChoicesStreamService
17
- from .types import AiChoiceDelta
18
- from .types import ContentAiChoiceDelta
19
- from .types import ToolUseAiChoiceDelta
20
12
 
21
13
 
22
14
  ##
@@ -31,50 +23,13 @@ class ChatChoicesStreamServiceChatChoicesService:
31
23
  AiChoices,
32
24
  ChatChoicesOutputs | ChatChoicesStreamOutputs,
33
25
  ]:
34
- choice_lsts: list[list[list[str] | ToolUse]] = []
35
-
36
- def add(l: list[list[str] | ToolUse], d: AiChoiceDelta) -> None:
37
- if isinstance(d, ContentAiChoiceDelta):
38
- s = check.isinstance(d.c, str)
39
- if l and isinstance(l[-1], list):
40
- l[-1].append(s)
41
- else:
42
- l.append([s])
43
-
44
- elif isinstance(d, ToolUseAiChoiceDelta):
45
- l.append(d.tu)
46
-
47
- else:
48
- raise TypeError(d)
26
+ joiner = AiChoiceDeltaJoiner()
49
27
 
50
28
  async with (resp := await self.service.invoke(request)).v as it: # noqa
51
- i = -1 # noqa
52
- l: list[list[str] | ToolUse]
53
- async for i, cs in lang.async_enumerate(it):
54
- if i == 0:
55
- for c in cs.choices:
56
- choice_lsts.append(l := [])
57
- for d in c.deltas:
58
- add(l, d)
59
-
60
- else:
61
- for l, c in zip(choice_lsts, cs.choices, strict=True):
62
- for d in c.deltas:
63
- add(l, d)
29
+ async for cs in it:
30
+ joiner.add(cs.choices)
64
31
 
65
32
  # check.state(resp_v.is_done)
66
33
 
67
- ret: list[AiChoice] = []
68
- for cl in choice_lsts:
69
- cc: list[AnyAiMessage] = []
70
- for e in cl:
71
- if isinstance(e, list):
72
- cc.append(AiMessage(''.join(e)))
73
- elif isinstance(e, ToolUse):
74
- cc.append(ToolUseMessage(e))
75
- else:
76
- raise TypeError(e)
77
- ret.append(AiChoice(cc))
78
-
79
34
  # FIXME: outputs lol
80
- return Response(ret)
35
+ return Response([AiChoice(ms) for ms in joiner.build()])
@@ -0,0 +1,96 @@
1
+ import typing as ta
2
+
3
+ from omlish import check
4
+ from omlish.formats import json
5
+
6
+ from ...tools.types import ToolUse
7
+ from ..messages import AiChat
8
+ from ..messages import AiMessage
9
+ from ..messages import AnyAiMessage
10
+ from ..messages import ToolUseMessage
11
+ from .types import AiChoiceDelta
12
+ from .types import AiChoiceDeltas
13
+ from .types import ContentAiChoiceDelta
14
+ from .types import PartialToolUseAiChoiceDelta
15
+ from .types import ToolUseAiChoiceDelta
16
+
17
+
18
+ ##
19
+
20
+
21
+ class AiChoiceDeltaJoiner:
22
+ def __init__(self) -> None:
23
+ super().__init__()
24
+
25
+ self._seq = 0
26
+ self._channels: list[AiChoiceDeltaJoiner._Channel] = []
27
+
28
+ class _Channel(ta.NamedTuple):
29
+ deltas: list[AiChoiceDelta]
30
+ messages: list[AnyAiMessage]
31
+
32
+ def _build_joined(self, deltas: ta.Sequence[AiChoiceDelta]) -> AnyAiMessage:
33
+ dty = check.single(set(map(type, check.not_empty(deltas))))
34
+
35
+ if dty is ContentAiChoiceDelta:
36
+ cds = ta.cast(ta.Sequence[ContentAiChoiceDelta], deltas)
37
+ return AiMessage(''.join(check.isinstance(cd.c, str) for cd in cds))
38
+
39
+ elif dty is ToolUseAiChoiceDelta:
40
+ raise TypeError(dty)
41
+
42
+ elif dty is PartialToolUseAiChoiceDelta:
43
+ tds = ta.cast(ta.Sequence[PartialToolUseAiChoiceDelta], deltas)
44
+ for td in ta.cast(ta.Sequence[PartialToolUseAiChoiceDelta], deltas)[1:]:
45
+ check.none(td.id)
46
+ check.none(td.name)
47
+
48
+ ra = ''.join(filter(None, (td.raw_args for td in tds)))
49
+
50
+ return ToolUseMessage(ToolUse(
51
+ id=tds[0].id,
52
+ name=check.non_empty_str(tds[0].name),
53
+ args=json.loads(ra),
54
+ raw_args=ra,
55
+ ))
56
+
57
+ else:
58
+ raise TypeError(dty)
59
+
60
+ def _join_one(self, chan: _Channel) -> None:
61
+ if not chan.deltas:
62
+ return
63
+
64
+ chan.messages.append(self._build_joined(chan.deltas))
65
+ chan.deltas.clear()
66
+
67
+ def _add_to(self, chan: _Channel, d: AiChoiceDelta) -> None:
68
+ if chan.deltas and type(chan.deltas[0]) is not type(d):
69
+ self._join_one(chan)
70
+
71
+ if isinstance(d, ToolUseAiChoiceDelta):
72
+ chan.messages.append(ToolUseMessage(ToolUse(
73
+ id=d.id,
74
+ name=check.not_none(d.name),
75
+ args=d.args or {},
76
+ )))
77
+
78
+ else:
79
+ chan.deltas.append(d)
80
+
81
+ def add(self, choices: ta.Sequence[AiChoiceDeltas]) -> None:
82
+ if not self._seq:
83
+ check.empty(self._channels)
84
+ self._channels.extend(self._Channel([], []) for _ in range(len(choices)))
85
+
86
+ for chan, c in zip(self._channels, choices, strict=True):
87
+ for d in c.deltas:
88
+ self._add_to(chan, d)
89
+
90
+ self._seq += 1
91
+
92
+ def build(self) -> list[AiChat]:
93
+ for chan in self._channels:
94
+ self._join_one(chan)
95
+
96
+ return [list(chan.messages) for chan in self._channels]
@@ -6,7 +6,6 @@ from omlish import marshal as msh
6
6
 
7
7
  from ...content.types import Content
8
8
  from ...stream.services import StreamOptions
9
- from ...tools.types import ToolUse
10
9
  from ...types import Option
11
10
  from ...types import Output
12
11
  from ..choices.types import ChatChoicesOptions
@@ -48,9 +47,23 @@ class ContentAiChoiceDelta(AiChoiceDelta, lang.Final):
48
47
  c: Content
49
48
 
50
49
 
51
- @dc.dataclass(frozen=True)
52
- class ToolUseAiChoiceDelta(AiChoiceDelta, lang.Final):
53
- tu: ToolUse
50
+ #
51
+
52
+
53
+ @dc.dataclass(frozen=True, kw_only=True)
54
+ class AnyToolUseAiChoiceDelta(AiChoiceDelta, lang.Abstract):
55
+ id: str | None = None
56
+ name: str | None = None
57
+
58
+
59
+ @dc.dataclass(frozen=True, kw_only=True)
60
+ class ToolUseAiChoiceDelta(AnyToolUseAiChoiceDelta, lang.Final):
61
+ args: ta.Mapping[str, ta.Any] | None = None
62
+
63
+
64
+ @dc.dataclass(frozen=True, kw_only=True)
65
+ class PartialToolUseAiChoiceDelta(AnyToolUseAiChoiceDelta, lang.Final):
66
+ raw_args: ta.Any | None = None
54
67
 
55
68
 
56
69
  #
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommlds
3
- Version: 0.0.0.dev465
3
+ Version: 0.0.0.dev466
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.dev465
18
- Requires-Dist: omlish==0.0.0.dev465
17
+ Requires-Dist: omdev==0.0.0.dev466
18
+ Requires-Dist: omlish==0.0.0.dev466
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,4 +1,4 @@
1
- ommlds/.omlish-manifests.json,sha256=5HdEXx21B_B9DSFeEoQ1teSsanB_NOU5F2o5yjrAtKI,17930
1
+ ommlds/.omlish-manifests.json,sha256=ZrDlaAwG8hoshkjW-up0pk0dMvDI3g5dW1M92uaf5KI,17930
2
2
  ommlds/__about__.py,sha256=uAJgr2I_m_oZPlV5P8XLFeYpBlEM-DdzeyF6O5OK_qs,1759
3
3
  ommlds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  ommlds/huggingface.py,sha256=JfEyfKOxU3-SY_ojtXBJFNeD-NIuKjvMe3GL3e93wNA,1175
@@ -16,7 +16,7 @@ ommlds/backends/anthropic/protocol/sse/events.py,sha256=pLscyLFpxcrtOijNPRgivrxY
16
16
  ommlds/backends/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  ommlds/backends/google/protocol/__init__.py,sha256=OWmhuCS_sZ08ZaBtSSDRIudHKzkzgmqxY-3jgQxTidw,105
18
18
  ommlds/backends/google/protocol/_marshal.py,sha256=LWikcdMDrKQ0lMtclNXwK9qamijUBzK62nrEVo2OFtc,305
19
- ommlds/backends/google/protocol/types.py,sha256=-szndCfo4h4TnfWY23B-_ksgDO0W_Qnu958h4NEWJFw,17494
19
+ ommlds/backends/google/protocol/types.py,sha256=JDft5-5sPuy8sFWTvid4JuC9a9EnuQizt9dyAV2L56s,17536
20
20
  ommlds/backends/llamacpp/__init__.py,sha256=zXFpLXE4a2vEl0jcPDyKlPHHfZ3Z8Dz0twhEIyZ8-vg,59
21
21
  ommlds/backends/llamacpp/buildwheel.py,sha256=q9ghCLVbm8Jm6syrZlBP-x1qNDd0wSl15B2OXBtDBQ8,3813
22
22
  ommlds/backends/llamacpp/logging.py,sha256=nCEC6ASEuTpJqx47DMLhnbr5KelDlbxhM0nKQt4bc3w,773
@@ -100,7 +100,7 @@ ommlds/cli/sessions/chat/chat/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
100
100
  ommlds/cli/sessions/chat/chat/ai/inject.py,sha256=FCq-E8auVJ-gnK18NoKiINGBHgDllroZRG7z5ZY63L8,2514
101
101
  ommlds/cli/sessions/chat/chat/ai/injection.py,sha256=2O_ELMusxQsYaB2oqvzjYpZQzjshocJup7Z5unzoUIY,404
102
102
  ommlds/cli/sessions/chat/chat/ai/rendering.py,sha256=cicA6NwkM9UJb1dgsakhkhIMWGzBsArPFvYoINBmuec,2285
103
- ommlds/cli/sessions/chat/chat/ai/services.py,sha256=RNO3emXEFPr0M04wThRQo332x0n5R3n8aQFctcePCHQ,2629
103
+ ommlds/cli/sessions/chat/chat/ai/services.py,sha256=-XcMEatIDA0h_h-crL45c3qvC5VbDdhvKcWsxzioQA8,2507
104
104
  ommlds/cli/sessions/chat/chat/ai/tools.py,sha256=en94LLM8y73N11xhQPlkSLfbzAmYVwKU-4nz2i0CK0E,1094
105
105
  ommlds/cli/sessions/chat/chat/ai/types.py,sha256=QH6Cn6DrdxBi0Tnura7Fq-WtGUm0FdsazZSgki6nf0A,750
106
106
  ommlds/cli/sessions/chat/chat/state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -147,7 +147,7 @@ ommlds/cli/state/storage.py,sha256=tRPmgCANRrw7A5Qr700OaH58F6S96O37I8Ivrbo7_gI,3
147
147
  ommlds/datasets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
148
148
  ommlds/datasets/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
149
  ommlds/datasets/lib/movies.py,sha256=LmdfoXsZU9XMM_r-sxCLv_s06BFzwWO4xUj6sc9XVcI,1961
150
- ommlds/minichain/__init__.py,sha256=5pHq8Tlhgqx5p9ilC0EjN8dpOZ2Xc1ADHgwa1V-FFkk,10829
150
+ ommlds/minichain/__init__.py,sha256=EqNJpuMwqkkdlNmipjaoC30yAqH7c8oziszlkCcXBrQ,10982
151
151
  ommlds/minichain/_marshal.py,sha256=n9PGWrHhvAmGIc7KDOYt3IF9Z6G0ncXskyICTp3Ji6k,1923
152
152
  ommlds/minichain/_typedvalues.py,sha256=Vl1Edt5khC0e5RPFBPmPCxn0IzrfVd0NHzAjAN2E6Kc,2183
153
153
  ommlds/minichain/completion.py,sha256=lQ0LfCIYZsvDqteHhhDIv16D2_gn_xMfEL0ouywE5Yo,1033
@@ -172,14 +172,14 @@ ommlds/minichain/backends/impls/anthropic/__init__.py,sha256=47DEQpj8HBSa-_TImW-
172
172
  ommlds/minichain/backends/impls/anthropic/chat.py,sha256=LVaRP_Pbz4UghSHD8GZ22hMWE4Rsd_6bSysgl2BR_AM,4166
173
173
  ommlds/minichain/backends/impls/anthropic/names.py,sha256=GPPeYt0CcDcDCR8I6BMd7bMjC_Zk_bjnLLpF9ClwXcg,1099
174
174
  ommlds/minichain/backends/impls/anthropic/protocol.py,sha256=whPVYuKShKiMCzasHl77sCIiymhzXj8mFZXEyhZvld8,3292
175
- ommlds/minichain/backends/impls/anthropic/stream.py,sha256=agET8PPbKg-7gYL3FGyU45J-QqV65VkEo15ipScEzUA,7667
175
+ ommlds/minichain/backends/impls/anthropic/stream.py,sha256=AvoLk25R7E_aSS1tAN-P-UKjhKPxYtQoeGakXvFdblI,8677
176
176
  ommlds/minichain/backends/impls/duckduckgo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
177
  ommlds/minichain/backends/impls/duckduckgo/search.py,sha256=igzeU9P9b1MMiu4KAJVS9H6KLIoPm68wXi4Kx3_DHyQ,940
178
178
  ommlds/minichain/backends/impls/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
179
  ommlds/minichain/backends/impls/google/chat.py,sha256=q6LasmAh3Xn78kNlgpgwoKhdTj3o76j0X3_xitdyAE0,6316
180
180
  ommlds/minichain/backends/impls/google/names.py,sha256=HxHJ31HeKZg6aW1C_Anqp-gamCXpq9pOdKj8_yVgE8Y,871
181
181
  ommlds/minichain/backends/impls/google/search.py,sha256=5-2nAZ1QmbqHSQcwWnqqcgCM-Duy2ryctJEIv2tcpZg,3260
182
- ommlds/minichain/backends/impls/google/stream.py,sha256=no8MM4rrduvxrDWKIPAaYUiH5la3OxuVgAvDP3mkmnE,4921
182
+ ommlds/minichain/backends/impls/google/stream.py,sha256=Mhg5cOe7PKbnlQURyk2IRermtpzxU5Y0j3w4fkt2ZRg,7900
183
183
  ommlds/minichain/backends/impls/google/tools.py,sha256=Tty0gsyx7-PbeoNqMuql_ewQ6q-ZsDaDdsD5ShinGVY,5089
184
184
  ommlds/minichain/backends/impls/huggingface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
185
185
  ommlds/minichain/backends/impls/huggingface/configs.py,sha256=6jsBtPNXOP57PcpxNTVLGWLc-18Iwn_lDbGouwCJTIQ,258
@@ -195,7 +195,7 @@ ommlds/minichain/backends/impls/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
195
195
  ommlds/minichain/backends/impls/openai/chat.py,sha256=3hiKX2WqRo1cwF4AhcnzcCb2fsmwNLW7YPGYpask41A,2660
196
196
  ommlds/minichain/backends/impls/openai/completion.py,sha256=0XTC08mZzbW23Y2DNW2xfRR0eDX4nTyejF8CR1BdHZs,1756
197
197
  ommlds/minichain/backends/impls/openai/embedding.py,sha256=kkDJ3_0EqwQ_E0eXsSH1TuWXQmRqaijK8zG90fnlf3s,1582
198
- ommlds/minichain/backends/impls/openai/format.py,sha256=xzd7iuyEcu8aROZQJ14A6C0Vxylg75yQbWwk-Oz8Q74,7150
198
+ ommlds/minichain/backends/impls/openai/format.py,sha256=M1AYWDhz1QApazFeae4xTO9ng_59sx4uYs0FKt0GIKM,7275
199
199
  ommlds/minichain/backends/impls/openai/format2.py,sha256=OQ3N8VR4uL3PvHxjOQSdgg1bQ4_WiDz_sOV4WhVEXpQ,6611
200
200
  ommlds/minichain/backends/impls/openai/names.py,sha256=b74t8FwSbGEveVtVz4SqM5tiRDyTKNlUKlseV6AX3Yo,1211
201
201
  ommlds/minichain/backends/impls/openai/stream.py,sha256=X45qIXgwAk7IVe4LL6gzL3uJivdaB-hUGutltHeswTc,5280
@@ -228,9 +228,10 @@ ommlds/minichain/chat/choices/services.py,sha256=p_FsCZEsGJun8epzAHoeNdjwJ86Zwih
228
228
  ommlds/minichain/chat/choices/types.py,sha256=OPnMUp0KUKGGPJKsQZiXUtd8Z9b_JnhOy7SXKL6QDWU,725
229
229
  ommlds/minichain/chat/stream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
230
  ommlds/minichain/chat/stream/_marshal.py,sha256=r6NYBUviV7jIssaFprzv2rVEj8cFEuBlt71BSMZ-448,397
231
- ommlds/minichain/chat/stream/adapters.py,sha256=Mxftmg6izUoeZnVZM4v5o0_eCtY0QuYAd-X7BkqYHWY,2627
231
+ ommlds/minichain/chat/stream/adapters.py,sha256=3hKo3-MLtVIB-Nhdlxt17LP9vZESr-2fBZQ3Yr6l_Ps,1077
232
+ ommlds/minichain/chat/stream/joining.py,sha256=oPxLT4qEYWCaxclnZvt54ztQP5md4V6u6Uwn4qd2e9M,2936
232
233
  ommlds/minichain/chat/stream/services.py,sha256=TxNEOm85QEFYtKb59q_uP6eSNh75v1fF-IpsJjhY4to,1252
233
- ommlds/minichain/chat/stream/types.py,sha256=OoPNYpPZxFNZcEbr36U1zpA_hsVU16ujsFnnHcq5W-0,1252
234
+ ommlds/minichain/chat/stream/types.py,sha256=t1udlFSMlSlEyQHRnBEQYI_f-FuE6twRBFGzR66blWQ,1585
234
235
  ommlds/minichain/chat/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
235
236
  ommlds/minichain/chat/tools/execution.py,sha256=tCPsz1kCt5RcoRX7dwfaJRvObniJJv_D2hCwz1Slo_A,573
236
237
  ommlds/minichain/chat/tools/ids.py,sha256=DFBKrpeDTCnMcU-P38VbPWX0YBDaz_HzMgx3yXWjFWQ,759
@@ -367,9 +368,9 @@ ommlds/wiki/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
367
368
  ommlds/wiki/utils/io.py,sha256=UKgDJGtmpnWvIqVd2mJc2QNPOqlToEY1GEveNp6_pMo,7088
368
369
  ommlds/wiki/utils/progress.py,sha256=EhvKcMFYtsarCQhIahlO6f0SboyAKP3UwUyrnVnP-Vk,3222
369
370
  ommlds/wiki/utils/xml.py,sha256=vVV8Ctn13aaRM9eYfs9Wd6rHn5WOCEUzQ44fIhOvJdg,3754
370
- ommlds-0.0.0.dev465.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
371
- ommlds-0.0.0.dev465.dist-info/METADATA,sha256=JAD5TLj7Vqeese-787MMUhAcQFykg29h_upNHQ5XUFA,3224
372
- ommlds-0.0.0.dev465.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
373
- ommlds-0.0.0.dev465.dist-info/entry_points.txt,sha256=Z5YWtX7ClfiCKdW-dd_CSVvM0h4yQpJPi-2G3q6gNFo,35
374
- ommlds-0.0.0.dev465.dist-info/top_level.txt,sha256=Rbnk5d5wi58vnAXx13WFZqdQ4VX8hBCS2hEL3WeXOhY,7
375
- ommlds-0.0.0.dev465.dist-info/RECORD,,
371
+ ommlds-0.0.0.dev466.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
372
+ ommlds-0.0.0.dev466.dist-info/METADATA,sha256=cTdtmfR8ON19GS5ay_ImJD5oZ5uXwylxukZIaX7NNUM,3224
373
+ ommlds-0.0.0.dev466.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
374
+ ommlds-0.0.0.dev466.dist-info/entry_points.txt,sha256=Z5YWtX7ClfiCKdW-dd_CSVvM0h4yQpJPi-2G3q6gNFo,35
375
+ ommlds-0.0.0.dev466.dist-info/top_level.txt,sha256=Rbnk5d5wi58vnAXx13WFZqdQ4VX8hBCS2hEL3WeXOhY,7
376
+ ommlds-0.0.0.dev466.dist-info/RECORD,,