ommlds 0.0.0.dev491__py3-none-any.whl → 0.0.0.dev493__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 (55) hide show
  1. ommlds/.omlish-manifests.json +9 -7
  2. ommlds/__about__.py +1 -1
  3. ommlds/cli/_dataclasses.py +617 -724
  4. ommlds/cli/backends/catalog.py +0 -5
  5. ommlds/cli/backends/inject.py +2 -0
  6. ommlds/cli/inject.py +11 -3
  7. ommlds/cli/main.py +35 -25
  8. ommlds/cli/sessions/base.py +1 -10
  9. ommlds/cli/sessions/chat/configs.py +6 -8
  10. ommlds/cli/sessions/chat/drivers/driver.py +8 -0
  11. ommlds/cli/sessions/chat/drivers/inject.py +2 -3
  12. ommlds/cli/sessions/chat/drivers/state/configs.py +2 -0
  13. ommlds/cli/sessions/chat/drivers/state/ids.py +25 -0
  14. ommlds/cli/sessions/chat/drivers/state/inject.py +54 -6
  15. ommlds/cli/sessions/chat/drivers/state/inmemory.py +0 -4
  16. ommlds/cli/sessions/chat/drivers/state/storage.py +17 -10
  17. ommlds/cli/sessions/chat/drivers/state/types.py +9 -4
  18. ommlds/cli/sessions/chat/drivers/user/inject.py +4 -4
  19. ommlds/cli/sessions/chat/facades/__init__.py +0 -0
  20. ommlds/cli/sessions/chat/facades/configs.py +9 -0
  21. ommlds/cli/sessions/chat/facades/facade.py +19 -0
  22. ommlds/cli/sessions/chat/facades/inject.py +23 -0
  23. ommlds/cli/sessions/chat/inject.py +5 -3
  24. ommlds/cli/sessions/chat/interfaces/bare/configs.py +15 -0
  25. ommlds/cli/sessions/chat/interfaces/bare/inject.py +2 -2
  26. ommlds/cli/sessions/chat/interfaces/bare/interactive.py +10 -2
  27. ommlds/cli/sessions/chat/interfaces/configs.py +2 -14
  28. ommlds/cli/sessions/chat/interfaces/inject.py +9 -4
  29. ommlds/cli/sessions/chat/interfaces/textual/app.py +113 -45
  30. ommlds/cli/sessions/chat/interfaces/textual/configs.py +11 -0
  31. ommlds/cli/sessions/chat/interfaces/textual/inject.py +39 -15
  32. ommlds/cli/sessions/chat/interfaces/textual/interface.py +5 -0
  33. ommlds/cli/sessions/chat/interfaces/textual/styles/input.tcss +3 -1
  34. ommlds/cli/sessions/chat/interfaces/textual/styles/messages.tcss +76 -22
  35. ommlds/cli/sessions/chat/interfaces/textual/tools.py +38 -0
  36. ommlds/cli/sessions/chat/interfaces/textual/widgets/messages.py +60 -2
  37. ommlds/cli/sessions/chat/session.py +2 -15
  38. ommlds/cli/sessions/completion/configs.py +3 -4
  39. ommlds/cli/sessions/completion/inject.py +1 -2
  40. ommlds/cli/sessions/completion/session.py +4 -8
  41. ommlds/cli/sessions/configs.py +10 -0
  42. ommlds/cli/sessions/embedding/configs.py +3 -4
  43. ommlds/cli/sessions/embedding/inject.py +1 -2
  44. ommlds/cli/sessions/embedding/session.py +4 -8
  45. ommlds/cli/sessions/inject.py +15 -15
  46. ommlds/cli/state/storage.py +7 -1
  47. ommlds/minichain/backends/impls/cerebras/protocol.py +4 -4
  48. ommlds/minichain/backends/impls/ollama/chat.py +26 -0
  49. ommlds/minichain/backends/impls/openai/names.py +3 -1
  50. {ommlds-0.0.0.dev491.dist-info → ommlds-0.0.0.dev493.dist-info}/METADATA +6 -6
  51. {ommlds-0.0.0.dev491.dist-info → ommlds-0.0.0.dev493.dist-info}/RECORD +55 -46
  52. {ommlds-0.0.0.dev491.dist-info → ommlds-0.0.0.dev493.dist-info}/WHEEL +0 -0
  53. {ommlds-0.0.0.dev491.dist-info → ommlds-0.0.0.dev493.dist-info}/entry_points.txt +0 -0
  54. {ommlds-0.0.0.dev491.dist-info → ommlds-0.0.0.dev493.dist-info}/licenses/LICENSE +0 -0
  55. {ommlds-0.0.0.dev491.dist-info → ommlds-0.0.0.dev493.dist-info}/top_level.txt +0 -0
