launchables 0.5.0__tar.gz → 0.6.0__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 (22) hide show
  1. {launchables-0.5.0 → launchables-0.6.0}/PKG-INFO +2 -2
  2. {launchables-0.5.0 → launchables-0.6.0}/README.md +1 -1
  3. launchables-0.6.0/src/launchables/_version.py +1 -0
  4. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/questions.py +7 -2
  5. {launchables-0.5.0 → launchables-0.6.0}/src/launchables.egg-info/PKG-INFO +2 -2
  6. {launchables-0.5.0 → launchables-0.6.0}/tests/test_client.py +8 -6
  7. launchables-0.5.0/src/launchables/_version.py +0 -1
  8. {launchables-0.5.0 → launchables-0.6.0}/LICENSE +0 -0
  9. {launchables-0.5.0 → launchables-0.6.0}/pyproject.toml +0 -0
  10. {launchables-0.5.0 → launchables-0.6.0}/setup.cfg +0 -0
  11. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/__init__.py +0 -0
  12. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/admin.py +0 -0
  13. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/batches.py +0 -0
  14. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/client.py +0 -0
  15. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/errors.py +0 -0
  16. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/images.py +0 -0
  17. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/py.typed +0 -0
  18. {launchables-0.5.0 → launchables-0.6.0}/src/launchables/responses.py +0 -0
  19. {launchables-0.5.0 → launchables-0.6.0}/src/launchables.egg-info/SOURCES.txt +0 -0
  20. {launchables-0.5.0 → launchables-0.6.0}/src/launchables.egg-info/dependency_links.txt +0 -0
  21. {launchables-0.5.0 → launchables-0.6.0}/src/launchables.egg-info/top_level.txt +0 -0
  22. {launchables-0.5.0 → launchables-0.6.0}/tests/test_batches.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: launchables
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Python client for the Launchables Decision API
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://www.launchables.ai/docs
@@ -66,7 +66,7 @@ resp.answers["urgency"].score # 1.92
66
66
  resp.answers["urgency"].probabilities # {"0": 0.03, "1": 0.12, ...}
67
67
  ```
68
68
 
69
- Helpers validate locally and raise `ValidationError` before any request is sent: at most 16 questions per request, at most 26 options per choice, non-empty instructions.
69
+ Helpers validate locally and raise `ValidationError` before any request is sent: at most 256 questions per request, at most 256 options per choice and 4,096 options over a request (the API's largest limits; Myles-G 31B takes 16 and 26 for now and answers 422 above them), non-empty instructions.
70
70
 
71
71
  ### Other calls
72
72
 
@@ -49,7 +49,7 @@ resp.answers["urgency"].score # 1.92
49
49
  resp.answers["urgency"].probabilities # {"0": 0.03, "1": 0.12, ...}
50
50
  ```
51
51
 
