cat-stack 1.6.1__tar.gz → 1.6.2__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 (44) hide show
  1. {cat_stack-1.6.1 → cat_stack-1.6.2}/PKG-INFO +1 -1
  2. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/__about__.py +1 -1
  3. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_providers.py +34 -3
  4. {cat_stack-1.6.1 → cat_stack-1.6.2}/.gitignore +0 -0
  5. {cat_stack-1.6.1 → cat_stack-1.6.2}/LICENSE +0 -0
  6. {cat_stack-1.6.1 → cat_stack-1.6.2}/README.md +0 -0
  7. {cat_stack-1.6.1 → cat_stack-1.6.2}/pyproject.toml +0 -0
  8. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/cat_stack/__init__.py +0 -0
  9. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/__init__.py +0 -0
  10. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_batch.py +0 -0
  11. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_category_analysis.py +0 -0
  12. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_chunked.py +0 -0
  13. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_embeddings.py +0 -0
  14. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_formatter.py +0 -0
  15. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_pilot_test.py +0 -0
  16. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_prompts.py +0 -0
  17. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_review_ui.py +0 -0
  18. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_tiebreaker.py +0 -0
  19. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_utils.py +0 -0
  20. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_web_fetch.py +0 -0
  21. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/_wrapper_helpers.py +0 -0
  22. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/CoVe.py +0 -0
  23. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/__init__.py +0 -0
  24. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/image_CoVe.py +0 -0
  25. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/image_stepback.py +0 -0
  26. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/pdf_CoVe.py +0 -0
  27. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/pdf_stepback.py +0 -0
  28. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/stepback.py +0 -0
  29. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/calls/top_n.py +0 -0
  30. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/classify.py +0 -0
  31. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/explore.py +0 -0
  32. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/extract.py +0 -0
  33. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/image_functions.py +0 -0
  34. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/images/circle.png +0 -0
  35. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/images/cube.png +0 -0
  36. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/images/diamond.png +0 -0
  37. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/images/overlapping_pentagons.png +0 -0
  38. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/images/rectangles.png +0 -0
  39. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/model_reference_list.py +0 -0
  40. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/pdf_functions.py +0 -0
  41. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/prompt_tune.py +0 -0
  42. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/summarize.py +0 -0
  43. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/text_functions.py +0 -0
  44. {cat_stack-1.6.1 → cat_stack-1.6.2}/src/catstack/text_functions_ensemble.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cat-stack
3
- Version: 1.6.1
3
+ Version: 1.6.2
4
4
  Summary: Domain-agnostic text, image, PDF, and DOCX classification engine powered by LLMs
5
5
  Project-URL: Documentation, https://github.com/chrissoria/cat-stack#readme
6
6
  Project-URL: Issues, https://github.com/chrissoria/cat-stack/issues
@@ -1,7 +1,7 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Christopher Soria <chrissoria@berkeley.edu>
2
2
  #
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
- __version__ = "1.6.1"
4
+ __version__ = "1.6.2"
5
5
  __author__ = "Chris Soria"
6
6
  __email__ = "chrissoria@berkeley.edu"
7
7
  __title__ = "cat-stack"
@@ -59,6 +59,26 @@ def _openai_reasoning_effort_floor(model: str) -> str:
59
59
  return floor
60
60
  return "minimal"
61
61
 
62
+
63
+ # ---------------------------------------------------------------------------
64
+ # HuggingFace `chat_template_kwargs={"enable_thinking": False}` is the knob
65
+ # to suppress Qwen3-family `<think>` blocks. Other model families don't
66
+ # expose an `enable_thinking` template variable, and strict HF backends
67
+ # (Fireworks, Groq) reject the unknown field with 400 — forcing a wasted
68
+ # retry. Restrict injection to families that actually honor the flag.
69
+ #
70
+ # The runtime fallback in `complete()` (strip-on-400) stays as a safety
71
+ # net for unexpected cases — e.g. if a Qwen variant lands on a router
72
+ # whose validator doesn't accept the field.
73
+ # ---------------------------------------------------------------------------
74
+ _HF_NEEDS_ENABLE_THINKING_OFF = (
75
+ "Qwen/Qwen3", # covers Qwen3, Qwen3.5, Qwen3.6, …
76
+ )
77
+
78
+
79
+ def _hf_model_needs_enable_thinking_off(model: str) -> bool:
80
+ return any(model.startswith(p) for p in _HF_NEEDS_ENABLE_THINKING_OFF)
81
+
62
82
  __all__ = [
63
83
  # Main client
64
84
  "UnifiedLLMClient",
@@ -449,9 +469,20 @@ class UnifiedLLMClient:
449
469
  elif creativity is not None:
450
470
  payload["temperature"] = creativity
451
471
 
452
- # HuggingFace: disable thinking for models that reason by default (e.g., Qwen3)
453
- # when thinking_budget is explicitly set to 0
454
- if self.provider in ("huggingface", "huggingface-together") and thinking_budget is not None and thinking_budget == 0:
472
+ # HuggingFace: disable thinking on model families whose chat
473
+ # template honors `enable_thinking` (Qwen3-family). Other HF-routed
474
+ # models don't need the kwarg, and strict-validator backends
475
+ # (Fireworks, Groq) reject the unknown field outright — sending it
476
+ # to a non-Qwen model just buys a wasted retry. See
477
+ # `_hf_model_needs_enable_thinking_off()`. The runtime fallback in
478
+ # `complete()` still strips on 400 if a router rejects the kwarg
479
+ # even for a model we expected to support it.
480
+ if (
481
+ self.provider in ("huggingface", "huggingface-together")
482
+ and thinking_budget is not None
483
+ and thinking_budget == 0
484
+ and _hf_model_needs_enable_thinking_off(self.model)
485
+ ):
455
486
  payload["chat_template_kwargs"] = {"enable_thinking": False}
456
487
 
457
488
  return payload
File without changes
File without changes
File without changes
File without changes