@@ -1,48 +1,57 @@
1
1
  /* Container */
2
2
 
3
- #messages-scroll {
3
+ #messages-container {
4
4
  width: 100%;
5
5
  height: 1fr;
6
6
 
7
- padding: 0 2 0 2;
7
+ scrollbar-gutter: stable;
8
+
9
+ background: $background-darken-3;
10
+
11
+ text-align: left;
12
+
13
+ scrollbar-size: 1 1;
8
14
  }
9
15
 
10
- #messages-container {
11
- width: 100%;
16
+
17
+ /* Base */
18
+
19
+ .message {
20
+ width: 1fr;
12
21
  height: auto;
13
22
 
14
- margin-top: 1;
15
- margin-bottom: 0;
23
+ margin: 1 0 0 0;
24
+
25
+ padding-right: 1;
16
26
 
17
27
  layout: stream;
18
- text-align: left;
19
28
  }
20
29
 
21
30
 
22
31
  /* Welcome */
23
32
 
24
33
  .welcome-message {
25
- margin: 1;
34
+ padding: 1 2 1 1;
26
35
 
27
36
  border: round;
37
+ }
28
38
 
29
- padding: 1;
39
+ .welcome-message-outer {
40
+ width: 1fr;
41
+ height: auto;
42
+ }
30
43
 
31
- text-align: center;
44
+ .welcome-message-content {
32
45
  }
33
46
 
34
47
 
35
48
  /* User */
36
49
 
37
50
  .user-message {
38
- width: 100%;
39
- height: auto;
40
-
41
- margin-top: 1;
42
51
  }
43
52
 
44
53
  .user-message-outer {
45
- width: 100%;
54
+ width: 1fr;
46
55
  height: auto;
47
56
  }
48
57
 
@@ -57,7 +66,7 @@
57
66
  }
58
67
 
59
68
  .user-message-inner {
60
- width: 100%;
69
+ width: 1fr;
61
70
  height: auto;
62
71
  }
63
72
 
@@ -65,14 +74,10 @@
65
74
  /* Ai */
66
75
 
67
76
  .ai-message {
68
- width: 100%;
69
- height: auto;
70
-
71
- margin-top: 1;
72
77
  }
73
78
 
74
79
  .ai-message-outer {
75
- width: 100%;
80
+ width: 1fr;
76
81
  height: auto;
77
82
 
78
83
  align: left top;
@@ -89,7 +94,7 @@
89
94
  }
90
95
 
91
96
  .ai-message-inner {
92
- width: 100%;
97
+ width: 1fr;
93
98
  height: auto;
94
99
 
95
100
  padding: 0;
@@ -102,3 +107,52 @@
102
107
  padding: 0;
103
108
  }
104
109
  }
