python-fastllm 0.0.14__tar.gz → 0.0.16__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.
Files changed (29) hide show
  1. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/PKG-INFO +2 -2
  2. python_fastllm-0.0.16/fastllm/__init__.py +1 -0
  3. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/anthropic.py +1 -0
  4. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/chat.py +1 -1
  5. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/gemini.py +1 -0
  6. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/openai_chat.py +1 -0
  7. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/openai_responses.py +1 -0
  8. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/types.py +9 -6
  9. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/pyproject.toml +2 -2
  10. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/python_fastllm.egg-info/PKG-INFO +2 -2
  11. python_fastllm-0.0.16/python_fastllm.egg-info/requires.txt +3 -0
  12. python_fastllm-0.0.14/fastllm/__init__.py +0 -1
  13. python_fastllm-0.0.14/python_fastllm.egg-info/requires.txt +0 -3
  14. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/README.md +0 -0
  15. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/_modidx.py +0 -0
  16. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/acomplete.py +0 -0
  17. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/codex.py +0 -0
  18. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/specs/anthropic.json +0 -0
  19. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/specs/anthropic.yml +0 -0
  20. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/specs/gemini.json +0 -0
  21. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/specs/openai.with-code-samples.json +0 -0
  22. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/specs/openai.with-code-samples.yml +0 -0
  23. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/specs/spec_manifest.json +0 -0
  24. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/fastllm/streaming.py +0 -0
  25. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/python_fastllm.egg-info/SOURCES.txt +0 -0
  26. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/python_fastllm.egg-info/dependency_links.txt +0 -0
  27. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/python_fastllm.egg-info/entry_points.txt +0 -0
  28. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/python_fastllm.egg-info/top_level.txt +0 -0
  29. {python_fastllm-0.0.14 → python_fastllm-0.0.16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-fastllm
3
- Version: 0.0.14
3
+ Version: 0.0.16
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
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3 :: Only
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: fastspec
12
+ Requires-Dist: fastspec>=0.0.9
13
13
  Requires-Dist: toolslm
14
14
  Requires-Dist: pillow
15
15
 
@@ -0,0 +1 @@
1
+ __version__ = "0.0.16"
@@ -85,6 +85,7 @@ def norm_parts(resp):
85
85
 
86
86
  # %% ../nbs/04_anthropic.ipynb #a3869e31
87
87
  def norm_sse_event(ev, **kwargs):
88
+ ev = obj2dict(ev)
88
89
  typ = ev.get("type")
89
90
  text, thinking, tcs, citations = None, None, [], None
90
91
  if typ == "content_block_start":
@@ -316,7 +316,7 @@ def _has_stop(tres_parts): return any(isinstance(p.text, StopResponse) for p in
316
316
  def _trunc_str(s, mx=2000, skip=10, replace="TRUNCATED"):
317
317
  "Truncate `s` to `mx` chars max, adding `replace` if truncated"
318
318
  if not isinstance(s, str): s = str(s)
319
- s = s.rstrip() if type(s) is str else type(s)(s.rstrip())
319
+ s = type(s)(s.rstrip())
320
320
  if len(s)>2 and s[0]=='𝍁' and s[-1]=='𝍁':
321
321
  s = s[1:-1]
322
322
  if replace: return s
@@ -86,6 +86,7 @@ def norm_parts(resp):
86
86
  # %% ../nbs/05_gemini.ipynb #9a5024ee
87
87
  def norm_sse_event(ev, **kwargs):
88
88
  "Normalize Gemini stream event into Delta."
89
+ ev = obj2dict(ev)
89
90
  cand = nested_idx(ev, 'candidates', 0) or {}
90
91
  finish_reason = norm_finish(ev)
91
92
  parts = nested_idx(cand, 'content', 'parts') or []
@@ -55,6 +55,7 @@ def norm_parts(resp):
55
55
  def norm_sse_event(ev, **kwargs):
56
56
  "Normalize a chat completion stream event."
57
57
  # usage always arrives as a single final event with choices: []
58
+ ev = obj2dict(ev)
58
59
  fin = nested_idx(ev, 'choices', 0, 'finish_reason')
59
60
  tcs = norm_tool_calls(ev, delta=True)
60
61
  if (dlt:=nested_idx(ev, 'choices', 0, 'delta')) is not None:
@@ -82,6 +82,7 @@ def norm_parts(resp):
82
82
  # %% ../nbs/02_oai_responses.ipynb #7cd48aa5
83
83
  def norm_sse_event(ev, **kwargs):
84
84
  "Normalize OpenAI Responses API stream event into Delta."
85
+ ev = obj2dict(ev)
85
86
  typ = ev.get("type")
86
87
  if typ == "response.output_text.delta": return Delta(text=ev.get("delta"), raw=ev, **kwargs)
87
88
  if typ == "response.reasoning_text.delta": return Delta(thinking=ev.get("delta",""), raw=ev, **kwargs)
@@ -161,6 +161,7 @@ api_registry = APIRegistry()
161
161
  # %% ../nbs/00_types.ipynb #d58a5f96
162
162
  def mk_completion(resp, model, api_name, vendor_name):
163
163
  "Normalize an api response into Completion."
164
+ resp = obj2dict(resp)
164
165
  api = api_registry.apis[api_name]
165
166
  tcs = api.norm_tool_calls(resp)
166
167
  parts = api.norm_parts(resp)
@@ -258,8 +259,11 @@ def resize_b64(b64, max_sz):
258
259
  # %% ../nbs/00_types.ipynb #852adecd
259
260
  model_prices_url = 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json'
260
261
 
261
- @flexicache(time_policy(24*60*60))
262
- def model_prices_meta(): return urljson(model_prices_url)
262
+ def model_prices_meta():
263
+ "Download model prices to the module dir once, then load from disk."
264
+ p = Path(__file__).parent/'model_prices.json'
265
+ if not p.exists(): p.write_text(httpx.get(model_prices_url, follow_redirects=True).text)
266
+ return loads(p.read_text())
263
267
 
264
268
  # %% ../nbs/00_types.ipynb #68e488d8
265
269
  def infer_api_name(model):
@@ -269,7 +273,6 @@ def infer_api_name(model):
269
273
  if any(o in model for o in ('gpt','o3-','o4-')): return 'openai'
270
274
 
271
275
  # %% ../nbs/00_types.ipynb #2f0720c2
272
- @flexicache(time_policy(24*60*60))
273
276
  def get_model_meta(model, vendor_name=None, tfm=noop):
274
277
  "Look up cost metadata for `model` from litellm price map, using `vendor_name` prefix if needed."
275
278
  vendor_name = ifnone(vendor_name, infer_api_name(model))
@@ -277,7 +280,7 @@ def get_model_meta(model, vendor_name=None, tfm=noop):
277
280
  if model in mp: key = model
278
281
  elif vendor_name=='gemini' and model.startswith('models/'): key = f"gemini/{model.removeprefix('models/')}"
279
282
  elif vendor_name: key = f"{vendor_name}/{model}"
280
- return dict2obj(tfm(mp.get(key), model, vendor_name))
283
+ return dict2obj(tfm(mp.get(key, {}), model, vendor_name))
281
284
 
282
285
  # %% ../nbs/00_types.ipynb #60607e23
283
286
  haik45 = "claude-haiku-4-5"
@@ -355,9 +358,9 @@ register_model_info('deepseek-v4-pro', vendor_name='deepseek', base='deepseek/de
355
358
 
356
359
  mimo_v25_common = dict(**modern_llm, supports_web_search=True, max_input_tokens=1048576, max_output_tokens=131072, max_tokens=131072)
357
360
 
358
- register_model_info('mimo-v2.5-pro', vendor_name='mimo', **mimo_v25_common, base='deepseek/deepseek-v4-pro',
361
+ register_model_info('mimo-v2.5-pro', vendor_name='mimo', **mimo_v25_common, base='deepseek-v4-pro', base_vendor_name='deepseek',
359
362
  input_cost_per_token=0.435e-6, output_cost_per_token=0.87e-6, cache_read_input_token_cost=0.0036e-6, search_context_cost_per_query=0.005)
360
- register_model_info('mimo-v2.5', vendor_name='mimo', **mimo_v25_common, base='deepseek/deepseek-v4',
363
+ register_model_info('mimo-v2.5', vendor_name='mimo', **mimo_v25_common, base='deepseek-v4-pro', base_vendor_name='deepseek',
361
364
  input_cost_per_token=0.14e-6, output_cost_per_token=0.28e-6, cache_read_input_token_cost=0.0028e-6, search_context_cost_per_query=0.005,
362
365
  supports_vision=True, supports_image_input=True)
363
366
 
@@ -15,7 +15,7 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3",
16
16
  "Programming Language :: Python :: 3 :: Only",
17
17
  ]
18
- dependencies = ['fastspec', 'toolslm', 'pillow']
18
+ dependencies = ['fastspec>=0.0.9', 'toolslm', 'pillow']
19
19
 
20
20
  [project.urls]
21
21
  Repository = "https://github.com/AnswerDotAI/fastllm"
@@ -36,4 +36,4 @@ fastllm = ["specs/*.yml", "specs/*.json"]
36
36
  allowed_metadata_keys = ['solveit']
37
37
  allowed_cell_metadata_keys = ['solveit_ai']
38
38
  custom_sidebar = false
39
- lib_path = "fastllm"
39
+ lib_path = "fastllm"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-fastllm
3
- Version: 0.0.14
3
+ Version: 0.0.16
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
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3 :: Only
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: fastspec
12
+ Requires-Dist: fastspec>=0.0.9
13
13
  Requires-Dist: toolslm
14
14
  Requires-Dist: pillow
15
15
 
@@ -0,0 +1,3 @@
1
+ fastspec>=0.0.9
2
+ toolslm
3
+ pillow
@@ -1 +0,0 @@
1
- __version__ = "0.0.14"
@@ -1,3 +0,0 @@
1
- fastspec
2
- toolslm
3
- pillow