52
- Helpers validate locally and raise `ValidationError` before any request is sent: at most 16 questions per request, at most 26 options per choice, non-empty instructions.
52
+ Helpers validate locally and raise `ValidationError` before any request is sent: at most 256 questions per request, at most 256 options per choice and 4,096 options over a request (the API's largest limits; Myles-G 31B takes 16 and 26 for now and answers 422 above them), non-empty instructions.
53
53
 
54
54
  ### Other calls
55
55
 
@@ -0,0 +1 @@
1
+ __version__ = "0.6.0"
@@ -6,8 +6,9 @@ from typing import Any, Dict, Iterable, List, Mapping, Optional, Union
6
6
 
7
7
  from .errors import ValidationError
8
8
 
9
- MAX_QUESTIONS = 16
10
- MAX_OPTIONS = 26
9
+ MAX_QUESTIONS = 256 # the API's largest limits (Myles-G 12B since 24 Oct 2026); a model on lower limits answers 422
10
+ MAX_OPTIONS = 256
11
+ MAX_OPTIONS_TOTAL = 4096 # options over all questions in one request
11
12
  QUESTION_TYPES = ("noul", "choice", "score")
12
13
 
13
14
  Question = Dict[str, Any]
@@ -75,6 +76,7 @@ def validate_questions(questions: Any) -> Dict[str, Question]:
75
76
  if len(questions) > MAX_QUESTIONS:
76
77
  raise ValidationError(f"at most {MAX_QUESTIONS} questions per request, got {len(questions)}")
77
78
  out: Dict[str, Question] = {}
79
+ total = 0
78
80
  for name, q in questions.items():
79
81
  if not isinstance(name, str) or not name:
80
82
  raise ValidationError("question names must be non-empty strings")
@@ -93,6 +95,9 @@ def validate_questions(questions: Any) -> Dict[str, Question]:
93
95
  elif qtype == "score":
94
96
  if not isinstance(crit, (list, tuple)) or not crit:
95
97
  raise ValidationError(f"question {name!r}: score needs criteria (a list of level descriptions)")
98
+ total += len(crit) if isinstance(crit, (Mapping, list, tuple)) and qtype != "noul" else 2 # as the server counts
99
+ if total > MAX_OPTIONS_TOTAL:
100
+ raise ValidationError(f"at most {MAX_OPTIONS_TOTAL} options over all questions in one request")
96
101
  out[name] = dict(q)
97
102
  return out
98
103
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: launchables
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Python client for the Launchables Decision API
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://www.launchables.ai/docs
@@ -66,7 +66,7 @@ resp.answers["urgency"].score # 1.92
66
66
  resp.answers["urgency"].probabilities # {"0": 0.03, "1": 0.12, ...}
67
67
  ```
68
68
 
69
- Helpers validate locally and raise `ValidationError` before any request is sent: at most 16 questions per request, at most 26 options per choice, non-empty instructions.
69
+ Helpers validate locally and raise `ValidationError` before any request is sent: at most 256 questions per request, at most 256 options per choice and 4,096 options over a request (the API's largest limits; Myles-G 31B takes 16 and 26 for now and answers 422 above them), non-empty instructions.
70
70
 
71
71
  ### Other calls
72
72
 
@@ -345,9 +345,9 @@ class ValidationTests(Base):
345
345
  self.assertEqual(choice("x", ("a", "b"))["criteria"], ["a", "b"])
346
346
 
347
347
  def test_choice_limits(self):
348
- choice("x", [str(i) for i in range(26)])
349
- with self.assertRaisesRegex(ValidationError, "at most 26"):
350
- choice("x", [str(i) for i in range(27)])
348
+ choice("x", [str(i) for i in range(256)])
349
+ with self.assertRaisesRegex(ValidationError, "at most 256"):
350
+ choice("x", [str(i) for i in range(257)])
351
351
  with self.assertRaises(ValidationError):
352
352
  choice("x", [])
353
353
  with self.assertRaises(ValidationError):
@@ -366,10 +366,12 @@ class ValidationTests(Base):
366
366
  noul(" ")
367
367
 
368
368
  def test_too_many_questions(self):
369
- qs = {f"q{i}": noul("x") for i in range(17)}
370
- with self.assertRaisesRegex(ValidationError, "at most 16"):
369
+ qs = {f"q{i}": noul("x") for i in range(257)}
370
+ with self.assertRaisesRegex(ValidationError, "at most 256"):
371
371
  self.client.decide("s", qs)
372
- self.client.decide # 16 is fine (validated, not sent here)
372
+ wide = {f"q{i}": choice("x", [str(j) for j in range(250)]) for i in range(17)}
373
+ with self.assertRaisesRegex(ValidationError, "at most 4096 options"):
374
+ self.client.decide("s", wide)
373
375
  self.assertEqual(self.server.requests, [])
374
376
 
375
377
  def test_sixteen_ok(self):
@@ -1 +0,0 @@
1
- __version__ = "0.5.0"
File without changes
File without changes
File without changes