110
+
111
+
112
+ /* Tool Confirmation */
113
+
114
+ .tool-confirmation-message {
115
+ }
116
+
117
+ .tool-confirmation-message-outer {
118
+ width: 1fr;
119
+ height: auto;
120
+
121
+ align: left top;
122
+ }
123
+
124
+ .tool-confirmation-message-glyph {
125
+ width: auto;
126
+ height: auto;
127
+
128
+ background: transparent;
129
+ color: $primary;
130
+
131
+ text-style: bold;
132
+ }
133
+
134
+ .tool-confirmation-message-inner {
135
+ width: 1fr;
136
+ height: auto;
137
+ }
138
+
139
+ .tool-confirmation-message-inner-open {
140
+ background: $warning-lighten-3 15%;
141
+ }
142
+
143
+ .tool-confirmation-message-inner-closed {
144
+ }
145
+
146
+ .tool-confirmation-message-outer-content {
147
+ }
148
+
149
+ .tool-confirmation-message-inner-content {
150
+ background: $background;
151
+
152
+ margin: 1;
153
+ padding: 1;
154
+ }
155
+
156
+ .tool-confirmation-message-controls {
157
+ margin: 1;
158
+ }
@@ -0,0 +1,38 @@
1
+ from omlish.formats import json
2
+
3
+ from ...... import minichain as mc
4
+ from ...drivers.tools.confirmation import ToolExecutionConfirmation
5
+ from ...drivers.tools.confirmation import ToolExecutionRequestDeniedError
6
+ from .app import ChatAppGetter
7
+
8
+
9
+ ##
10
+
11
+
12
+ class ChatAppToolExecutionConfirmation(ToolExecutionConfirmation):
13
+ def __init__(
14
+ self,
15
+ *,
16
+ app: ChatAppGetter,
17
+ ) -> None:
18
+ super().__init__()
19
+
20
+ self._app = app
21
+
22
+ async def confirm_tool_execution_or_raise(
23
+ self,
24
+ use: 'mc.ToolUse',
25
+ entry: 'mc.ToolCatalogEntry',
26
+ ) -> None:
27
+ tr_dct = dict(
28
+ id=use.id,
29
+ name=entry.spec.name,
30
+ args=use.args,
31
+ # spec=msh.marshal(tce.spec),
32
+ )
33
+
34
+ if not await (await self._app()).confirm_tool_use(
35
+ 'Execute requested tool?',
36
+ json.dumps_pretty(tr_dct),
37
+ ):
38
+ raise ToolExecutionRequestDeniedError
@@ -1,4 +1,5 @@
1
1
  import abc
2
+ import asyncio
2
3
  import typing as ta
3
4
 
4
5
  from omdev.tui import textual as tx
@@ -9,7 +10,10 @@ from omlish import lang
9
10
 
10
11
 
11
12
  class Message(tx.Static, lang.Abstract):
12
- pass
13
+ def __init__(self, *args: ta.Any, **kwargs: ta.Any) -> None:
14
+ super().__init__(*args, **kwargs)
15
+
16
+ self.add_class('message')
13
17
 
14
18
 
15
19
  ##
@@ -17,10 +21,16 @@ class Message(tx.Static, lang.Abstract):
17
21
 
18
22
  class WelcomeMessage(Message):
19
23
  def __init__(self, content: str) -> None:
20
- super().__init__(content)
24
+ super().__init__()
21
25
 
22
26
  self.add_class('welcome-message')
23
27
 
28
+ self._content = content
29
+
30
+ def compose(self) -> tx.ComposeResult:
31
+ with tx.Vertical(classes='welcome-message-outer'):
32
+ yield tx.Static(self._content, classes='welcome-message-content')
33
+
24
34
 
25
35
  ##
26
36
 
@@ -112,3 +122,51 @@ class StreamAiMessage(AiMessage):
112
122
 
113
123
  await stream.stop()
114
124
  self._stream_ = None
125
+
126
+
127
+ ##
128
+
129
+
130
+ class ToolConfirmationControls(tx.Static):
131
+ class Allowed(tx.Message):
132
+ pass
133
+
134
+ def compose(self) -> tx.ComposeResult:
135
+ yield tx.Button('Allow', action='allow')
136
+
137
+ def action_allow(self) -> None:
138
+ self.post_message(self.Allowed())
139
+
140
+
141
+ class ToolConfirmationMessage(Message):
142
+ def __init__(
143
+ self,
144
+ outer_content: str,
145
+ inner_content: str,
146
+ fut: asyncio.Future[bool],
147
+ ) -> None:
148
+ super().__init__()
149
+
150
+ self.add_class('tool-confirmation-message')
151
+
152
+ self._outer_content = outer_content
153
+ self._inner_content = inner_content
154
+ self._fut = fut
155
+
156
+ def compose(self) -> tx.ComposeResult:
157
+ with tx.Horizontal(classes='tool-confirmation-message-outer'):
158
+ yield tx.Static('? ', classes='tool-confirmation-message-glyph')
159
+ with tx.Vertical(classes='tool-confirmation-message-inner tool-confirmation-message-inner-open'):
160
+ yield tx.Static(self._outer_content, classes='tool-confirmation-message-outer-content')
161
+ yield tx.Static(self._inner_content, classes='tool-confirmation-message-inner-content')
162
+ yield ToolConfirmationControls(classes='tool-confirmation-message-controls')
163
+
164
+ @tx.on(ToolConfirmationControls.Allowed)
165
+ async def on_allowed(self, event: ToolConfirmationControls.Allowed) -> None:
166
+ inner = self.query_one(tx.Vertical)
167
+ await inner.query_one(ToolConfirmationControls).remove()
168
+ inner.remove_class('tool-confirmation-message-inner-open')
169
+ inner.add_class('tool-confirmation-message-inner-closed')
170
+ inner.query_one('.tool-confirmation-message-outer-content', tx.Static).update('Tool use confirmed.')
171
+
172
+ self._fut.set_result(True)
@@ -1,9 +1,6 @@
1
1
  import typing as ta
