python-fastllm 0.0.32__tar.gz → 0.0.34__tar.gz
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.
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/PKG-INFO +2 -2
- python_fastllm-0.0.34/fastllm/__init__.py +1 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/_modidx.py +4 -5
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/acomplete.py +22 -7
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/chat.py +2 -30
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/streaming.py +1 -1
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/types.py +28 -25
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/pyproject.toml +1 -1
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/PKG-INFO +2 -2
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/requires.txt +1 -1
- python_fastllm-0.0.32/fastllm/__init__.py +0 -1
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/README.md +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/anthropic.py +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/codex.py +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/gemini.py +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/openai_chat.py +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/openai_responses.py +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/specs/anthropic.json +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/specs/anthropic.yml +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/specs/gemini.json +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/specs/openai.with-code-samples.json +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/specs/openai.with-code-samples.yml +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/fastllm/specs/spec_manifest.json +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/SOURCES.txt +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/dependency_links.txt +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/entry_points.txt +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/top_level.txt +0 -0
- {python_fastllm-0.0.32 → python_fastllm-0.0.34}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-fastllm
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
4
4
|
Author-email: Kerem Turgutlu <keremturgutlu@gmail.com>
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Repository, https://github.com/AnswerDotAI/fastllm
|
|
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
Requires-Dist: fastcore>=2.1.11
|
|
13
|
-
Requires-Dist: aidialog>=0.0.
|
|
13
|
+
Requires-Dist: aidialog>=0.0.5
|
|
14
14
|
Requires-Dist: fastspec>=0.0.11
|
|
15
15
|
Requires-Dist: toolslm
|
|
16
16
|
Requires-Dist: pillow
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.34"
|
|
@@ -10,6 +10,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
10
10
|
'fastllm.acomplete._classify_error': ('acomplete.html#_classify_error', 'fastllm/acomplete.py'),
|
|
11
11
|
'fastllm.acomplete._classify_error_stream': ( 'acomplete.html#_classify_error_stream',
|
|
12
12
|
'fastllm/acomplete.py'),
|
|
13
|
+
'fastllm.acomplete._codex_mtime_policy': ('acomplete.html#_codex_mtime_policy', 'fastllm/acomplete.py'),
|
|
13
14
|
'fastllm.acomplete._debug_print': ('acomplete.html#_debug_print', 'fastllm/acomplete.py'),
|
|
14
15
|
'fastllm.acomplete._is_ctx_exceeded': ('acomplete.html#_is_ctx_exceeded', 'fastllm/acomplete.py'),
|
|
15
16
|
'fastllm.acomplete._raise_if_done': ('acomplete.html#_raise_if_done', 'fastllm/acomplete.py'),
|
|
@@ -106,7 +107,6 @@ d = { 'settings': { 'branch': 'main',
|
|
|
106
107
|
'fastllm.chat._add_cache_control': ('chat.html#_add_cache_control', 'fastllm/chat.py'),
|
|
107
108
|
'fastllm.chat._alite_call_func': ('chat.html#_alite_call_func', 'fastllm/chat.py'),
|
|
108
109
|
'fastllm.chat._apply_cache_idxs': ('chat.html#_apply_cache_idxs', 'fastllm/chat.py'),
|
|
109
|
-
'fastllm.chat._bytes2content': ('chat.html#_bytes2content', 'fastllm/chat.py'),
|
|
110
110
|
'fastllm.chat._call_func': ('chat.html#_call_func', 'fastllm/chat.py'),
|
|
111
111
|
'fastllm.chat._handle_stop_reason': ('chat.html#_handle_stop_reason', 'fastllm/chat.py'),
|
|
112
112
|
'fastllm.chat._has_cache': ('chat.html#_has_cache', 'fastllm/chat.py'),
|
|
@@ -114,14 +114,11 @@ d = { 'settings': { 'branch': 'main',
|
|
|
114
114
|
'fastllm.chat._has_stop': ('chat.html#_has_stop', 'fastllm/chat.py'),
|
|
115
115
|
'fastllm.chat._inject_tool_reminder': ('chat.html#_inject_tool_reminder', 'fastllm/chat.py'),
|
|
116
116
|
'fastllm.chat._lite_call_func': ('chat.html#_lite_call_func', 'fastllm/chat.py'),
|
|
117
|
-
'fastllm.chat._mime2part_type': ('chat.html#_mime2part_type', 'fastllm/chat.py'),
|
|
118
|
-
'fastllm.chat._mk_content': ('chat.html#_mk_content', 'fastllm/chat.py'),
|
|
119
117
|
'fastllm.chat._mk_prefill': ('chat.html#_mk_prefill', 'fastllm/chat.py'),
|
|
120
118
|
'fastllm.chat._mk_tool_result': ('chat.html#_mk_tool_result', 'fastllm/chat.py'),
|
|
121
119
|
'fastllm.chat._tc_summary': ('chat.html#_tc_summary', 'fastllm/chat.py'),
|
|
122
120
|
'fastllm.chat._think_kw': ('chat.html#_think_kw', 'fastllm/chat.py'),
|
|
123
121
|
'fastllm.chat._trunc_param': ('chat.html#_trunc_param', 'fastllm/chat.py'),
|
|
124
|
-
'fastllm.chat._url2content': ('chat.html#_url2content', 'fastllm/chat.py'),
|
|
125
122
|
'fastllm.chat._usrtools': ('chat.html#_usrtools', 'fastllm/chat.py'),
|
|
126
123
|
'fastllm.chat.add_warning': ('chat.html#add_warning', 'fastllm/chat.py'),
|
|
127
124
|
'fastllm.chat.adisplay_stream': ('chat.html#adisplay_stream', 'fastllm/chat.py'),
|
|
@@ -253,7 +250,9 @@ d = { 'settings': { 'branch': 'main',
|
|
|
253
250
|
'fastllm.streaming.norm_and_yield': ('streaming.html#norm_and_yield', 'fastllm/streaming.py'),
|
|
254
251
|
'fastllm.streaming.stop_and_trim': ('streaming.html#stop_and_trim', 'fastllm/streaming.py')},
|
|
255
252
|
'fastllm.types': { 'fastllm.types.APIRegistry': ('types.html#apiregistry', 'fastllm/types.py'),
|
|
256
|
-
'fastllm.types.APIRegistry.
|
|
253
|
+
'fastllm.types.APIRegistry.__contains__': ('types.html#apiregistry.__contains__', 'fastllm/types.py'),
|
|
254
|
+
'fastllm.types.APIRegistry.__missing__': ('types.html#apiregistry.__missing__', 'fastllm/types.py'),
|
|
255
|
+
'fastllm.types.APIRegistry._load': ('types.html#apiregistry._load', 'fastllm/types.py'),
|
|
257
256
|
'fastllm.types.APIRegistry.register': ('types.html#apiregistry.register', 'fastllm/types.py'),
|
|
258
257
|
'fastllm.types.Completion': ('types.html#completion', 'fastllm/types.py'),
|
|
259
258
|
'fastllm.types.Completion._repr_markdown_': ('types.html#completion._repr_markdown_', 'fastllm/types.py'),
|
|
@@ -54,14 +54,29 @@ api2spec = {'openai':oai_spec, 'openai_chat':oai_spec, 'anthropic':ant_spec, 'ge
|
|
|
54
54
|
|
|
55
55
|
# %% ../nbs/06_acomplete.ipynb #e3ed40fb
|
|
56
56
|
def split_vendor(model):
|
|
57
|
-
"Split a `'vendor/model'` path into `(vendor_name, model)`: the prefix must name a known vendor or a registered api, else `(None, model)`."
|
|
57
|
+
"Split a `'vendor/model'` path into `(vendor_name, model)`: the prefix must name a known vendor or a registered api (installed `fastllm.apis` plugins load on demand), else `(None, model)`."
|
|
58
58
|
if model and '/' in model:
|
|
59
59
|
v, m = model.split('/', 1)
|
|
60
|
-
if v in vendor_mapping or v in api_registry
|
|
60
|
+
if v in vendor_mapping or v in api_registry: return v, m
|
|
61
61
|
return None, model
|
|
62
62
|
|
|
63
|
+
# %% ../nbs/06_acomplete.ipynb #977a115b
|
|
64
|
+
def _codex_mtime_policy():
|
|
65
|
+
"`flexicache` policy: expire codex clients when the codex auth file changes"
|
|
66
|
+
def policy(state, args, kwargs):
|
|
67
|
+
v = kwargs.get('vendor_name') or (args[1] if len(args)>1 else None)
|
|
68
|
+
if not v:
|
|
69
|
+
m = kwargs.get('model') or (args[0] if args else None)
|
|
70
|
+
v = split_vendor(m)[0] if m else None
|
|
71
|
+
if v != 'codex': return None
|
|
72
|
+
try: mt = Path(_codex_path).expanduser().stat().st_mtime
|
|
73
|
+
except OSError: mt = None
|
|
74
|
+
return mt if state != mt else None
|
|
75
|
+
policy.needs_args = True
|
|
76
|
+
return policy
|
|
77
|
+
|
|
63
78
|
# %% ../nbs/06_acomplete.ipynb #79075d95
|
|
64
|
-
@flexicache()
|
|
79
|
+
@flexicache(_codex_mtime_policy())
|
|
65
80
|
def mk_client(model=None, vendor_name=None, api_name=None, api_key=None, base_url=None, xtra_hdrs=None,
|
|
66
81
|
timeout=httpx.Timeout(connect=30, read=300, write=30, pool=10)):
|
|
67
82
|
err_msg = f"please pass a valid one vendor: {', '.join(list(vendor_mapping))} or pass `api_name`,`base_url` and `api_key`"
|
|
@@ -82,7 +97,7 @@ def mk_client(model=None, vendor_name=None, api_name=None, api_key=None, base_ur
|
|
|
82
97
|
elif base_url and api_key: vendor_name, api_name = ifnone(vendor_name, 'custom'), ifnone(api_name, 'openai_chat')
|
|
83
98
|
elif (api_name:=infer_api_name(model)): base_url, vendor_name = None, api_name
|
|
84
99
|
else: raise ValueError(f"Model {model} can't be auto resolved, {err_msg}")
|
|
85
|
-
api = api_registry
|
|
100
|
+
api = api_registry[api_name]
|
|
86
101
|
spec, hdrs = api2spec[api_name], api.get_hdrs(api_key)
|
|
87
102
|
cli = OpenAPIClient(spec, headers=merge(hdrs, ifnone(xtra_hdrs, {})), timeout=timeout)
|
|
88
103
|
if base_url is not None:
|
|
@@ -163,13 +178,13 @@ async def acomplete(msgs, model, api_name=None, vendor_name=None, api_key=None,
|
|
|
163
178
|
elif v: api_name, model = v, m # a registered transport api (e.g. claude_code): not an HTTP vendor
|
|
164
179
|
if api_name == 'claude_code':
|
|
165
180
|
if not stream: raise NotImplementedError("claude_code backend supports stream=True only for now")
|
|
166
|
-
api = api_registry
|
|
181
|
+
api = api_registry[api_name]
|
|
167
182
|
payload = api.mk_payload(msgs, model, stream=stream, **kwargs)
|
|
168
183
|
async def _mk_gen():
|
|
169
184
|
async for o in api.acollect_stream(payload, model=model, vendor_name='claude_code', stop_callables=stop_callables): yield o
|
|
170
185
|
return _retry_stream(_mk_gen, retries, retry_delay)
|
|
171
|
-
cli, api_name, vendor_name = mk_client(model, vendor_name, api_name, api_key, base_url, xtra_hdrs)
|
|
172
|
-
api = api_registry
|
|
186
|
+
cli, api_name, vendor_name = mk_client(model=model, vendor_name=vendor_name, api_name=api_name, api_key=api_key, base_url=base_url, xtra_hdrs=xtra_hdrs)
|
|
187
|
+
api = api_registry[api_name]
|
|
173
188
|
payload = api.mk_payload(msgs, model, stream=stream, **kwargs)
|
|
174
189
|
payload = merge(payload, ifnone(xtra_body, {}))
|
|
175
190
|
if vendor_name == 'codex':
|
|
@@ -15,35 +15,13 @@ from toolslm.funccall import mk_ns, call_func, call_func_async, get_schema
|
|
|
15
15
|
from fastcore.utils import *
|
|
16
16
|
from fastcore.meta import delegates
|
|
17
17
|
from dataclasses import dataclass
|
|
18
|
-
import base64
|
|
19
18
|
|
|
20
19
|
from .types import *
|
|
21
|
-
from fastcore.xtras import detect_mime
|
|
22
20
|
from aidialog.msg_parts import (Msg, Part, PartType, ToolCall, mk_tool_res_msg, mk_tr_details,
|
|
23
|
-
tool_info, usage_info, think_start, think_end, StopResponse, display_list,
|
|
24
|
-
_mk_result_fence, _split_fence_msgs, _fence_back, _trunc_str)
|
|
21
|
+
tool_info, usage_info, think_start, think_end, StopResponse, display_list, fmt2hist,
|
|
22
|
+
_mk_content, _mk_result_fence, _split_fence_msgs, _fence_back, _trunc_str)
|
|
25
23
|
from .acomplete import *
|
|
26
24
|
|
|
27
|
-
# %% ../nbs/07_chat.ipynb #4a37bae5
|
|
28
|
-
def _mime2part_type(mime):
|
|
29
|
-
"Map MIME string to canonical PartType"
|
|
30
|
-
if mime.startswith('image/'): return PartType.input_image
|
|
31
|
-
if mime.startswith('audio/'): return PartType.input_audio
|
|
32
|
-
if mime.startswith('video/'): return PartType.input_video
|
|
33
|
-
return PartType.input_file
|
|
34
|
-
|
|
35
|
-
def _bytes2content(data):
|
|
36
|
-
"Convert bytes to fastllm canonical content"
|
|
37
|
-
mtype = detect_mime(data)
|
|
38
|
-
if not mtype: raise ValueError(f'Data must be a supported file type, got {data[:10]}')
|
|
39
|
-
encoded = base64.b64encode(data).decode("utf-8")
|
|
40
|
-
return Part(type=_mime2part_type(mtype), text=f'data:{mtype};base64,{encoded}')
|
|
41
|
-
|
|
42
|
-
def _url2content(o):
|
|
43
|
-
"Convert MediaUrl to fastllm canonical content"
|
|
44
|
-
mime = o.mime or url_mime(o.url)
|
|
45
|
-
return Part(type=_mime2part_type(mime), text=o.url, data=dict(mime=mime))
|
|
46
|
-
|
|
47
25
|
# %% ../nbs/07_chat.ipynb #43a55cda
|
|
48
26
|
def _add_cache_control(
|
|
49
27
|
msg, # LiteLLM formatted msg
|
|
@@ -67,12 +45,6 @@ def remove_cache_ckpts(msg):
|
|
|
67
45
|
if part.data: part.data.pop('cache_control', None)
|
|
68
46
|
return msg
|
|
69
47
|
|
|
70
|
-
def _mk_content(o):
|
|
71
|
-
if isinstance(o, str): return Part(type=PartType.text, text=o)
|
|
72
|
-
elif isinstance(o, bytes): return _bytes2content(o)
|
|
73
|
-
elif isinstance(o, MediaUrl): return _url2content(o)
|
|
74
|
-
return o
|
|
75
|
-
|
|
76
48
|
|
|
77
49
|
# %% ../nbs/07_chat.ipynb #48c78e48
|
|
78
50
|
def contents(c):
|
|
@@ -150,7 +150,7 @@ async def mk_acollect_stream(it, index_fn, model=None, api_name=None, vendor_nam
|
|
|
150
150
|
deltas.append(d)
|
|
151
151
|
part_accum.finalize()
|
|
152
152
|
tcs = part_accum.tool_calls
|
|
153
|
-
if api_name: usg = api_registry
|
|
153
|
+
if api_name: usg = api_registry[api_name].finalize_usage(usg, part_accum.parts)
|
|
154
154
|
if stop: fin = FinishReason.stop
|
|
155
155
|
fin = FinishReason.tool_calls if fin==FinishReason.stop and any(~L(tcs).attrgot('server')) else fin # recheck tool calls post collation
|
|
156
156
|
# tool calls and non-anthropic citations are yielded at the end
|
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_types.ipynb.
|
|
4
4
|
|
|
5
5
|
# %% auto #0
|
|
6
|
-
__all__ = ['FinishReason', 'api_registry', 'model_prices_url', 'haik45', 'sonn45', '
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'get_model_info', 'get_model_pricing', 'approx_pricing',
|
|
6
|
+
__all__ = ['FinishReason', 'api_registry', 'model_prices_url', 'haik45', 'sonn45', 'sonn46', 'sonn', 'sonn5', 'opus46', 'opus48',
|
|
7
|
+
'opus', 'opus5', 'fable', 'fable5', 'gpt54', 'gpt54m', 'gpt55', 'codex54', 'codex54m', 'codex55',
|
|
8
|
+
'codex53spark', 'model_info_registry', 'modern_llm', 'deepseek_v4_common', 'mimo_v25_common',
|
|
9
|
+
'codex_pricing', 'sol', 'terra', 'luna', 'gpt56s', 'Usage', 'Completion', 'APIRegistry', 'mk_completion',
|
|
10
|
+
'fn_schema', 'payload_kwargs', 'get_api_key', 'resize_b64', 'model_prices_meta', 'infer_api_name',
|
|
11
|
+
'get_model_meta', 'register_model_info', 'get_model_info', 'get_model_pricing', 'approx_pricing',
|
|
12
|
+
'is_deepseek_peak_hour']
|
|
12
13
|
|
|
13
14
|
# %% ../nbs/00_types.ipynb #b4d047fd
|
|
14
15
|
import httpx, base64, io
|
|
16
|
+
from importlib.metadata import entry_points
|
|
15
17
|
from dataclasses import dataclass, field
|
|
16
18
|
from datetime import datetime, timezone
|
|
17
19
|
from fastcore.net import urljson
|
|
@@ -73,9 +75,18 @@ def _repr_markdown_(self: Completion):
|
|
|
73
75
|
FinishReason = str_enum('finish_reason', 'stop', 'tool_calls', 'length', 'content_filter')
|
|
74
76
|
|
|
75
77
|
# %% ../nbs/00_types.ipynb #fc681c52
|
|
76
|
-
class APIRegistry:
|
|
77
|
-
|
|
78
|
-
def register(self, name, finalize_usage=noop, **kwargs): self
|
|
78
|
+
class APIRegistry(dict):
|
|
79
|
+
_eps = None
|
|
80
|
+
def register(self, name, finalize_usage=noop, **kwargs): self[name] = SimpleNamespace(finalize_usage=finalize_usage, **kwargs)
|
|
81
|
+
def _load(self, name):
|
|
82
|
+
"Import the plugin providing api `name` from the `fastllm.apis` entry-point group; its import registers the api."
|
|
83
|
+
if self._eps is None: self._eps = {o.name:o for o in entry_points(group='fastllm.apis')}
|
|
84
|
+
if name in self._eps: self._eps[name].load()
|
|
85
|
+
return dict.__contains__(self, name)
|
|
86
|
+
def __contains__(self, name): return dict.__contains__(self, name) or self._load(name)
|
|
87
|
+
def __missing__(self, name):
|
|
88
|
+
if self._load(name): return self[name]
|
|
89
|
+
raise KeyError(name)
|
|
79
90
|
|
|
80
91
|
api_registry = APIRegistry()
|
|
81
92
|
|
|
@@ -84,7 +95,7 @@ api_registry = APIRegistry()
|
|
|
84
95
|
def mk_completion(resp, model, api_name, vendor_name):
|
|
85
96
|
"Normalize an api response into Completion."
|
|
86
97
|
resp = obj2dict(resp)
|
|
87
|
-
api = api_registry
|
|
98
|
+
api = api_registry[api_name]
|
|
88
99
|
tcs = api.norm_tool_calls(resp)
|
|
89
100
|
parts = api.norm_parts(resp)
|
|
90
101
|
usg = api.finalize_usage(api.norm_usage(resp), parts)
|
|
@@ -158,10 +169,12 @@ def get_model_meta(model, vendor_name=None, tfm=noop):
|
|
|
158
169
|
# %% ../nbs/00_types.ipynb #60607e23
|
|
159
170
|
haik45 = "claude-haiku-4-5"
|
|
160
171
|
sonn45 = "claude-sonnet-4-5"
|
|
161
|
-
|
|
162
|
-
sonn5 = "claude-sonnet-5"
|
|
172
|
+
sonn46 = "claude-sonnet-4-6"
|
|
173
|
+
sonn = sonn5 = "claude-sonnet-5"
|
|
163
174
|
opus46 = "claude-opus-4-6"
|
|
164
|
-
|
|
175
|
+
opus48 = "claude-opus-4-8"
|
|
176
|
+
opus = opus5 = "claude-opus-5"
|
|
177
|
+
fable = fable5 = 'claude-fable-5'
|
|
165
178
|
gpt54 = "gpt-5.4"
|
|
166
179
|
gpt54m = "gpt-5.4-mini"
|
|
167
180
|
gpt55 = "gpt-5.5"
|
|
@@ -186,9 +199,6 @@ def get_model_info(mn, vendor_name=None):
|
|
|
186
199
|
if 'search_context_cost_per_query' in info: info['supports_web_search'] = True
|
|
187
200
|
return dict2obj(info)
|
|
188
201
|
|
|
189
|
-
# %% ../nbs/00_types.ipynb #331c5d0a
|
|
190
|
-
register_model_info("claude-opus-4-8", vendor_name='anthropic', base="claude-opus-4-6")
|
|
191
|
-
|
|
192
202
|
# %% ../nbs/00_types.ipynb #b36178d4
|
|
193
203
|
modern_llm = dict(supports_function_calling=True, supports_tool_choice=True, supports_prompt_caching=True,
|
|
194
204
|
supports_parallel_function_calling=True, supports_native_streaming=True, supports_native_structured_output=True,
|
|
@@ -259,10 +269,6 @@ register_model_info('mimo-v2.5-pro-ultraspeed', vendor_name='mimo', **mimo_v25_c
|
|
|
259
269
|
# %% ../nbs/00_types.ipynb #defb1c5c
|
|
260
270
|
register_model_info('MiniMax-M3', vendor_name='minimax', **modern_llm, max_input_tokens=512_000, max_output_tokens=512_000, max_tokens=512_000, input_cost_per_token=0.3e-6, output_cost_per_token=1.2e-6, cache_read_input_token_cost=0.06e-6, supports_vision=True, supports_video_input=True)
|
|
261
271
|
|
|
262
|
-
register_model_info('claude-fable-5', vendor_name='anthropic', base="claude-opus-4-8",
|
|
263
|
-
input_cost_per_token=10e-6, cache_creation_input_token_cost=12.5e-6, output_cost_per_token=50e-6,
|
|
264
|
-
cache_read_input_token_cost=1e-6, search_context_cost_per_query=0.005)
|
|
265
|
-
|
|
266
272
|
# %% ../nbs/00_types.ipynb #4e1b40b3
|
|
267
273
|
register_model_info('muse-spark-1.1', vendor_name='meta_ai', **modern_llm,
|
|
268
274
|
max_input_tokens=1_048_576, max_output_tokens=128000, max_tokens=128000,
|
|
@@ -283,12 +289,9 @@ register_model_info(codex53spark, 'codex', **codex_pricing,
|
|
|
283
289
|
max_tokens=128000, max_input_tokens=128000, max_output_tokens=128000)
|
|
284
290
|
|
|
285
291
|
# %% ../nbs/00_types.ipynb #5d3e4720
|
|
286
|
-
for model in (haik45, sonn45, sonn46, sonn5, opus46,
|
|
292
|
+
for model in (haik45, sonn45, sonn46, sonn5, opus46, opus48, opus5, fable5):
|
|
287
293
|
register_model_info(model, 'claude_code', base=model, base_vendor_name='anthropic', **codex_pricing)
|
|
288
294
|
|
|
289
|
-
# %% ../nbs/00_types.ipynb #60630540
|
|
290
|
-
register_model_info(sonn5, base=sonn5, max_input_tokens=760_000)
|
|
291
|
-
|
|
292
295
|
# %% ../nbs/00_types.ipynb #bb0c4c2a
|
|
293
296
|
sol,terra,luna = gpt56s = 'gpt-5.6-sol gpt-5.6-terra gpt-5.6-luna'.split()
|
|
294
297
|
for model in ['gpt-5.6']+gpt56s:
|
|
@@ -321,7 +324,7 @@ def is_deepseek_peak_hour(dt=None):
|
|
|
321
324
|
@patch(as_prop=True)
|
|
322
325
|
def cost(self:Completion):
|
|
323
326
|
meta = dict2obj(get_model_info(self.model, self.vendor_name))
|
|
324
|
-
api = api_registry
|
|
327
|
+
api = api_registry[self.api_name]
|
|
325
328
|
if not hasattr(api, 'cost'): raise NotImplementedError(f"API: {self.api_name} doesn't have a registered `cost` function in ns")
|
|
326
329
|
res = api.cost(self.usage, meta)
|
|
327
330
|
return res*2 if self.vendor_name=='deepseek' and self.model.startswith('deepseek-v4') and is_deepseek_peak_hour() else res
|
|
@@ -15,7 +15,7 @@ classifiers = [
|
|
|
15
15
|
"Programming Language :: Python :: 3",
|
|
16
16
|
"Programming Language :: Python :: 3 :: Only",
|
|
17
17
|
]
|
|
18
|
-
dependencies = ['fastcore>=2.1.11', 'aidialog>=0.0.
|
|
18
|
+
dependencies = ['fastcore>=2.1.11', 'aidialog>=0.0.5', 'fastspec>=0.0.11', 'toolslm', 'pillow']
|
|
19
19
|
|
|
20
20
|
[project.urls]
|
|
21
21
|
Repository = "https://github.com/AnswerDotAI/fastllm"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-fastllm
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
4
4
|
Author-email: Kerem Turgutlu <keremturgutlu@gmail.com>
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Repository, https://github.com/AnswerDotAI/fastllm
|
|
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
Requires-Dist: fastcore>=2.1.11
|
|
13
|
-
Requires-Dist: aidialog>=0.0.
|
|
13
|
+
Requires-Dist: aidialog>=0.0.5
|
|
14
14
|
Requires-Dist: fastspec>=0.0.11
|
|
15
15
|
Requires-Dist: toolslm
|
|
16
16
|
Requires-Dist: pillow
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.32"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_fastllm-0.0.32 → python_fastllm-0.0.34}/python_fastllm.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|