cat-stack 2.5.2__tar.gz → 2.5.3__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 (45) hide show
  1. {cat_stack-2.5.2 → cat_stack-2.5.3}/PKG-INFO +4 -4
  2. {cat_stack-2.5.2 → cat_stack-2.5.3}/README.md +1 -1
  3. {cat_stack-2.5.2 → cat_stack-2.5.3}/pyproject.toml +2 -2
  4. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/__about__.py +1 -1
  5. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_providers.py +18 -0
  6. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/image_functions.py +2 -0
  7. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/pdf_functions.py +2 -0
  8. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/text_functions_ensemble.py +3 -0
  9. {cat_stack-2.5.2 → cat_stack-2.5.3}/.gitignore +0 -0
  10. {cat_stack-2.5.2 → cat_stack-2.5.3}/LICENSE +0 -0
  11. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/cat_stack/__init__.py +0 -0
  12. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/__init__.py +0 -0
  13. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_batch.py +0 -0
  14. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_category_analysis.py +0 -0
  15. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_chunked.py +0 -0
  16. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_embeddings.py +0 -0
  17. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_formatter.py +0 -0
  18. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_pilot_test.py +0 -0
  19. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_prompts.py +0 -0
  20. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_review_ui.py +0 -0
  21. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_tiebreaker.py +0 -0
  22. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_utils.py +0 -0
  23. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_web_fetch.py +0 -0
  24. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/_wrapper_helpers.py +0 -0
  25. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/CoVe.py +0 -0
  26. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/__init__.py +0 -0
  27. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/image_CoVe.py +0 -0
  28. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/image_stepback.py +0 -0
  29. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/pdf_CoVe.py +0 -0
  30. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/pdf_stepback.py +0 -0
  31. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/stepback.py +0 -0
  32. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/calls/top_n.py +0 -0
  33. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/classify.py +0 -0
  34. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/collapse_themes.py +0 -0
  35. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/explore.py +0 -0
  36. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/extract.py +0 -0
  37. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/images/circle.png +0 -0
  38. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/images/cube.png +0 -0
  39. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/images/diamond.png +0 -0
  40. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/images/overlapping_pentagons.png +0 -0
  41. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/images/rectangles.png +0 -0
  42. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/model_reference_list.py +0 -0
  43. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/prompt_tune.py +0 -0
  44. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/summarize.py +0 -0
  45. {cat_stack-2.5.2 → cat_stack-2.5.3}/src/catstack/text_functions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cat-stack
3
- Version: 2.5.2
3
+ Version: 2.5.3
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
@@ -24,9 +24,9 @@ Requires-Dist: pandas
24
24
  Requires-Dist: requests
25
25
  Requires-Dist: tqdm
26
26
  Provides-Extra: agent
27
- Requires-Dist: cat-claws[claude]>=0.3.2; extra == 'agent'
27
+ Requires-Dist: cat-claws[claude]>=0.3.3; extra == 'agent'
28
28
  Provides-Extra: codex-agent
29
- Requires-Dist: cat-claws[codex]>=0.3.2; extra == 'codex-agent'
29
+ Requires-Dist: cat-claws[codex]>=0.3.3; extra == 'codex-agent'
30
30
  Provides-Extra: docx
31
31
  Requires-Dist: python-docx>=1.0.0; extra == 'docx'
32
32
  Provides-Extra: embeddings
@@ -239,7 +239,7 @@ OpenAI, Anthropic, Google (Gemini), Mistral, Perplexity, xAI (Grok), HuggingFace
239
239
 
240
240
  All providers use the same `(model_name, provider, api_key)` tuple format. Provider is auto-detected from model name if omitted.
241
241
 
242
- **Subscription backends (no API key).** Three `model_source` values authenticate through a chat subscription instead of a metered key — leave `api_key` unset: `"claude-agent"` (Claude subscription via the Agent SDK; `pip install "cat-stack[agent]"`), `"claude-code"` (the Claude Code CLI, if installed — no extra needed), and `"codex-agent"` (ChatGPT subscription; `pip install "cat-stack[codex-agent]"`). Classification, extraction, exploration, and summarization all route through them.
242
+ **Subscription backends (no API key).** Three `model_source` values authenticate through a chat subscription instead of a metered key — leave `api_key` unset: `"claude-agent"` (Claude subscription via the Agent SDK; `pip install "cat-stack[agent]"`), `"claude-code"` (the Claude Code CLI, if installed — no extra needed), and `"codex-agent"` (ChatGPT subscription; `pip install "cat-stack[codex-agent]"`). Classification, extraction, exploration, and summarization all route through them, including images and PDF pages on the two agent backends. They use the agent CLI's own sign-in (separate from the Claude desktop app's): runs check it up front and, if you're signed out, open a single browser window to sign in once, then continue. See the [cat-claws README](https://github.com/chrissoria/cat-agent#signing-in-once).
243
243
 
244
244
  **Reproducibility note:** the same nominal model can behave differently across access routes. In a seed-matched benchmark (Claude Sonnet 5, temperature 0), extraction through the Agent SDK produced more varied label phrasings than the direct API (89% vs. 74% unique raw labels), while final consolidated taxonomies were equivalent. If raw label counts matter to your analysis, record the access route alongside the model version.
245
245
 
@@ -198,7 +198,7 @@ OpenAI, Anthropic, Google (Gemini), Mistral, Perplexity, xAI (Grok), HuggingFace
198
198
 
199
199
  All providers use the same `(model_name, provider, api_key)` tuple format. Provider is auto-detected from model name if omitted.
200
200
 