2
2
 
3
- from omlish import dataclasses as dc
4
-
5
3
  from ..base import Session
6
- from .configs import ChatConfig
7
4
  from .interfaces.base import ChatInterface
8
5
 
9
6
 
@@ -11,23 +8,13 @@ from .interfaces.base import ChatInterface
11
8
 
12
9
 
13
10
  @ta.final
14
- class ChatSession(Session['ChatSession.Config']):
15
- """
16
- An adapter to the lower level, dumber, non-chat-specific cli 'session' layer. Nothing else takes the kitchen-sink
17
- 'ChatConfig' object, it's only here for type dispatch in lower layers.
18
- """
19
-
20
- @dc.dataclass(frozen=True)
21
- class Config(Session.Config, ChatConfig):
22
- pass
23
-
11
+ class ChatSession(Session):
24
12
  def __init__(
25
13
  self,
26
- config: Config,
27
14
  *,
28
15
  interface: ChatInterface,
29
16
  ) -> None:
30
- super().__init__(config)
17
+ super().__init__()
31
18
 
32
19
  self._interface = interface
33
20
 
@@ -1,6 +1,7 @@
1
1
  from omlish import dataclasses as dc
2
2
 
3
3
  from .... import minichain as mc
4
+ from ..configs import SessionConfig
4
5
 
5
6
 
6
7
  ##
@@ -12,10 +13,8 @@ DEFAULT_BACKEND = 'openai'
12
13
  ##
13
14
 
14
15
 
15
- @dc.dataclass(frozen=True)
16
- class CompletionConfig:
16
+ @dc.dataclass(frozen=True, kw_only=True)
17
+ class CompletionConfig(SessionConfig):
17
18
  content: 'mc.Content'
18
19
 
19
- _: dc.KW_ONLY
20
-
21
20
  backend: str | None = None
@@ -1,4 +1,3 @@
1
- from omlish import dataclasses as dc
2
1
  from omlish import inject as inj
3
2
  from omlish import lang
4
3
 
@@ -23,7 +22,7 @@ def bind_completion(cfg: CompletionConfig) -> inj.Elements:
23
22
  #
24
23
 
25
24
  els.extend([
26
- inj.bind(_session.CompletionSession.Config(**dc.asdict(cfg))),
25
+ inj.bind(cfg),
27
26
  inj.bind(Session, to_ctor=_session.CompletionSession, singleton=True),
28
27
  ])
29
28
 
@@ -1,5 +1,4 @@
1
1
  from omlish import check
2
- from omlish import dataclasses as dc
3
2
 
4
3
  from .... import minichain as mc
5
4
  from ...backends.types import CompletionServiceBackendProvider
@@ -10,19 +9,16 @@ from .configs import CompletionConfig
10
9
  ##
11
10
 
12
11
 
13
- class CompletionSession(Session['CompletionSession.Config']):
14
- @dc.dataclass(frozen=True)
15
- class Config(Session.Config, CompletionConfig):
16
- pass
17
-
12
+ class CompletionSession(Session):
18
13
  def __init__(
19
14
  self,
20
- config: Config,
15
+ config: CompletionConfig,
21
16
  *,
22
17
  service_provider: CompletionServiceBackendProvider,
23
18
  ) -> None:
24
- super().__init__(config)
19
+ super().__init__()
25
20
 
