dreadnode 1.12.0__tar.gz → 1.12.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 (47) hide show
  1. {dreadnode-1.12.0 → dreadnode-1.12.2}/PKG-INFO +2 -2
  2. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/object.py +3 -0
  3. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/__init__.py +2 -0
  4. dreadnode-1.12.2/dreadnode/scorers/llm_judge.py +102 -0
  5. {dreadnode-1.12.0 → dreadnode-1.12.2}/pyproject.toml +3 -3
  6. {dreadnode-1.12.0 → dreadnode-1.12.2}/README.md +0 -0
  7. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/__init__.py +0 -0
  8. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/api/__init__.py +0 -0
  9. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/api/client.py +0 -0
  10. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/api/models.py +0 -0
  11. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/api/util.py +0 -0
  12. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/artifact/__init__.py +0 -0
  13. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/artifact/merger.py +0 -0
  14. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/artifact/storage.py +0 -0
  15. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/artifact/tree_builder.py +0 -0
  16. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/constants.py +0 -0
  17. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/convert.py +0 -0
  18. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/__init__.py +0 -0
  19. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/audio.py +0 -0
  20. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/base.py +0 -0
  21. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/image.py +0 -0
  22. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/object_3d.py +0 -0
  23. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/table.py +0 -0
  24. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/text.py +0 -0
  25. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/data_types/video.py +0 -0
  26. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/integrations/__init__.py +0 -0
  27. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/integrations/transformers.py +0 -0
  28. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/main.py +0 -0
  29. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/metric.py +0 -0
  30. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/py.typed +0 -0
  31. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/consistency.py +0 -0
  32. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/contains.py +0 -0
  33. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/length.py +0 -0
  34. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/pii.py +0 -0
  35. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/readability.py +0 -0
  36. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/rigging.py +0 -0
  37. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/sentiment.py +0 -0
  38. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/scorers/similarity.py +0 -0
  39. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/serialization.py +0 -0
  40. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/task.py +0 -0
  41. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/tracing/__init__.py +0 -0
  42. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/tracing/constants.py +0 -0
  43. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/tracing/exporters.py +0 -0
  44. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/tracing/span.py +0 -0
  45. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/types.py +0 -0
  46. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/util.py +0 -0
  47. {dreadnode-1.12.0 → dreadnode-1.12.2}/dreadnode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dreadnode
3
- Version: 1.12.0
3
+ Version: 1.12.2
4
4
  Summary: Dreadnode SDK
5
5
  Author: Nick Landers
6
6
  Author-email: monoxgas@gmail.com
@@ -22,7 +22,7 @@ Requires-Dist: pandas (>=2.2.3,<3.0.0)
22
22
  Requires-Dist: pillow (>=11.2.1,<12.0.0) ; extra == "multimodal"
23
23
  Requires-Dist: pydantic (>=2.9.2,<3.0.0)
24
24
  Requires-Dist: python-ulid (>=3.0.0,<4.0.0)
25
- Requires-Dist: rigging (>=3.1.1,<4.0.0)
25
+ Requires-Dist: rigging (>=3.2.1,<4.0.0)
26
26
  Requires-Dist: soundfile (>=0.13.1,<0.14.0) ; extra == "multimodal"
27
27
  Requires-Dist: transformers (>=4.41.0,<5.0.0) ; extra == "training"
28
28
  Project-URL: Repository, https://github.com/dreadnode/sdk
@@ -1,6 +1,7 @@
1
1
  import typing as t
2
2
  from dataclasses import dataclass
3
3
 
4
+ from litellm import ConfigDict
4
5
  from pydantic import BaseModel, Field
5
6
 
6
7
  from dreadnode.types import AnyDict
@@ -31,6 +32,8 @@ class ObjectUri(BaseModel):
31
32
 
32
33
 
33
34
  class ObjectVal(BaseModel):
35
+ model_config = ConfigDict(serialize_by_alias=True)
36
+
34
37
  hash: str
35
38
  schema_hash: str
36
39
  value_: t.Any = Field(alias="value")
@@ -7,6 +7,7 @@ from dreadnode.scorers.contains import (
7
7
  detect_unsafe_shell_content,
8
8
  )
9
9
  from dreadnode.scorers.length import length_in_range, length_ratio, length_target
10
+ from dreadnode.scorers.llm_judge import llm_judge
10
11
  from dreadnode.scorers.pii import detect_pii, detect_pii_with_presidio
11
12
  from dreadnode.scorers.readability import readability
12
13
  from dreadnode.scorers.rigging import wrap_chat