201
- **Subscription backends (no API key).** Three `model_source` values authenticate through a chat subscription instead of a metered key — leave `api_key` unset: `"claude-agent"` (Claude subscription via the Agent SDK; `pip install "cat-stack[agent]"`), `"claude-code"` (the Claude Code CLI, if installed — no extra needed), and `"codex-agent"` (ChatGPT subscription; `pip install "cat-stack[codex-agent]"`). Classification, extraction, exploration, and summarization all route through them.
201
+ **Subscription backends (no API key).** Three `model_source` values authenticate through a chat subscription instead of a metered key — leave `api_key` unset: `"claude-agent"` (Claude subscription via the Agent SDK; `pip install "cat-stack[agent]"`), `"claude-code"` (the Claude Code CLI, if installed — no extra needed), and `"codex-agent"` (ChatGPT subscription; `pip install "cat-stack[codex-agent]"`). Classification, extraction, exploration, and summarization all route through them, including images and PDF pages on the two agent backends. They use the agent CLI's own sign-in (separate from the Claude desktop app's): runs check it up front and, if you're signed out, open a single browser window to sign in once, then continue. See the [cat-claws README](https://github.com/chrissoria/cat-agent#signing-in-once).
202
202
 
203
203
  **Reproducibility note:** the same nominal model can behave differently across access routes. In a seed-matched benchmark (Claude Sonnet 5, temperature 0), extraction through the Agent SDK produced more varied label phrasings than the direct API (89% vs. 74% unique raw labels), while final consolidated taxonomies were equivalent. If raw label counts matter to your analysis, record the access route alongside the model version.
204
204
 
@@ -42,8 +42,8 @@ embeddings = ["sentence-transformers>=2.2.0"]
42
42
  # `agent` keeps its historical meaning (the Claude backend) so every shipped
43
43
  # install hint stays true; `codex-agent` matches the provider string so the
44
44
  # error-message hint is copy-pasteable.
45
- agent = ["cat-claws[claude]>=0.3.2"]
46
- codex-agent = ["cat-claws[codex]>=0.3.2"]
45
+ agent = ["cat-claws[claude]>=0.3.3"]
46
+ codex-agent = ["cat-claws[codex]>=0.3.3"]
47
47
 
48
48
  [project.urls]
49
49
  Documentation = "https://github.com/chrissoria/cat-stack#readme"
@@ -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__ = "2.5.2"
4
+ __version__ = "2.5.3"
5
5
  __author__ = "Chris Soria"
6
6
  __email__ = "chrissoria@berkeley.edu"
7
7
  __title__ = "cat-stack"
@@ -790,6 +790,24 @@ def _split_agent_content(content):
790
790
  return "\n\n".join(t for t in texts if t), images
791
791
 
792
792
 
793
+ def _require_agent_sign_in(provider):
794
+ """Preflight for the cat-claws subscription backends: stop before any row
795
+ runs when the agent CLI is signed out, instead of every row failing on
796
+ "not logged in". cat-claws >= 0.3.3 checks with a cheap status call (no
797
+ model call); if signed out it opens ONE browser sign-in automatically and
798
+ continues, or, where no browser can open, raises NotSignedInError with
799
+ instructions worded for the Claude app or a terminal. No-op for other
800
+ providers, and when cat-claws is missing or older.
801
+ """
802
+ if provider not in _AGENT_BACKENDS:
803
+ return
804
+ try:
805
+ from catclaws import ensure_signed_in
806
+ except ImportError:
807
+ return
808
+ ensure_signed_in(_AGENT_BACKENDS[provider][0])
809
+
810
+
793
811
  def _require_http_provider(model_source, feature):
794
812
  """Raise a clear error when an HTTP-only feature is used with a
795
813
  subscription/CLI provider (claude-code / claude-agent / codex-agent)."""
@@ -154,6 +154,8 @@ def image_multi_class(
154
154
  "(the text-only CLI shim). Use model_source='claude-agent' (the cat-claws "
155
155
  "subscription backend) or an API-key provider."
156
156
  )
157
+ from ._providers import _require_agent_sign_in
158
+ _require_agent_sign_in(model_source)
157
159
 
158
160
  image_files = _load_image_files(image_input)
159
161
 
@@ -399,6 +399,8 @@ def pdf_multi_class(
399
399
  "(the text-only CLI shim). Use model_source='claude-agent' (the cat-claws "
400
400
  "subscription backend) or an API-key provider."
401
401
  )
402
+ from ._providers import _require_agent_sign_in
403
+ _require_agent_sign_in(model_source)
402
404
 
403
405
  # Providers with native PDF support (only used in image/both modes)
404
406
  native_pdf_providers = {"anthropic", "google"}
@@ -53,6 +53,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
53
53
  from typing import Optional, Callable, Union
54
54
 
55
55
  from ._utils import _extract_balanced_json
56
+ from ._providers import _require_agent_sign_in
56
57
  from .text_functions import (
57
58
  UnifiedLLMClient,
58
59
  detect_provider,
@@ -684,6 +685,7 @@ def prepare_model_configs(
684
685
  "Install: pip install cat-stack[agent]\n"
685
686
  + "="*60
686
687
  )
688
+ _require_agent_sign_in(detected_provider)
687
689
  elif detected_provider == "codex-agent":
688
690
  try:
689
691
  import catclaws # noqa: F401
@@ -696,6 +698,7 @@ def prepare_model_configs(
696
698
  'Install: pip install "cat-stack[codex-agent]"\n'
697
699
  + "="*60
698
700
  )
701
+ _require_agent_sign_in(detected_provider)
699
702
  else:
700
703
  # Validate API key exists for cloud providers
701
704
  if not api_key:
File without changes
File without changes