21
+ self._config = config
26
22
  self._service_provider = service_provider
27
23
 
28
24
  async def run(self) -> None:
@@ -0,0 +1,10 @@
1
+ from omlish import dataclasses as dc
2
+ from omlish import lang
3
+
4
+
5
+ ##
6
+
7
+
8
+ @dc.dataclass(frozen=True, kw_only=True)
9
+ class SessionConfig(lang.Abstract):
10
+ pass
@@ -1,6 +1,7 @@
1
1
  from omlish import dataclasses as dc
2
2
 
3
3
  from .... import minichain as mc
4
+ from ..configs import SessionConfig
4
5
 
5
6
 
6
7
  ##
@@ -12,10 +13,8 @@ DEFAULT_BACKEND = 'openai'
12
13
  ##
13
14
 
14
15
 
15
- @dc.dataclass(frozen=True)
16
- class EmbeddingConfig:
16
+ @dc.dataclass(frozen=True, kw_only=True)
17
+ class EmbeddingConfig(SessionConfig):
17
18
  content: 'mc.Content'
18
19
 
19
- _: dc.KW_ONLY
20
-
21
20
  backend: str | None = None
@@ -1,4 +1,3 @@
1
- from omlish import dataclasses as dc
2
1
  from omlish import inject as inj
3
2
  from omlish import lang
4
3
 
@@ -23,7 +22,7 @@ def bind_embedding(cfg: EmbeddingConfig) -> inj.Elements:
23
22
  #
24
23
 
25
24
  els.extend([
26
- inj.bind(_session.EmbeddingSession.Config(**dc.asdict(cfg))),
25
+ inj.bind(cfg),
27
26
  inj.bind(Session, to_ctor=_session.EmbeddingSession, singleton=True),
28
27
  ])
29
28
 
@@ -1,4 +1,3 @@
1
- from omlish import dataclasses as dc
2
1
  from omlish.formats import json
3
2
 
4
3
  from .... import minichain as mc
@@ -10,19 +9,16 @@ from .configs import EmbeddingConfig
10
9
  ##
11
10
 
12
11
 
13
- class EmbeddingSession(Session['EmbeddingSession.Config']):
14
- @dc.dataclass(frozen=True)
15
- class Config(Session.Config, EmbeddingConfig):
16
- pass
17
-
12
+ class EmbeddingSession(Session):
18
13
  def __init__(
19
14
  self,
20
- config: Config,
15
+ config: EmbeddingConfig,
21
16
  *,
22
17
  service_provider: EmbeddingServiceBackendProvider,
23
18
  ) -> None:
24
- super().__init__(config)
19
+ super().__init__()
25
20
 
21
+ self._config = config
26
22
  self._service_provider = service_provider
27
23
 
28
24
  async def run(self) -> None:
@@ -1,34 +1,34 @@
1
- import typing as ta
2
-
3
1
  from omlish import inject as inj
4
2
  from omlish import lang
5
3
 
4
+ from .chat.configs import ChatConfig
5
+ from .completion.configs import CompletionConfig
6
+ from .configs import SessionConfig
7
+ from .embedding.configs import EmbeddingConfig
8
+
6
9
 
7
10
  with lang.auto_proxy_import(globals()):
8
- from .chat import configs as _chat_cfgs
9
- from .chat import inject as _chat_inj
10
- from .completion import configs as _completion_cfgs
11
- from .completion import inject as _completion_inj
12
- from .embedding import configs as _embedding_cfgs
13
- from .embedding import inject as _embedding_inj
11
+ from .chat import inject as _chat
12
+ from .completion import inject as _completion
13
+ from .embedding import inject as _embedding
14
14
 
15
15
 
16
16
  ##
17
17
 
18
18
 
19
- def bind_sessions(cfg: ta.Any) -> inj.Elements:
19
+ def bind_sessions(cfg: SessionConfig) -> inj.Elements:
20
20
  els: list[inj.Elemental] = []
21
21
 
22
22
  #
23
23
 
24
- if isinstance(cfg, _chat_cfgs.ChatConfig):
25
- els.append(_chat_inj.bind_chat(cfg))
24
+ if isinstance(cfg, ChatConfig):
25
+ els.append(_chat.bind_chat(cfg))
26
26
 