@@ -26,6 +27,7 @@ __all__ = [
26
27
  "length_in_range",
27
28
  "length_ratio",
28
29
  "length_target",
30
+ "llm_judge",
29
31
  "readability",
30
32
  "semantic_similarity",
31
33
  "sentiment",
@@ -0,0 +1,102 @@
1
+ import typing as t
2
+
3
+ from rigging import GenerateParams, get_generator
4
+ from rigging.generator import Generator
5
+ from rigging.model import Model, element
6
+ from rigging.prompt import prompt
7
+
8
+ from dreadnode.metric import Metric, Scorer
9
+ from dreadnode.task import TaskInput
10
+
11
+
12
+ class JudgeInput(Model):
13
+ input: str | None = element(default=None)
14
+ expected_output: str | None = element(default=None)
15
+ output: str = element()
16
+ rubric: str = element()
17
+
18
+
19
+ class Judgement(Model):
20
+ reason: str = element()
21
+ pass_: bool = element(alias="pass")
22
+ score: float = element()
23
+
24
+
25
+ @prompt()
26
+ def judge(input: JudgeInput) -> Judgement: # type: ignore [empty-body]
27
+ """
28
+ You are grading output according to a user-specified rubric. \
29
+ If the statement in the rubric is true for the provided input and output, then the output passes the test.
30
+ Assign a score based on the rubric, where applicable, otherwise 1.0 for passing and 0.0 for failing.
31
+ """
32
+
33
+
34
+ def llm_judge(
35
+ model: "str | Generator | TaskInput",
36
+ rubric: str | TaskInput,
37
+ *,
38
+ expected_output: str | TaskInput | None = None,
39
+ params: "GenerateParams | None" = None,
40
+ passing: t.Callable[[float], bool] | None = None,
41
+ min_score: float | None = None,
42
+ max_score: float | None = None,
43
+ name: str = "llm_judge",
44
+ ) -> "Scorer[t.Any]":
45
+ """
46
+ Score the output of a task using an LLM to judge it against a rubric.
47
+
48
+ Args:
49
+ model: The model to use for judging. Can be a string identifier (rigging), a Generator instance
50
+ or a TaskInput that resolves to a string identifier.
51
+ rubric: The rubric to use for judging. Can be a string or a TaskInput that resolves to a string.
52
+ expected_output: The expected output to compare against, if applicable. Can be a string or a TaskInput that resolves to a string.
53
+ params: Optional parameters for the generator.
54
+ passing: Optional callback to determine if the score is passing based on the score value - overrides any model-specified value.
55
+ min_score: Optional minimum score for the judgement - if provided, the score will be clamped to this value.
56
+ max_score: Optional maximum score for the judgement - if provided, the score will be clamped to this value.
57
+ name: The name of the scorer.
58
+ """
59
+
60
+ async def evaluate(data: t.Any) -> Metric:
61
+ _model = model.resolve() if isinstance(model, TaskInput) else model
62
+ _rubric = rubric.resolve(cast_as=str) if isinstance(rubric, TaskInput) else rubric
63
+ _expected_output = (
64
+ expected_output.resolve(cast_as=str)
65
+ if isinstance(expected_output, TaskInput)
66
+ else expected_output
67
+ )
68
+
69
+ generator: Generator
70
+ if isinstance(_model, str):
71
+ generator = get_generator(_model, params=params or GenerateParams())
72
+ elif isinstance(_model, Generator):
73
+ generator = _model
74
+ else:
75
+ raise TypeError("Model must be a string identifier or a Generator instance.")
76
+
77
+ input_data = JudgeInput(
78
+ input=str(data),
79
+ expected_output=_expected_output,
80
+ output=str(data),
81
+ rubric=_rubric,
82
+ )
83
+
84
+ judgement = await judge.bind(generator)(input_data)
85
+
86
+ if min_score is not None:
87
+ judgement.score = max(min_score, judgement.score)
88
+ if max_score is not None:
89
+ judgement.score = min(max_score, judgement.score)
90
+
91
+ if passing is not None:
92
+ judgement.pass_ = passing(judgement.score)
93
+
94
+ return Metric(
95
+ value=judgement.score,
96
+ attributes={
97
+ "reason": judgement.reason,
98
+ "pass": judgement.pass_,
99
+ },
100
+ )
101
+
102
+ return Scorer.from_callable(evaluate, name=name, catch=True)
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "dreadnode"
3
- version = "1.12.0"
3
+ version = "1.12.2"
4
4
  description = "Dreadnode SDK"
5
5
  requires-python = ">=3.10,<3.14"
6
6
 
7
7
  [tool.poetry]
8
8
  name = "dreadnode"
9
- version = "1.12.0"
9
+ version = "1.12.2"
10
10
  description = "Dreadnode SDK"
11
11
  authors = ["Nick Landers <monoxgas@gmail.com>"]
12
12
  repository = "https://github.com/dreadnode/sdk"
@@ -23,12 +23,12 @@ pandas = "^2.2.3"
23
23
  fsspec = { version = ">=2023.1.0,<=2025.3.0", extras = [
24
24
  "s3",
25
25
  ] } # Pinned for datasets compatibility
26
- rigging = "^3.1.1"
27
26
 
28
27
  transformers = { version = "^4.41.0", optional = true }
29
28
  soundfile = { version = "^0.13.1", optional = true }
30
29
  moviepy = { version = "^2.1.2", optional = true }
31
30
  pillow = { version = "^11.2.1", optional = true }
31
+ rigging = "^3.2.1"
32
32
 
33
33
  [tool.poetry.extras]
34
34
  training = ["transformers"]
File without changes
File without changes
File without changes
File without changes