ommlds 0.0.0.dev440__py3-none-any.whl → 0.0.0.dev480__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.
- ommlds/.omlish-manifests.json +332 -35
- ommlds/__about__.py +15 -9
- ommlds/_hacks/__init__.py +4 -0
- ommlds/_hacks/funcs.py +110 -0
- ommlds/_hacks/names.py +158 -0
- ommlds/_hacks/params.py +73 -0
- ommlds/_hacks/patches.py +0 -3
- ommlds/backends/anthropic/protocol/_marshal.py +2 -2
- ommlds/backends/anthropic/protocol/sse/_marshal.py +1 -1
- ommlds/backends/anthropic/protocol/sse/assemble.py +23 -7
- ommlds/backends/anthropic/protocol/sse/events.py +13 -0
- ommlds/backends/anthropic/protocol/types.py +30 -9
- ommlds/backends/google/protocol/__init__.py +3 -0
- ommlds/backends/google/protocol/_marshal.py +16 -0
- ommlds/backends/google/protocol/types.py +626 -0
- ommlds/backends/groq/_marshal.py +23 -0
- ommlds/backends/groq/protocol.py +249 -0
- ommlds/backends/mlx/generation.py +1 -1
- ommlds/backends/mlx/loading.py +58 -1
- ommlds/backends/ollama/__init__.py +0 -0
- ommlds/backends/ollama/protocol.py +170 -0
- ommlds/backends/openai/protocol/__init__.py +9 -28
- ommlds/backends/openai/protocol/_common.py +18 -0
- ommlds/backends/openai/protocol/_marshal.py +27 -0
- ommlds/backends/openai/protocol/chatcompletion/chunk.py +58 -31
- ommlds/backends/openai/protocol/chatcompletion/contentpart.py +49 -44
- ommlds/backends/openai/protocol/chatcompletion/message.py +55 -43
- ommlds/backends/openai/protocol/chatcompletion/request.py +114 -66
- ommlds/backends/openai/protocol/chatcompletion/response.py +71 -45
- ommlds/backends/openai/protocol/chatcompletion/responseformat.py +27 -20
- ommlds/backends/openai/protocol/chatcompletion/tokenlogprob.py +16 -7
- ommlds/backends/openai/protocol/completionusage.py +24 -15
- ommlds/backends/tavily/__init__.py +0 -0
- ommlds/backends/tavily/protocol.py +301 -0
- ommlds/backends/tinygrad/models/llama3/__init__.py +22 -14
- ommlds/backends/transformers/__init__.py +0 -0
- ommlds/backends/transformers/filecache.py +109 -0
- ommlds/backends/transformers/streamers.py +73 -0
- ommlds/cli/asyncs.py +30 -0
- ommlds/cli/backends/catalog.py +93 -0
- ommlds/cli/backends/configs.py +9 -0
- ommlds/cli/backends/inject.py +31 -36
- ommlds/cli/backends/injection.py +16 -0
- ommlds/cli/backends/types.py +46 -0
- ommlds/cli/content/__init__.py +0 -0
- ommlds/cli/content/messages.py +34 -0
- ommlds/cli/content/strings.py +42 -0
- ommlds/cli/inject.py +15 -32
- ommlds/cli/inputs/__init__.py +0 -0
- ommlds/cli/inputs/asyncs.py +32 -0
- ommlds/cli/inputs/sync.py +75 -0
- ommlds/cli/main.py +270 -110
- ommlds/cli/rendering/__init__.py +0 -0
- ommlds/cli/rendering/configs.py +9 -0
- ommlds/cli/rendering/inject.py +31 -0
- ommlds/cli/rendering/markdown.py +52 -0
- ommlds/cli/rendering/raw.py +73 -0
- ommlds/cli/rendering/types.py +21 -0
- ommlds/cli/secrets.py +21 -0
- ommlds/cli/sessions/base.py +1 -1
- ommlds/cli/sessions/chat/chat/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/ai/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/ai/configs.py +11 -0
- ommlds/cli/sessions/chat/chat/ai/inject.py +74 -0
- ommlds/cli/sessions/chat/chat/ai/injection.py +14 -0
- ommlds/cli/sessions/chat/chat/ai/rendering.py +70 -0
- ommlds/cli/sessions/chat/chat/ai/services.py +79 -0
- ommlds/cli/sessions/chat/chat/ai/tools.py +44 -0
- ommlds/cli/sessions/chat/chat/ai/types.py +28 -0
- ommlds/cli/sessions/chat/chat/state/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/state/configs.py +11 -0
- ommlds/cli/sessions/chat/chat/state/inject.py +36 -0
- ommlds/cli/sessions/chat/chat/state/inmemory.py +33 -0
- ommlds/cli/sessions/chat/chat/state/storage.py +52 -0
- ommlds/cli/sessions/chat/chat/state/types.py +38 -0
- ommlds/cli/sessions/chat/chat/user/__init__.py +0 -0
- ommlds/cli/sessions/chat/chat/user/configs.py +17 -0
- ommlds/cli/sessions/chat/chat/user/inject.py +62 -0
- ommlds/cli/sessions/chat/chat/user/interactive.py +31 -0
- ommlds/cli/sessions/chat/chat/user/oneshot.py +25 -0
- ommlds/cli/sessions/chat/chat/user/types.py +15 -0
- ommlds/cli/sessions/chat/configs.py +27 -0
- ommlds/cli/sessions/chat/driver.py +43 -0
- ommlds/cli/sessions/chat/inject.py +33 -65
- ommlds/cli/sessions/chat/phases/__init__.py +0 -0
- ommlds/cli/sessions/chat/phases/inject.py +27 -0
- ommlds/cli/sessions/chat/phases/injection.py +14 -0
- ommlds/cli/sessions/chat/phases/manager.py +29 -0
- ommlds/cli/sessions/chat/phases/types.py +29 -0
- ommlds/cli/sessions/chat/session.py +27 -0
- ommlds/cli/sessions/chat/tools/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/configs.py +22 -0
- ommlds/cli/sessions/chat/tools/confirmation.py +46 -0
- ommlds/cli/sessions/chat/tools/execution.py +66 -0
- ommlds/cli/sessions/chat/tools/fs/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/fs/configs.py +12 -0
- ommlds/cli/sessions/chat/tools/fs/inject.py +35 -0
- ommlds/cli/sessions/chat/tools/inject.py +88 -0
- ommlds/cli/sessions/chat/tools/injection.py +44 -0
- ommlds/cli/sessions/chat/tools/rendering.py +58 -0
- ommlds/cli/sessions/chat/tools/todo/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/todo/configs.py +12 -0
- ommlds/cli/sessions/chat/tools/todo/inject.py +31 -0
- ommlds/cli/sessions/chat/tools/weather/__init__.py +0 -0
- ommlds/cli/sessions/chat/tools/weather/configs.py +12 -0
- ommlds/cli/sessions/chat/tools/weather/inject.py +22 -0
- ommlds/cli/{tools/weather.py → sessions/chat/tools/weather/tools.py} +1 -1
- ommlds/cli/sessions/completion/configs.py +21 -0
- ommlds/cli/sessions/completion/inject.py +42 -0
- ommlds/cli/sessions/completion/session.py +35 -0
- ommlds/cli/sessions/embedding/configs.py +21 -0
- ommlds/cli/sessions/embedding/inject.py +42 -0
- ommlds/cli/sessions/embedding/session.py +33 -0
- ommlds/cli/sessions/inject.py +28 -11
- ommlds/cli/state/__init__.py +0 -0
- ommlds/cli/state/inject.py +28 -0
- ommlds/cli/{state.py → state/storage.py} +41 -24
- ommlds/minichain/__init__.py +84 -24
- ommlds/minichain/_marshal.py +49 -9
- ommlds/minichain/_typedvalues.py +2 -4
- ommlds/minichain/backends/catalogs/base.py +20 -1
- ommlds/minichain/backends/catalogs/simple.py +2 -2
- ommlds/minichain/backends/catalogs/strings.py +10 -8
- ommlds/minichain/backends/impls/anthropic/chat.py +65 -27
- ommlds/minichain/backends/impls/anthropic/names.py +10 -8
- ommlds/minichain/backends/impls/anthropic/protocol.py +109 -0
- ommlds/minichain/backends/impls/anthropic/stream.py +111 -43
- ommlds/minichain/backends/impls/duckduckgo/search.py +1 -1
- ommlds/minichain/backends/impls/dummy/__init__.py +0 -0
- ommlds/minichain/backends/impls/dummy/chat.py +69 -0
- ommlds/minichain/backends/impls/google/chat.py +114 -22
- ommlds/minichain/backends/impls/google/search.py +7 -2
- ommlds/minichain/backends/impls/google/stream.py +219 -0
- ommlds/minichain/backends/impls/google/tools.py +149 -0
- ommlds/minichain/backends/impls/groq/__init__.py +0 -0
- ommlds/minichain/backends/impls/groq/chat.py +75 -0
- ommlds/minichain/backends/impls/groq/names.py +48 -0
- ommlds/minichain/backends/impls/groq/protocol.py +143 -0
- ommlds/minichain/backends/impls/groq/stream.py +125 -0
- ommlds/minichain/backends/impls/llamacpp/chat.py +33 -18
- ommlds/minichain/backends/impls/llamacpp/completion.py +1 -1
- ommlds/minichain/backends/impls/llamacpp/format.py +4 -2
- ommlds/minichain/backends/impls/llamacpp/stream.py +37 -20
- ommlds/minichain/backends/impls/mistral.py +20 -5
- ommlds/minichain/backends/impls/mlx/chat.py +96 -22
- ommlds/minichain/backends/impls/ollama/__init__.py +0 -0
- ommlds/minichain/backends/impls/ollama/chat.py +199 -0
- ommlds/minichain/backends/impls/openai/chat.py +18 -8
- ommlds/minichain/backends/impls/openai/completion.py +10 -3
- ommlds/minichain/backends/impls/openai/embedding.py +10 -3
- ommlds/minichain/backends/impls/openai/format.py +131 -106
- ommlds/minichain/backends/impls/openai/names.py +31 -5
- ommlds/minichain/backends/impls/openai/stream.py +43 -25
- ommlds/minichain/backends/impls/tavily.py +66 -0
- ommlds/minichain/backends/impls/tinygrad/chat.py +23 -16
- ommlds/minichain/backends/impls/transformers/sentence.py +1 -1
- ommlds/minichain/backends/impls/transformers/tokens.py +1 -1
- ommlds/minichain/backends/impls/transformers/transformers.py +155 -34
- ommlds/minichain/backends/strings/parsing.py +1 -1
- ommlds/minichain/backends/strings/resolving.py +4 -1
- ommlds/minichain/chat/_marshal.py +16 -9
- ommlds/minichain/chat/choices/adapters.py +4 -4
- ommlds/minichain/chat/choices/services.py +1 -1
- ommlds/minichain/chat/choices/stream/__init__.py +0 -0
- ommlds/minichain/chat/choices/stream/adapters.py +35 -0
- ommlds/minichain/chat/choices/stream/joining.py +31 -0
- ommlds/minichain/chat/choices/stream/services.py +45 -0
- ommlds/minichain/chat/choices/stream/types.py +43 -0
- ommlds/minichain/chat/choices/types.py +2 -2
- ommlds/minichain/chat/history.py +3 -3
- ommlds/minichain/chat/messages.py +55 -19
- ommlds/minichain/chat/services.py +3 -3
- ommlds/minichain/chat/stream/_marshal.py +16 -0
- ommlds/minichain/chat/stream/joining.py +85 -0
- ommlds/minichain/chat/stream/services.py +15 -21
- ommlds/minichain/chat/stream/types.py +32 -19
- ommlds/minichain/chat/tools/execution.py +8 -7
- ommlds/minichain/chat/tools/ids.py +9 -15
- ommlds/minichain/chat/tools/parsing.py +17 -26
- ommlds/minichain/chat/transforms/base.py +29 -38
- ommlds/minichain/chat/transforms/metadata.py +30 -4
- ommlds/minichain/chat/transforms/services.py +9 -11
- ommlds/minichain/content/_marshal.py +44 -20
- ommlds/minichain/content/json.py +13 -0
- ommlds/minichain/content/materialize.py +14 -21
- ommlds/minichain/content/prepare.py +4 -0
- ommlds/minichain/content/transforms/interleave.py +1 -1
- ommlds/minichain/content/transforms/squeeze.py +1 -1
- ommlds/minichain/content/transforms/stringify.py +1 -1
- ommlds/minichain/json.py +20 -0
- ommlds/minichain/lib/code/__init__.py +0 -0
- ommlds/minichain/lib/code/prompts.py +6 -0
- ommlds/minichain/lib/fs/binfiles.py +108 -0
- ommlds/minichain/lib/fs/context.py +126 -0
- ommlds/minichain/lib/fs/errors.py +101 -0
- ommlds/minichain/lib/fs/suggestions.py +36 -0
- ommlds/minichain/lib/fs/tools/__init__.py +0 -0
- ommlds/minichain/lib/fs/tools/edit.py +104 -0
- ommlds/minichain/lib/fs/tools/ls.py +38 -0
- ommlds/minichain/lib/fs/tools/read.py +115 -0
- ommlds/minichain/lib/fs/tools/recursivels/__init__.py +0 -0
- ommlds/minichain/lib/fs/tools/recursivels/execution.py +40 -0
- ommlds/minichain/lib/todo/__init__.py +0 -0
- ommlds/minichain/lib/todo/context.py +54 -0
- ommlds/minichain/lib/todo/tools/__init__.py +0 -0
- ommlds/minichain/lib/todo/tools/read.py +44 -0
- ommlds/minichain/lib/todo/tools/write.py +335 -0
- ommlds/minichain/lib/todo/types.py +60 -0
- ommlds/minichain/llms/_marshal.py +25 -17
- ommlds/minichain/llms/types.py +4 -0
- ommlds/minichain/registries/globals.py +18 -4
- ommlds/minichain/resources.py +66 -43
- ommlds/minichain/search.py +1 -1
- ommlds/minichain/services/_marshal.py +46 -39
- ommlds/minichain/services/facades.py +3 -3
- ommlds/minichain/services/services.py +1 -1
- ommlds/minichain/standard.py +8 -0
- ommlds/minichain/stream/services.py +152 -38
- ommlds/minichain/stream/wrap.py +22 -24
- ommlds/minichain/tools/_marshal.py +1 -1
- ommlds/minichain/tools/execution/catalog.py +2 -1
- ommlds/minichain/tools/execution/context.py +34 -14
- ommlds/minichain/tools/execution/errors.py +15 -0
- ommlds/minichain/tools/execution/executors.py +8 -3
- ommlds/minichain/tools/execution/reflect.py +40 -5
- ommlds/minichain/tools/fns.py +46 -9
- ommlds/minichain/tools/jsonschema.py +14 -5
- ommlds/minichain/tools/reflect.py +54 -18
- ommlds/minichain/tools/types.py +33 -1
- ommlds/minichain/utils.py +27 -0
- ommlds/minichain/vectors/_marshal.py +11 -10
- ommlds/nanochat/LICENSE +21 -0
- ommlds/nanochat/__init__.py +0 -0
- ommlds/nanochat/rustbpe/LICENSE +21 -0
- ommlds/nanochat/tokenizers.py +406 -0
- ommlds/server/server.py +3 -3
- ommlds/specs/__init__.py +0 -0
- ommlds/specs/mcp/__init__.py +0 -0
- ommlds/specs/mcp/_marshal.py +23 -0
- ommlds/specs/mcp/protocol.py +266 -0
- ommlds/tools/git.py +27 -10
- ommlds/tools/ocr.py +8 -9
- ommlds/wiki/analyze.py +2 -2
- ommlds/wiki/text/mfh.py +1 -5
- ommlds/wiki/text/wtp.py +1 -3
- ommlds/wiki/utils/xml.py +5 -5
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/METADATA +24 -21
- ommlds-0.0.0.dev480.dist-info/RECORD +427 -0
- ommlds/cli/backends/standard.py +0 -20
- ommlds/cli/sessions/chat/base.py +0 -42
- ommlds/cli/sessions/chat/interactive.py +0 -73
- ommlds/cli/sessions/chat/printing.py +0 -96
- ommlds/cli/sessions/chat/prompt.py +0 -143
- ommlds/cli/sessions/chat/state.py +0 -109
- ommlds/cli/sessions/chat/tools.py +0 -91
- ommlds/cli/sessions/completion/completion.py +0 -44
- ommlds/cli/sessions/embedding/embedding.py +0 -42
- ommlds/cli/tools/config.py +0 -13
- ommlds/cli/tools/inject.py +0 -64
- ommlds/minichain/chat/stream/adapters.py +0 -69
- ommlds/minichain/lib/fs/ls/execution.py +0 -32
- ommlds-0.0.0.dev440.dist-info/RECORD +0 -303
- /ommlds/{cli/tools → backends/google}/__init__.py +0 -0
- /ommlds/{minichain/lib/fs/ls → backends/groq}/__init__.py +0 -0
- /ommlds/{huggingface.py → backends/huggingface.py} +0 -0
- /ommlds/minichain/lib/fs/{ls → tools/recursivels}/rendering.py +0 -0
- /ommlds/minichain/lib/fs/{ls → tools/recursivels}/running.py +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/WHEEL +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/entry_points.txt +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/licenses/LICENSE +0 -0
- {ommlds-0.0.0.dev440.dist-info → ommlds-0.0.0.dev480.dist-info}/top_level.txt +0 -0
ommlds/_hacks/funcs.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import dataclasses as dc
|
|
2
|
+
import linecache
|
|
3
|
+
import textwrap
|
|
4
|
+
import threading
|
|
5
|
+
import types
|
|
6
|
+
import typing as ta
|
|
7
|
+
import uuid
|
|
8
|
+
import warnings
|
|
9
|
+
|
|
10
|
+
from omlish import check
|
|
11
|
+
from omlish import lang
|
|
12
|
+
|
|
13
|
+
from .names import NamespaceBuilder
|
|
14
|
+
from .params import render_param_spec_call
|
|
15
|
+
from .params import render_param_spec_def
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dc.dataclass()
|
|
22
|
+
class _ReservedFilenameEntry:
|
|
23
|
+
unique_id: str
|
|
24
|
+
seq: int = 0
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
_RESERVED_FILENAME_UUID_TLS = threading.local()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def reserve_linecache_filename(prefix: str) -> str:
|
|
31
|
+
try:
|
|
32
|
+
e = _RESERVED_FILENAME_UUID_TLS.unique_id
|
|
33
|
+
except AttributeError:
|
|
34
|
+
e = _RESERVED_FILENAME_UUID_TLS.unique_id = _ReservedFilenameEntry(str(uuid.uuid4()))
|
|
35
|
+
|
|
36
|
+
while True:
|
|
37
|
+
unique_filename = f'<generated:{prefix}:{e.seq}>'
|
|
38
|
+
cache_line = (1, None, (e.unique_id,), unique_filename)
|
|
39
|
+
e.seq += 1
|
|
40
|
+
if linecache.cache.setdefault(unique_filename, cache_line) == cache_line: # type: ignore
|
|
41
|
+
return unique_filename
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def create_function(
|
|
48
|
+
name: str,
|
|
49
|
+
params: lang.CanParamSpec,
|
|
50
|
+
body: str,
|
|
51
|
+
*,
|
|
52
|
+
globals: ta.Mapping[str, ta.Any] | None = None, # noqa
|
|
53
|
+
locals: ta.Mapping[str, ta.Any] | None = None, # noqa
|
|
54
|
+
indent: str = ' ',
|
|
55
|
+
) -> types.FunctionType:
|
|
56
|
+
params = lang.ParamSpec.of(params)
|
|
57
|
+
check.isinstance(body, str)
|
|
58
|
+
locals = dict(locals or {}) # noqa
|
|
59
|
+
|
|
60
|
+
nsb = NamespaceBuilder(reserved_names=set(locals) | set(globals or []))
|
|
61
|
+
sig = render_param_spec_def(params, nsb)
|
|
62
|
+
for k, v in nsb.items():
|
|
63
|
+
check.not_in(k, locals)
|
|
64
|
+
locals[k] = v
|
|
65
|
+
|
|
66
|
+
body_txt = '\n'.join([
|
|
67
|
+
f'def {name}{sig}:',
|
|
68
|
+
textwrap.indent(textwrap.dedent(body.strip()), indent),
|
|
69
|
+
])
|
|
70
|
+
|
|
71
|
+
exec_txt = '\n'.join([
|
|
72
|
+
f'def __create_fn__({", ".join(locals.keys())}):',
|
|
73
|
+
textwrap.indent(body_txt, indent),
|
|
74
|
+
f'{indent}return {name}',
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
ns: dict = {}
|
|
78
|
+
filename = reserve_linecache_filename(name)
|
|
79
|
+
bytecode = compile(exec_txt, filename, 'exec')
|
|
80
|
+
eval(bytecode, globals or {}, ns) # type: ignore # noqa
|
|
81
|
+
|
|
82
|
+
fn = ns['__create_fn__'](**locals)
|
|
83
|
+
fn.__source__ = body_txt
|
|
84
|
+
linecache.cache[filename] = (len(exec_txt), None, exec_txt.splitlines(True), filename)
|
|
85
|
+
return fn
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def create_detour(
|
|
92
|
+
params: lang.CanParamSpec,
|
|
93
|
+
target: ta.Callable,
|
|
94
|
+
*,
|
|
95
|
+
as_kwargs: bool = False,
|
|
96
|
+
) -> types.CodeType:
|
|
97
|
+
params = lang.ParamSpec.of(params)
|
|
98
|
+
check.callable(target)
|
|
99
|
+
|
|
100
|
+
with warnings.catch_warnings():
|
|
101
|
+
warnings.filterwarnings('ignore', category=SyntaxWarning)
|
|
102
|
+
|
|
103
|
+
gfn = create_function(
|
|
104
|
+
'_',
|
|
105
|
+
params,
|
|
106
|
+
f'return 1{render_param_spec_call(params, as_kwargs=as_kwargs)}',
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
check.state(gfn.__code__.co_consts[:2] == (None, 1))
|
|
110
|
+
return gfn.__code__.replace(co_consts=(None, target, *gfn.__code__.co_consts[2:]))
|
ommlds/_hacks/names.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- releaseable names
|
|
4
|
+
"""
|
|
5
|
+
import string
|
|
6
|
+
import typing as ta
|
|
7
|
+
|
|
8
|
+
from omlish import check
|
|
9
|
+
from omlish import collections as col
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class NameGenerator(ta.Protocol):
|
|
16
|
+
def __call__(self, prefix: str = '') -> str: ...
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class NameGeneratorImpl:
|
|
23
|
+
DEFAULT_PREFIX: ta.ClassVar[str] = '_'
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
*,
|
|
28
|
+
reserved_names: ta.Iterable[str] | None = None,
|
|
29
|
+
global_prefix: str | None = None,
|
|
30
|
+
use_global_prefix_if_present: bool = False,
|
|
31
|
+
add_global_prefix_before_number: bool = False,
|
|
32
|
+
) -> None:
|
|
33
|
+
super().__init__()
|
|
34
|
+
|
|
35
|
+
check.arg(not isinstance(reserved_names, str))
|
|
36
|
+
self._reserved_names = {check.isinstance(n, str) for n in (reserved_names or [])}
|
|
37
|
+
self._global_prefix = global_prefix if global_prefix is not None else self.DEFAULT_PREFIX
|
|
38
|
+
self._use_global_prefix_if_present = bool(use_global_prefix_if_present)
|
|
39
|
+
self._add_global_prefix_before_number = bool(add_global_prefix_before_number)
|
|
40
|
+
|
|
41
|
+
self._name_counts: dict[str, int] = {}
|
|
42
|
+
|
|
43
|
+
def __call__(self, prefix: str = '') -> str:
|
|
44
|
+
if self._use_global_prefix_if_present and prefix.startswith(self._global_prefix):
|
|
45
|
+
base_name = prefix
|
|
46
|
+
else:
|
|
47
|
+
base_name = self._global_prefix + prefix
|
|
48
|
+
|
|
49
|
+
base_count = -1
|
|
50
|
+
if base_name[-1] in string.digits:
|
|
51
|
+
i = len(base_name) - 2
|
|
52
|
+
while i >= 0 and base_name[i] in string.digits:
|
|
53
|
+
i -= 1
|
|
54
|
+
i += 1
|
|
55
|
+
base_count = int(base_name[i:])
|
|
56
|
+
base_name = base_name[:i]
|
|
57
|
+
|
|
58
|
+
if self._add_global_prefix_before_number:
|
|
59
|
+
if not (self._use_global_prefix_if_present and base_name.endswith(self._global_prefix)):
|
|
60
|
+
base_name += self._global_prefix
|
|
61
|
+
|
|
62
|
+
if base_count >= 0:
|
|
63
|
+
count = self._name_counts.setdefault(base_name, 0)
|
|
64
|
+
if base_count > count:
|
|
65
|
+
self._name_counts[base_name] = base_count
|
|
66
|
+
|
|
67
|
+
while True:
|
|
68
|
+
count = self._name_counts.get(base_name, 0)
|
|
69
|
+
self._name_counts[base_name] = count + 1
|
|
70
|
+
name = base_name + str(count)
|
|
71
|
+
if name not in self._reserved_names:
|
|
72
|
+
return name
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
name_generator = NameGeneratorImpl
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class NamespaceBuilder(ta.Mapping[str, ta.Any]):
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
*,
|
|
85
|
+
reserved_names: ta.Iterable[str] | None = None,
|
|
86
|
+
name_generator: NameGenerator | None = None, # noqa
|
|
87
|
+
) -> None:
|
|
88
|
+
super().__init__()
|
|
89
|
+
|
|
90
|
+
self._reserved_names = {
|
|
91
|
+
check.isinstance(n, str)
|
|
92
|
+
for n in (check.not_isinstance(reserved_names, str) or [])
|
|
93
|
+
}
|
|
94
|
+
self._name_generator = check.callable(name_generator) if name_generator is not None else \
|
|
95
|
+
NameGeneratorImpl(reserved_names=self._reserved_names, use_global_prefix_if_present=True)
|
|
96
|
+
|
|
97
|
+
self._dct: ta.MutableMapping[str, ta.Any] = {}
|
|
98
|
+
self._dedupe_dct: ta.MutableMapping[ta.Any, str] = col.IdentityKeyDict()
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def reserved_names(self) -> ta.AbstractSet[str]:
|
|
102
|
+
return self._reserved_names
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def name_generator(self) -> NameGenerator:
|
|
106
|
+
return self._name_generator
|
|
107
|
+
|
|
108
|
+
def __getitem__(self, k: str) -> ta.Any:
|
|
109
|
+
return self._dct[k]
|
|
110
|
+
|
|
111
|
+
def __len__(self):
|
|
112
|
+
return len(self._dct)
|
|
113
|
+
|
|
114
|
+
def __iter__(self) -> ta.Iterator[str]:
|
|
115
|
+
return iter(self._dct)
|
|
116
|
+
|
|
117
|
+
def items(self) -> ta.ItemsView[str, ta.Any]:
|
|
118
|
+
return self._dct.items()
|
|
119
|
+
|
|
120
|
+
def put(
|
|
121
|
+
self,
|
|
122
|
+
value: ta.Any,
|
|
123
|
+
name: str | None = None,
|
|
124
|
+
*,
|
|
125
|
+
exact: bool = False,
|
|
126
|
+
dedupe: bool = False,
|
|
127
|
+
) -> str:
|
|
128
|
+
check.arg(not (name is None and exact))
|
|
129
|
+
if name is not None:
|
|
130
|
+
check.isinstance(name, str)
|
|
131
|
+
|
|
132
|
+
if dedupe:
|
|
133
|
+
try:
|
|
134
|
+
return self._dedupe_dct[value]
|
|
135
|
+
except KeyError:
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
if name is not None:
|
|
139
|
+
if name not in self._reserved_names:
|
|
140
|
+
try:
|
|
141
|
+
existing = self._dct[name]
|
|
142
|
+
except KeyError:
|
|
143
|
+
self._dct[name] = value
|
|
144
|
+
if dedupe:
|
|
145
|
+
self._dedupe_dct[value] = name
|
|
146
|
+
return name
|
|
147
|
+
else:
|
|
148
|
+
if existing is value:
|
|
149
|
+
return name
|
|
150
|
+
if exact:
|
|
151
|
+
raise KeyError(name)
|
|
152
|
+
|
|
153
|
+
gen_name = self._name_generator(name or '')
|
|
154
|
+
check.not_in(gen_name, self._dct)
|
|
155
|
+
self._dct[gen_name] = value
|
|
156
|
+
if dedupe:
|
|
157
|
+
self._dedupe_dct[value] = gen_name
|
|
158
|
+
return gen_name
|
ommlds/_hacks/params.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import lang
|
|
4
|
+
|
|
5
|
+
from .names import NamespaceBuilder
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def render_param_spec_call(
|
|
12
|
+
params: lang.ParamSpec,
|
|
13
|
+
*,
|
|
14
|
+
as_kwargs: bool = False,
|
|
15
|
+
) -> str:
|
|
16
|
+
src = ['(']
|
|
17
|
+
|
|
18
|
+
for i, p in enumerate(params):
|
|
19
|
+
if isinstance(p, lang.ParamSeparator):
|
|
20
|
+
continue
|
|
21
|
+
|
|
22
|
+
if i:
|
|
23
|
+
src.append(', ')
|
|
24
|
+
|
|
25
|
+
if as_kwargs:
|
|
26
|
+
if isinstance(p, lang.Param):
|
|
27
|
+
src.append(f'{p.name}={p.name}')
|
|
28
|
+
else:
|
|
29
|
+
raise TypeError(p)
|
|
30
|
+
|
|
31
|
+
else:
|
|
32
|
+
if isinstance(p, lang.ArgsParam):
|
|
33
|
+
src.append(f'*{p.name}')
|
|
34
|
+
elif isinstance(p, lang.KwargsParam):
|
|
35
|
+
src.append(f'**{p.name}')
|
|
36
|
+
elif isinstance(p, lang.PosOnlyParam):
|
|
37
|
+
src.append(p.name)
|
|
38
|
+
elif isinstance(p, lang.KwOnlyParam):
|
|
39
|
+
src.append(f'{p.name}={p.name}')
|
|
40
|
+
elif isinstance(p, lang.ValParam):
|
|
41
|
+
src.append(p.name)
|
|
42
|
+
else:
|
|
43
|
+
raise TypeError(p)
|
|
44
|
+
|
|
45
|
+
src.append(')')
|
|
46
|
+
|
|
47
|
+
return ''.join(src)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def render_param_spec_def(
|
|
51
|
+
params: lang.ParamSpec,
|
|
52
|
+
nsb: NamespaceBuilder,
|
|
53
|
+
*,
|
|
54
|
+
return_ann: lang.Maybe[ta.Any] = lang.empty(),
|
|
55
|
+
) -> str:
|
|
56
|
+
src = ['(']
|
|
57
|
+
|
|
58
|
+
for i, p in enumerate(params):
|
|
59
|
+
if i:
|
|
60
|
+
src.append(', ')
|
|
61
|
+
|
|
62
|
+
src.append(lang.param_render(
|
|
63
|
+
p,
|
|
64
|
+
render_annotation=lambda ann: nsb.put(ann, f'ann_{p.name}'), # noqa
|
|
65
|
+
render_default=lambda dfl: nsb.put(dfl, f'dfl_{p.name}'), # noqa
|
|
66
|
+
))
|
|
67
|
+
|
|
68
|
+
src.append(')')
|
|
69
|
+
|
|
70
|
+
if return_ann.present:
|
|
71
|
+
src.append(f' -> {nsb.put(return_ann.must(), "ann_return")}')
|
|
72
|
+
|
|
73
|
+
return ''.join(src)
|
ommlds/_hacks/patches.py
CHANGED
|
@@ -8,7 +8,7 @@ from .types import Content
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@lang.static_init
|
|
11
|
-
def
|
|
11
|
+
def _install_standard_marshaling() -> None:
|
|
12
12
|
for root_cls in [
|
|
13
13
|
Content,
|
|
14
14
|
Content.CacheControl,
|
|
@@ -17,7 +17,7 @@ def _install_standard_marshalling() -> None:
|
|
|
17
17
|
msh.polymorphism_from_subclasses(
|
|
18
18
|
root_cls,
|
|
19
19
|
naming=msh.Naming.SNAKE,
|
|
20
|
-
strip_suffix=
|
|
20
|
+
strip_suffix=msh.AutoStripSuffix,
|
|
21
21
|
),
|
|
22
22
|
msh.FieldTypeTagging('type'),
|
|
23
23
|
))
|
|
@@ -8,7 +8,7 @@ from .events import AnthropicSseDecoderEvents
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@lang.static_init
|
|
11
|
-
def
|
|
11
|
+
def _install_standard_marshaling() -> None:
|
|
12
12
|
for root_cls in [
|
|
13
13
|
AnthropicSseDecoderEvents.Event,
|
|
14
14
|
AnthropicSseDecoderEvents.ContentBlockStart.ContentBlock,
|
|
@@ -63,9 +63,10 @@ class AnthropicSseMessageAssembler(
|
|
|
63
63
|
while True:
|
|
64
64
|
ae: ta.Any = check.not_none((yield from self._next_event()))
|
|
65
65
|
if isinstance(ae, AnthropicSseDecoderEvents.ContentBlockStart):
|
|
66
|
-
check.equal(ae.index, len(content))
|
|
66
|
+
# check.equal(ae.index, len(content))
|
|
67
67
|
c = yield from self._do_content_block(ae)
|
|
68
|
-
|
|
68
|
+
if c is not None:
|
|
69
|
+
content.append(check.isinstance(c, Content))
|
|
69
70
|
elif isinstance(ae, AnthropicSseDecoderEvents.MessageDelta):
|
|
70
71
|
for k in ('stop_reason', 'stop_sequence'):
|
|
71
72
|
if (v := getattr(ae.delta, k)) is not None:
|
|
@@ -76,7 +77,7 @@ class AnthropicSseMessageAssembler(
|
|
|
76
77
|
elif isinstance(ae, AnthropicSseDecoderEvents.MessageStop):
|
|
77
78
|
yield [Message(
|
|
78
79
|
id=ms.message.id,
|
|
79
|
-
role=ms.message.role,
|
|
80
|
+
role=ms.message.role, # type: ignore[arg-type]
|
|
80
81
|
model=ms.message.model,
|
|
81
82
|
content=content,
|
|
82
83
|
stop_reason=dct['stop_reason'],
|
|
@@ -92,6 +93,8 @@ class AnthropicSseMessageAssembler(
|
|
|
92
93
|
return (yield from self._do_text_content_block(cbs))
|
|
93
94
|
elif isinstance(cbs.content_block, AnthropicSseDecoderEvents.ContentBlockStart.ToolUse):
|
|
94
95
|
return (yield from self._do_tool_use_content_block(cbs))
|
|
96
|
+
elif isinstance(cbs.content_block, AnthropicSseDecoderEvents.ContentBlockStart.Thinking):
|
|
97
|
+
return (yield from self._do_thinking_content_block(cbs))
|
|
95
98
|
else:
|
|
96
99
|
raise TypeError(cbs.content_block)
|
|
97
100
|
|
|
@@ -101,11 +104,11 @@ class AnthropicSseMessageAssembler(
|
|
|
101
104
|
while True:
|
|
102
105
|
ae: ta.Any = check.not_none((yield from self._next_event()))
|
|
103
106
|
if isinstance(ae, AnthropicSseDecoderEvents.ContentBlockDelta):
|
|
104
|
-
check.equal(ae.index, cbs.index)
|
|
107
|
+
# check.equal(ae.index, cbs.index)
|
|
105
108
|
cdc = check.isinstance(ae.delta, AnthropicSseDecoderEvents.ContentBlockDelta.TextDelta)
|
|
106
109
|
parts.append(cdc.text)
|
|
107
110
|
elif isinstance(ae, AnthropicSseDecoderEvents.ContentBlockStop):
|
|
108
|
-
check.equal(ae.index, cbs.index)
|
|
111
|
+
# check.equal(ae.index, cbs.index)
|
|
109
112
|
return Text(''.join(parts))
|
|
110
113
|
else:
|
|
111
114
|
raise TypeError(ae)
|
|
@@ -119,11 +122,11 @@ class AnthropicSseMessageAssembler(
|
|
|
119
122
|
while True:
|
|
120
123
|
ae: ta.Any = check.not_none((yield from self._next_event()))
|
|
121
124
|
if isinstance(ae, AnthropicSseDecoderEvents.ContentBlockDelta):
|
|
122
|
-
check.equal(ae.index, cbs.index)
|
|
125
|
+
# check.equal(ae.index, cbs.index)
|
|
123
126
|
cdc = check.isinstance(ae.delta, AnthropicSseDecoderEvents.ContentBlockDelta.InputJsonDelta)
|
|
124
127
|
json_parts.append(cdc.partial_json)
|
|
125
128
|
elif isinstance(ae, AnthropicSseDecoderEvents.ContentBlockStop):
|
|
126
|
-
check.equal(ae.index, cbs.index)
|
|
129
|
+
# check.equal(ae.index, cbs.index)
|
|
127
130
|
dj = ''.join(json_parts).strip()
|
|
128
131
|
if dj:
|
|
129
132
|
dd = check.isinstance(json.loads(dj), ta.Mapping)
|
|
@@ -138,3 +141,16 @@ class AnthropicSseMessageAssembler(
|
|
|
138
141
|
)
|
|
139
142
|
else:
|
|
140
143
|
raise TypeError(ae)
|
|
144
|
+
|
|
145
|
+
def _do_thinking_content_block(self, cbs: AnthropicSseDecoderEvents.ContentBlockStart) -> ta.Any:
|
|
146
|
+
# csc = check.isinstance(cbs.content_block, AnthropicSseDecoderEvents.ContentBlockStart.Thinking)
|
|
147
|
+
while True:
|
|
148
|
+
ae: ta.Any = check.not_none((yield from self._next_event()))
|
|
149
|
+
if isinstance(ae, AnthropicSseDecoderEvents.ContentBlockDelta):
|
|
150
|
+
pass
|
|
151
|
+
elif isinstance(ae, AnthropicSseDecoderEvents.ContentBlockStop):
|
|
152
|
+
return None
|
|
153
|
+
else:
|
|
154
|
+
raise TypeError(ae)
|
|
155
|
+
return # type: ignore # noqa
|
|
156
|
+
yield # noqa
|
|
@@ -80,6 +80,11 @@ class AnthropicSseDecoderEvents(lang.Namespace):
|
|
|
80
80
|
name: str
|
|
81
81
|
input: ta.Any
|
|
82
82
|
|
|
83
|
+
@dc.dataclass(frozen=True)
|
|
84
|
+
class Thinking(ContentBlock):
|
|
85
|
+
signature: str
|
|
86
|
+
thinking: str
|
|
87
|
+
|
|
83
88
|
content_block: ContentBlock
|
|
84
89
|
index: int
|
|
85
90
|
|
|
@@ -96,6 +101,14 @@ class AnthropicSseDecoderEvents(lang.Namespace):
|
|
|
96
101
|
class InputJsonDelta(Delta):
|
|
97
102
|
partial_json: str
|
|
98
103
|
|
|
104
|
+
@dc.dataclass(frozen=True)
|
|
105
|
+
class ThinkingDelta(Delta):
|
|
106
|
+
thinking: str
|
|
107
|
+
|
|
108
|
+
@dc.dataclass(frozen=True)
|
|
109
|
+
class SignatureDelta(Delta):
|
|
110
|
+
signature: str
|
|
111
|
+
|
|
99
112
|
delta: Delta
|
|
100
113
|
index: int
|
|
101
114
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"""
|
|
2
|
+
https://docs.claude.com/en/api/messages
|
|
3
|
+
"""
|
|
1
4
|
import typing as ta
|
|
2
5
|
|
|
3
6
|
from omlish import dataclasses as dc
|
|
@@ -8,6 +11,22 @@ from omlish import marshal as msh
|
|
|
8
11
|
##
|
|
9
12
|
|
|
10
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
|
+
|
|
11
30
|
class Content(lang.Abstract, lang.Sealed):
|
|
12
31
|
class CacheControl(lang.Abstract, lang.Sealed):
|
|
13
32
|
"""https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching"""
|
|
@@ -18,7 +37,7 @@ class Content(lang.Abstract, lang.Sealed):
|
|
|
18
37
|
|
|
19
38
|
|
|
20
39
|
@dc.dataclass(frozen=True)
|
|
21
|
-
@
|
|
40
|
+
@_set_class_marshal_options
|
|
22
41
|
class Text(Content):
|
|
23
42
|
text: str
|
|
24
43
|
|
|
@@ -28,7 +47,7 @@ class Text(Content):
|
|
|
28
47
|
|
|
29
48
|
|
|
30
49
|
@dc.dataclass(frozen=True)
|
|
31
|
-
@
|
|
50
|
+
@_set_class_marshal_options
|
|
32
51
|
class ToolUse(Content):
|
|
33
52
|
id: str
|
|
34
53
|
name: str
|
|
@@ -40,6 +59,7 @@ class ToolUse(Content):
|
|
|
40
59
|
|
|
41
60
|
|
|
42
61
|
@dc.dataclass(frozen=True)
|
|
62
|
+
@_set_class_marshal_options
|
|
43
63
|
class ToolResult(Content):
|
|
44
64
|
tool_use_id: str
|
|
45
65
|
content: str
|
|
@@ -49,7 +69,7 @@ class ToolResult(Content):
|
|
|
49
69
|
|
|
50
70
|
|
|
51
71
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
52
|
-
@
|
|
72
|
+
@_set_class_marshal_options
|
|
53
73
|
class CacheCreation:
|
|
54
74
|
ephemeral_5m_input_tokens: int | None = None
|
|
55
75
|
ephemeral_1h_input_tokens: int | None = None
|
|
@@ -59,7 +79,7 @@ class CacheCreation:
|
|
|
59
79
|
|
|
60
80
|
|
|
61
81
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
62
|
-
@
|
|
82
|
+
@_set_class_marshal_options
|
|
63
83
|
class Usage:
|
|
64
84
|
input_tokens: int | None = None
|
|
65
85
|
output_tokens: int | None = None
|
|
@@ -75,15 +95,15 @@ class Usage:
|
|
|
75
95
|
|
|
76
96
|
|
|
77
97
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
78
|
-
@
|
|
98
|
+
@_set_class_marshal_options
|
|
79
99
|
class Message:
|
|
80
100
|
id: str | None = None
|
|
81
101
|
|
|
82
|
-
role:
|
|
102
|
+
role: ta.Literal['user', 'assistant']
|
|
83
103
|
|
|
84
104
|
model: str | None = None
|
|
85
105
|
|
|
86
|
-
content: ta.Sequence[Content] | None = None
|
|
106
|
+
content: str | ta.Sequence[Content] | None = None
|
|
87
107
|
|
|
88
108
|
stop_reason: str | None = None
|
|
89
109
|
stop_sequence: str | None = None
|
|
@@ -95,6 +115,7 @@ class Message:
|
|
|
95
115
|
|
|
96
116
|
|
|
97
117
|
@dc.dataclass(frozen=True)
|
|
118
|
+
@_set_class_marshal_options
|
|
98
119
|
class ToolSpec:
|
|
99
120
|
name: str
|
|
100
121
|
description: str
|
|
@@ -105,7 +126,7 @@ class ToolSpec:
|
|
|
105
126
|
|
|
106
127
|
|
|
107
128
|
@dc.dataclass(frozen=True)
|
|
108
|
-
@
|
|
129
|
+
@_set_class_marshal_options
|
|
109
130
|
class MessagesRequest:
|
|
110
131
|
model: str
|
|
111
132
|
|
|
@@ -113,7 +134,7 @@ class MessagesRequest:
|
|
|
113
134
|
|
|
114
135
|
_: dc.KW_ONLY
|
|
115
136
|
|
|
116
|
-
system: ta.Sequence[Content] | None = None
|
|
137
|
+
system: str | ta.Sequence[Content] | None = None
|
|
117
138
|
|
|
118
139
|
tools: ta.Sequence[ToolSpec] | None = None
|
|
119
140
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from omlish import lang
|
|
2
|
+
from omlish import marshal as msh
|
|
3
|
+
|
|
4
|
+
from .types import Value
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@lang.static_init
|
|
11
|
+
def _install_standard_marshaling() -> None:
|
|
12
|
+
msh.install_standard_factories(
|
|
13
|
+
*msh.standard_polymorphism_factories(
|
|
14
|
+
msh.polymorphism_from_subclasses(Value),
|
|
15
|
+
),
|
|
16
|
+
)
|