27
- elif isinstance(cfg, _completion_cfgs.CompletionConfig):
28
- els.append(_completion_inj.bind_completion(cfg))
27
+ elif isinstance(cfg, CompletionConfig):
28
+ els.append(_completion.bind_completion(cfg))
29
29
 
30
- elif isinstance(cfg, _embedding_cfgs.EmbeddingConfig):
31
- els.append(_embedding_inj.bind_embedding(cfg))
30
+ elif isinstance(cfg, EmbeddingConfig):
31
+ els.append(_embedding.bind_embedding(cfg))
32
32
 
33
33
  else:
34
34
  raise TypeError(cfg)
@@ -1,4 +1,5 @@
1
1
  import abc
2
+ import datetime
2
3
  import os.path
3
4
  import typing as ta
4
5
 
@@ -52,8 +53,12 @@ STATE_VERSION = 0
52
53
  @dc.dataclass(frozen=True)
53
54
  class MarshaledState:
54
55
  version: int
56
+
55
57
  payload: ta.Any
56
58
 
59
+ created_at: datetime.datetime | None = dc.field(default_factory=lang.utcnow)
60
+ updated_at: datetime.datetime | None = dc.field(default_factory=lang.utcnow)
61
+
57
62
 
58
63
  class MarshalStateStorage(StateStorage, lang.Abstract):
59
64
  def __init__(
@@ -75,6 +80,7 @@ class MarshalStateStorage(StateStorage, lang.Abstract):
75
80
  ms = MarshaledState(
76
81
  version=self._version,
77
82
  payload=msh.marshal(obj, ty),
83
+ updated_at=lang.utcnow(),
78
84
  )
79
85
  return msh.marshal(ms)
80
86
 
@@ -102,7 +108,7 @@ class JsonFileStateStorage(MarshalStateStorage):
102
108
  return json.loads(data)
103
109
 
104
110
  def _save_file_data(self, data: ta.Any) -> None:
105
- data = json.dumps_pretty(data)
111
+ data = json.dumps_compact(data)
106
112
  with open(self._file, 'w') as f:
107
113
  f.write(data)
108
114
 
@@ -16,7 +16,7 @@ from ....chat.messages import ToolUseResultMessage
16
16
  from ....chat.messages import UserMessage
17
17
  from ....chat.stream.types import AiDelta
18
18
  from ....chat.stream.types import ContentAiDelta
19
- from ....chat.stream.types import ToolUseAiDelta
19
+ from ....chat.stream.types import PartialToolUseAiDelta
20
20
  from ....chat.tools.types import Tool
21
21
  from ....content.prepare import prepare_content_str
22
22
  from ....tools.jsonschema import build_tool_spec_params_json_schema
@@ -128,10 +128,10 @@ def build_mc_ai_choice_deltas(delta: pt.ChatCompletionChunk.Choice.Delta) -> AiC
128
128
 
129
129
  for tc in delta.tool_calls or []:
130
130
  tc_fn = check.not_none(tc.function)
131
- lst.append(ToolUseAiDelta(
131
+ lst.append(PartialToolUseAiDelta(
132
132
  id=tc.id,
133
- name=check.not_none(tc_fn.name),
134
- args=json.loads(tc_fn.arguments or '{}'),
133
+ name=tc_fn.name,
134
+ raw_args=tc_fn.arguments,
135
135
  ))
136
136
 
137
137
  return AiChoiceDeltas(lst)
@@ -1,3 +1,29 @@
1
+ """
2
+ dolphin3:latest d5ab9ae8e1f2 4.9 GB 11 months ago (no tools)
3
+
4
+ functiongemma:270m 7c19b650567a 300 MB 5 minutes ago
5
+ gemma3:27b a418f5838eaf 17 GB 7 weeks ago (no tools)
6
+ gemma3:4b a2af6cc3eb7f 3.3 GB 7 weeks ago (no tools)
7
+
8
+ llama3.2:1b baf6a787fdff 1.3 GB 13 months ago (too stupid for tools)
9
+ llama3.2:latest a80c4f17acd5 2.0 GB 13 months ago
10
+
11
+ devstral-small-2:24b 24277f07f62d 15 GB 15 hours ago
12
+ ministral-3:14b 4760c35aeb9d 9.1 GB 11 hours ago
13
+ mistral:latest 6577803aa9a0 4.4 GB 3 seconds ago
14
+
15
+ nemotron-3-nano:30b b725f1117407 24 GB 15 hours ago
16
+
17
+ olmo-3.1:32b-instruct a16b6a5be6cf 19 GB 11 hours ago (no tools)
18
+ olmo-3.1:32b-think 223d4ec84d91 19 GB 11 hours ago (no tools)
19
+
20
+ phi4-mini:latest 78fad5d182a7 2.5 GB 8 months ago (no tools)
21
+
22
+ qwen3-coder:30b 06c1097efce0 18 GB 11 hours ago
23
+ qwen3-next:80b b2ebb986e4e9 50 GB 11 hours ago
24
+ qwen3:30b ad815644918f 18 GB 11 hours ago
25
+ qwen3:32b 030ee887880f 20 GB 11 hours ago
26
+ """
1
27
  import typing as ta
2
28
 
3
29
  from omlish import check
@@ -32,6 +32,8 @@ _GPT_MODEL_NAMES = [
32
32
  'gpt-5-nano',
33
33
 
34
34
  'gpt-5.1',
35
+
36
+ 'gpt-5.2',
35
37
  ]
36
38
 
37
39
 
@@ -48,7 +50,7 @@ CHAT_MODEL_NAMES = ModelNameCollection(
48
50
  for n in _GPT_MODEL_NAMES
49
51
  },
50
52
 
51
- 'gpt': 'gpt-5.1',
53
+ 'gpt': 'gpt-5.2',
52
54
  'gpt-mini': 'gpt-5-mini',
53
55
 
54
56
  #
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ommlds
3
- Version: 0.0.0.dev491
3
+ Version: 0.0.0.dev493
4
4
  Summary: ommlds
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,9 +14,9 @@ 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: omlish==0.0.0.dev491
17
+ Requires-Dist: omlish==0.0.0.dev493
18
18
  Provides-Extra: all
19
- Requires-Dist: omdev==0.0.0.dev491; extra == "all"
19
+ Requires-Dist: omdev==0.0.0.dev493; extra == "all"
20
20
  Requires-Dist: llama-cpp-python~=0.3; extra == "all"
21
21
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "all"
22
22
  Requires-Dist: mlx-lm~=0.29; sys_platform == "darwin" and extra == "all"
@@ -33,12 +33,12 @@ Requires-Dist: numpy>=1.26; extra == "all"
33
33
  Requires-Dist: pytesseract~=0.3; extra == "all"
34
34
  Requires-Dist: rapidocr-onnxruntime~=1.4; extra == "all"
35
35
  Requires-Dist: pillow~=12.0; extra == "all"
36
- Requires-Dist: ddgs~=9.9; extra == "all"
36
+ Requires-Dist: ddgs~=9.10; extra == "all"
37
37
  Requires-Dist: mwparserfromhell~=0.7; extra == "all"
38
38
  Requires-Dist: wikitextparser~=0.56; extra == "all"
39
39
  Requires-Dist: lxml>=5.3; python_version < "3.13" and extra == "all"
40
40
  Provides-Extra: omdev
41
- Requires-Dist: omdev==0.0.0.dev491; extra == "omdev"
41
+ Requires-Dist: omdev==0.0.0.dev493; extra == "omdev"
42
42
  Provides-Extra: backends
43
43
  Requires-Dist: llama-cpp-python~=0.3; extra == "backends"
44
44
  Requires-Dist: mlx~=0.30; sys_platform == "darwin" and extra == "backends"
@@ -62,7 +62,7 @@ Requires-Dist: rapidocr-onnxruntime~=1.4; extra == "ocr"
62
62
  Provides-Extra: pillow
63
63
  Requires-Dist: pillow~=12.0; extra == "pillow"
64
64
  Provides-Extra: search
65
- Requires-Dist: ddgs~=9.9; extra == "search"
65
+ Requires-Dist: ddgs~=9.10; extra == "search"
66
66
  Provides-Extra: wiki
67
67
  Requires-Dist: mwparserfromhell~=0.7; extra == "wiki"
68
68
  Requires-Dist: wikitextparser~=0.56; extra == "wiki"