bead 0.1.0__py3-none-any.whl
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.
- bead/__init__.py +11 -0
- bead/__main__.py +11 -0
- bead/active_learning/__init__.py +15 -0
- bead/active_learning/config.py +231 -0
- bead/active_learning/loop.py +566 -0
- bead/active_learning/models/__init__.py +24 -0
- bead/active_learning/models/base.py +852 -0
- bead/active_learning/models/binary.py +910 -0
- bead/active_learning/models/categorical.py +943 -0
- bead/active_learning/models/cloze.py +862 -0
- bead/active_learning/models/forced_choice.py +956 -0
- bead/active_learning/models/free_text.py +773 -0
- bead/active_learning/models/lora.py +365 -0
- bead/active_learning/models/magnitude.py +835 -0
- bead/active_learning/models/multi_select.py +795 -0
- bead/active_learning/models/ordinal_scale.py +811 -0
- bead/active_learning/models/peft_adapter.py +155 -0
- bead/active_learning/models/random_effects.py +639 -0
- bead/active_learning/selection.py +354 -0
- bead/active_learning/strategies.py +391 -0
- bead/active_learning/trainers/__init__.py +26 -0
- bead/active_learning/trainers/base.py +210 -0
- bead/active_learning/trainers/data_collator.py +172 -0
- bead/active_learning/trainers/dataset_utils.py +261 -0
- bead/active_learning/trainers/huggingface.py +304 -0
- bead/active_learning/trainers/lightning.py +324 -0
- bead/active_learning/trainers/metrics.py +424 -0
- bead/active_learning/trainers/mixed_effects.py +551 -0
- bead/active_learning/trainers/model_wrapper.py +509 -0
- bead/active_learning/trainers/registry.py +104 -0
- bead/adapters/__init__.py +11 -0
- bead/adapters/huggingface.py +61 -0
- bead/behavioral/__init__.py +116 -0
- bead/behavioral/analytics.py +646 -0
- bead/behavioral/extraction.py +343 -0
- bead/behavioral/merging.py +343 -0
- bead/cli/__init__.py +11 -0
- bead/cli/active_learning.py +513 -0
- bead/cli/active_learning_commands.py +779 -0
- bead/cli/completion.py +359 -0
- bead/cli/config.py +624 -0
- bead/cli/constraint_builders.py +286 -0
- bead/cli/deployment.py +859 -0
- bead/cli/deployment_trials.py +493 -0
- bead/cli/deployment_ui.py +332 -0
- bead/cli/display.py +378 -0
- bead/cli/items.py +960 -0
- bead/cli/items_factories.py +776 -0
- bead/cli/list_constraints.py +714 -0
- bead/cli/lists.py +490 -0
- bead/cli/main.py +430 -0
- bead/cli/models.py +877 -0
- bead/cli/resource_loaders.py +621 -0
- bead/cli/resources.py +1036 -0
- bead/cli/shell.py +356 -0
- bead/cli/simulate.py +840 -0
- bead/cli/templates.py +1158 -0
- bead/cli/training.py +1080 -0
- bead/cli/utils.py +614 -0
- bead/cli/workflow.py +1273 -0
- bead/config/__init__.py +68 -0
- bead/config/active_learning.py +1009 -0
- bead/config/config.py +192 -0
- bead/config/defaults.py +118 -0
- bead/config/deployment.py +217 -0
- bead/config/env.py +147 -0
- bead/config/item.py +45 -0
- bead/config/list.py +193 -0
- bead/config/loader.py +149 -0
- bead/config/logging.py +42 -0
- bead/config/model.py +49 -0
- bead/config/paths.py +46 -0
- bead/config/profiles.py +320 -0
- bead/config/resources.py +47 -0
- bead/config/serialization.py +210 -0
- bead/config/simulation.py +206 -0
- bead/config/template.py +238 -0
- bead/config/validation.py +267 -0
- bead/data/__init__.py +65 -0
- bead/data/base.py +87 -0
- bead/data/identifiers.py +97 -0
- bead/data/language_codes.py +61 -0
- bead/data/metadata.py +270 -0
- bead/data/range.py +123 -0
- bead/data/repository.py +358 -0
- bead/data/serialization.py +249 -0
- bead/data/timestamps.py +89 -0
- bead/data/validation.py +349 -0
- bead/data_collection/__init__.py +11 -0
- bead/data_collection/jatos.py +223 -0
- bead/data_collection/merger.py +154 -0
- bead/data_collection/prolific.py +198 -0
- bead/deployment/__init__.py +5 -0
- bead/deployment/distribution.py +402 -0
- bead/deployment/jatos/__init__.py +1 -0
- bead/deployment/jatos/api.py +200 -0
- bead/deployment/jatos/exporter.py +210 -0
- bead/deployment/jspsych/__init__.py +9 -0
- bead/deployment/jspsych/biome.json +44 -0
- bead/deployment/jspsych/config.py +411 -0
- bead/deployment/jspsych/generator.py +598 -0
- bead/deployment/jspsych/package.json +51 -0
- bead/deployment/jspsych/pnpm-lock.yaml +2141 -0
- bead/deployment/jspsych/randomizer.py +299 -0
- bead/deployment/jspsych/src/lib/list-distributor.test.ts +327 -0
- bead/deployment/jspsych/src/lib/list-distributor.ts +1282 -0
- bead/deployment/jspsych/src/lib/randomizer.test.ts +232 -0
- bead/deployment/jspsych/src/lib/randomizer.ts +367 -0
- bead/deployment/jspsych/src/plugins/cloze-dropdown.ts +252 -0
- bead/deployment/jspsych/src/plugins/forced-choice.ts +265 -0
- bead/deployment/jspsych/src/plugins/plugins.test.ts +141 -0
- bead/deployment/jspsych/src/plugins/rating.ts +248 -0
- bead/deployment/jspsych/src/slopit/index.ts +9 -0
- bead/deployment/jspsych/src/types/jatos.d.ts +256 -0
- bead/deployment/jspsych/src/types/jspsych.d.ts +228 -0
- bead/deployment/jspsych/templates/experiment.css +1 -0
- bead/deployment/jspsych/templates/experiment.js.template +289 -0
- bead/deployment/jspsych/templates/index.html +51 -0
- bead/deployment/jspsych/templates/randomizer.js +241 -0
- bead/deployment/jspsych/templates/randomizer.js.template +313 -0
- bead/deployment/jspsych/trials.py +723 -0
- bead/deployment/jspsych/tsconfig.json +23 -0
- bead/deployment/jspsych/tsup.config.ts +30 -0
- bead/deployment/jspsych/ui/__init__.py +1 -0
- bead/deployment/jspsych/ui/components.py +383 -0
- bead/deployment/jspsych/ui/styles.py +411 -0
- bead/dsl/__init__.py +80 -0
- bead/dsl/ast.py +168 -0
- bead/dsl/context.py +178 -0
- bead/dsl/errors.py +71 -0
- bead/dsl/evaluator.py +570 -0
- bead/dsl/grammar.lark +81 -0
- bead/dsl/parser.py +231 -0
- bead/dsl/stdlib.py +929 -0
- bead/evaluation/__init__.py +13 -0
- bead/evaluation/convergence.py +485 -0
- bead/evaluation/interannotator.py +398 -0
- bead/items/__init__.py +40 -0
- bead/items/adapters/__init__.py +70 -0
- bead/items/adapters/anthropic.py +224 -0
- bead/items/adapters/api_utils.py +167 -0
- bead/items/adapters/base.py +216 -0
- bead/items/adapters/google.py +259 -0
- bead/items/adapters/huggingface.py +1074 -0
- bead/items/adapters/openai.py +323 -0
- bead/items/adapters/registry.py +202 -0
- bead/items/adapters/sentence_transformers.py +224 -0
- bead/items/adapters/togetherai.py +309 -0
- bead/items/binary.py +515 -0
- bead/items/cache.py +558 -0
- bead/items/categorical.py +593 -0
- bead/items/cloze.py +757 -0
- bead/items/constructor.py +784 -0
- bead/items/forced_choice.py +413 -0
- bead/items/free_text.py +681 -0
- bead/items/generation.py +432 -0
- bead/items/item.py +396 -0
- bead/items/item_template.py +787 -0
- bead/items/magnitude.py +573 -0
- bead/items/multi_select.py +621 -0
- bead/items/ordinal_scale.py +569 -0
- bead/items/scoring.py +448 -0
- bead/items/validation.py +723 -0
- bead/lists/__init__.py +30 -0
- bead/lists/balancer.py +263 -0
- bead/lists/constraints.py +1067 -0
- bead/lists/experiment_list.py +286 -0
- bead/lists/list_collection.py +378 -0
- bead/lists/partitioner.py +1141 -0
- bead/lists/stratification.py +254 -0
- bead/participants/__init__.py +73 -0
- bead/participants/collection.py +699 -0
- bead/participants/merging.py +312 -0
- bead/participants/metadata_spec.py +491 -0
- bead/participants/models.py +276 -0
- bead/resources/__init__.py +29 -0
- bead/resources/adapters/__init__.py +19 -0
- bead/resources/adapters/base.py +104 -0
- bead/resources/adapters/cache.py +128 -0
- bead/resources/adapters/glazing.py +508 -0
- bead/resources/adapters/registry.py +117 -0
- bead/resources/adapters/unimorph.py +796 -0
- bead/resources/classification.py +856 -0
- bead/resources/constraint_builders.py +329 -0
- bead/resources/constraints.py +165 -0
- bead/resources/lexical_item.py +223 -0
- bead/resources/lexicon.py +744 -0
- bead/resources/loaders.py +209 -0
- bead/resources/template.py +441 -0
- bead/resources/template_collection.py +707 -0
- bead/resources/template_generation.py +349 -0
- bead/simulation/__init__.py +29 -0
- bead/simulation/annotators/__init__.py +15 -0
- bead/simulation/annotators/base.py +175 -0
- bead/simulation/annotators/distance_based.py +135 -0
- bead/simulation/annotators/lm_based.py +114 -0
- bead/simulation/annotators/oracle.py +182 -0
- bead/simulation/annotators/random.py +181 -0
- bead/simulation/dsl_extension/__init__.py +3 -0
- bead/simulation/noise_models/__init__.py +13 -0
- bead/simulation/noise_models/base.py +42 -0
- bead/simulation/noise_models/random_noise.py +82 -0
- bead/simulation/noise_models/systematic.py +132 -0
- bead/simulation/noise_models/temperature.py +86 -0
- bead/simulation/runner.py +144 -0
- bead/simulation/strategies/__init__.py +23 -0
- bead/simulation/strategies/base.py +123 -0
- bead/simulation/strategies/binary.py +103 -0
- bead/simulation/strategies/categorical.py +123 -0
- bead/simulation/strategies/cloze.py +224 -0
- bead/simulation/strategies/forced_choice.py +127 -0
- bead/simulation/strategies/free_text.py +105 -0
- bead/simulation/strategies/magnitude.py +116 -0
- bead/simulation/strategies/multi_select.py +129 -0
- bead/simulation/strategies/ordinal_scale.py +131 -0
- bead/templates/__init__.py +27 -0
- bead/templates/adapters/__init__.py +17 -0
- bead/templates/adapters/base.py +128 -0
- bead/templates/adapters/cache.py +178 -0
- bead/templates/adapters/huggingface.py +312 -0
- bead/templates/combinatorics.py +103 -0
- bead/templates/filler.py +605 -0
- bead/templates/renderers.py +177 -0
- bead/templates/resolver.py +178 -0
- bead/templates/strategies.py +1806 -0
- bead/templates/streaming.py +195 -0
- bead-0.1.0.dist-info/METADATA +212 -0
- bead-0.1.0.dist-info/RECORD +231 -0
- bead-0.1.0.dist-info/WHEEL +4 -0
- bead-0.1.0.dist-info/entry_points.txt +2 -0
- bead-0.1.0.dist-info/licenses/LICENSE +21 -0
bead/items/item.py
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
"""Data models for constructed experimental items."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from pydantic import Field, field_validator
|
|
8
|
+
|
|
9
|
+
from bead.data.base import BeadBaseModel
|
|
10
|
+
|
|
11
|
+
# Type aliases for JSON-serializable metadata values
|
|
12
|
+
type MetadataValue = (
|
|
13
|
+
str | int | float | bool | None | dict[str, MetadataValue] | list[MetadataValue]
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Factory functions for default values with explicit types
|
|
18
|
+
def _empty_uuid_list() -> list[UUID]:
|
|
19
|
+
"""Return empty UUID list."""
|
|
20
|
+
return []
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _empty_unfilled_slot_list() -> list[UnfilledSlot]:
|
|
24
|
+
"""Return empty UnfilledSlot list."""
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _empty_model_output_list() -> list[ModelOutput]:
|
|
29
|
+
"""Return empty ModelOutput list."""
|
|
30
|
+
return []
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _empty_item_list() -> list[Item]:
|
|
34
|
+
"""Return empty Item list."""
|
|
35
|
+
return []
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _empty_str_dict() -> dict[str, str]:
|
|
39
|
+
"""Return empty string-to-string dict."""
|
|
40
|
+
return {}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _empty_uuid_bool_dict() -> dict[UUID, bool]:
|
|
44
|
+
"""Return empty UUID-to-bool dict."""
|
|
45
|
+
return {}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _empty_metadata_dict() -> dict[str, MetadataValue]:
|
|
49
|
+
"""Return empty metadata dict."""
|
|
50
|
+
return {}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _empty_str_list() -> list[str]:
|
|
54
|
+
"""Return empty string list."""
|
|
55
|
+
return []
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class UnfilledSlot(BeadBaseModel):
|
|
59
|
+
"""An unfilled slot in a cloze task item.
|
|
60
|
+
|
|
61
|
+
Represents a slot in a partially filled template where the participant
|
|
62
|
+
must provide a response. The UI widget for collecting the response is
|
|
63
|
+
inferred from the slot's constraints at deployment time.
|
|
64
|
+
|
|
65
|
+
Attributes
|
|
66
|
+
----------
|
|
67
|
+
slot_name : str
|
|
68
|
+
Name of the unfilled template slot.
|
|
69
|
+
position : int
|
|
70
|
+
Token index position in the rendered text.
|
|
71
|
+
constraint_ids : list[UUID]
|
|
72
|
+
UUIDs of constraints that apply to this slot.
|
|
73
|
+
|
|
74
|
+
Examples
|
|
75
|
+
--------
|
|
76
|
+
>>> from uuid import UUID
|
|
77
|
+
>>> # Extensional constraint slot (will render as dropdown)
|
|
78
|
+
>>> UnfilledSlot(
|
|
79
|
+
... slot_name="determiner",
|
|
80
|
+
... position=0,
|
|
81
|
+
... constraint_ids=[UUID("12345678-1234-5678-1234-567812345678")]
|
|
82
|
+
... )
|
|
83
|
+
>>> # Unconstrained slot (will render as text input)
|
|
84
|
+
>>> UnfilledSlot(
|
|
85
|
+
... slot_name="adjective",
|
|
86
|
+
... position=2,
|
|
87
|
+
... constraint_ids=[]
|
|
88
|
+
... )
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
slot_name: str = Field(..., description="Template slot name")
|
|
92
|
+
position: int = Field(..., description="Token position in rendered text")
|
|
93
|
+
constraint_ids: list[UUID] = Field(
|
|
94
|
+
default_factory=_empty_uuid_list, description="Constraint UUIDs for this slot"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
@field_validator("slot_name")
|
|
98
|
+
@classmethod
|
|
99
|
+
def validate_slot_name(cls, v: str) -> str:
|
|
100
|
+
"""Validate slot name is not empty.
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
v : str
|
|
105
|
+
Slot name to validate.
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
str
|
|
110
|
+
Validated slot name.
|
|
111
|
+
|
|
112
|
+
Raises
|
|
113
|
+
------
|
|
114
|
+
ValueError
|
|
115
|
+
If slot name is empty or contains only whitespace.
|
|
116
|
+
"""
|
|
117
|
+
if not v or not v.strip():
|
|
118
|
+
raise ValueError("Slot name cannot be empty")
|
|
119
|
+
return v.strip()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ModelOutput(BeadBaseModel):
|
|
123
|
+
"""Output from a model computation.
|
|
124
|
+
|
|
125
|
+
Attributes
|
|
126
|
+
----------
|
|
127
|
+
model_name : str
|
|
128
|
+
Name/identifier of the model.
|
|
129
|
+
model_version : str
|
|
130
|
+
Version of the model.
|
|
131
|
+
operation : str
|
|
132
|
+
Operation performed (e.g., "log_probability", "nli", "embedding").
|
|
133
|
+
inputs : dict[str, MetadataValue]
|
|
134
|
+
Inputs to the model.
|
|
135
|
+
output : MetadataValue
|
|
136
|
+
Model output.
|
|
137
|
+
cache_key : str
|
|
138
|
+
Cache key for this computation.
|
|
139
|
+
computation_metadata : dict[str, MetadataValue]
|
|
140
|
+
Metadata about the computation (timestamp, device, etc.).
|
|
141
|
+
|
|
142
|
+
Examples
|
|
143
|
+
--------
|
|
144
|
+
>>> output = ModelOutput(
|
|
145
|
+
... model_name="gpt2",
|
|
146
|
+
... model_version="latest",
|
|
147
|
+
... operation="log_probability",
|
|
148
|
+
... inputs={"text": "The cat broke the vase"},
|
|
149
|
+
... output=-12.4,
|
|
150
|
+
... cache_key="abc123..."
|
|
151
|
+
... )
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
model_name: str = Field(..., description="Model identifier")
|
|
155
|
+
model_version: str = Field(..., description="Model version")
|
|
156
|
+
operation: str = Field(..., description="Operation type")
|
|
157
|
+
inputs: dict[str, MetadataValue] = Field(..., description="Model inputs")
|
|
158
|
+
output: MetadataValue = Field(..., description="Model output")
|
|
159
|
+
cache_key: str = Field(..., description="Cache key")
|
|
160
|
+
computation_metadata: dict[str, MetadataValue] = Field(
|
|
161
|
+
default_factory=_empty_metadata_dict, description="Computation metadata"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
@field_validator("model_name", "model_version", "operation", "cache_key")
|
|
165
|
+
@classmethod
|
|
166
|
+
def validate_non_empty_strings(cls, v: str) -> str:
|
|
167
|
+
"""Validate required string fields are not empty.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
v : str
|
|
172
|
+
String value to validate.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
str
|
|
177
|
+
Validated string.
|
|
178
|
+
|
|
179
|
+
Raises
|
|
180
|
+
------
|
|
181
|
+
ValueError
|
|
182
|
+
If string is empty or contains only whitespace.
|
|
183
|
+
"""
|
|
184
|
+
if not v or not v.strip():
|
|
185
|
+
raise ValueError("Field cannot be empty")
|
|
186
|
+
return v.strip()
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class Item(BeadBaseModel):
|
|
190
|
+
"""A constructed experimental item.
|
|
191
|
+
|
|
192
|
+
Items are discrete stimuli presented to participants or models
|
|
193
|
+
for judgment collection. They are constructed from item templates
|
|
194
|
+
and filled templates.
|
|
195
|
+
|
|
196
|
+
Attributes
|
|
197
|
+
----------
|
|
198
|
+
item_template_id : UUID
|
|
199
|
+
UUID of the item template this was constructed from.
|
|
200
|
+
filled_template_refs : list[UUID]
|
|
201
|
+
UUIDs of filled templates used in this item.
|
|
202
|
+
rendered_elements : dict[str, str]
|
|
203
|
+
Rendered text for each element (by element_name).
|
|
204
|
+
options : list[str]
|
|
205
|
+
Choice options for forced_choice/multi_select tasks. Each string
|
|
206
|
+
is one option text. Order matters (first option is displayed first).
|
|
207
|
+
unfilled_slots : list[UnfilledSlot]
|
|
208
|
+
Unfilled slots for cloze tasks (UI widgets inferred from constraints).
|
|
209
|
+
model_outputs : list[ModelOutput]
|
|
210
|
+
All model computations for this item.
|
|
211
|
+
constraint_satisfaction : dict[UUID, bool]
|
|
212
|
+
Constraint UUIDs mapped to satisfaction status.
|
|
213
|
+
item_metadata : dict[str, MetadataValue]
|
|
214
|
+
Additional metadata for this item.
|
|
215
|
+
|
|
216
|
+
Examples
|
|
217
|
+
--------
|
|
218
|
+
>>> # Simple item
|
|
219
|
+
>>> item = Item(
|
|
220
|
+
... item_template_id=UUID("..."),
|
|
221
|
+
... filled_template_refs=[UUID("...")],
|
|
222
|
+
... rendered_elements={"sentence": "The cat broke the vase"}
|
|
223
|
+
... )
|
|
224
|
+
>>> # Forced-choice item with options
|
|
225
|
+
>>> fc_item = Item(
|
|
226
|
+
... item_template_id=UUID("..."),
|
|
227
|
+
... options=["The cat sat on the mat.", "The cats sat on the mat."],
|
|
228
|
+
... item_metadata={"n_options": 2}
|
|
229
|
+
... )
|
|
230
|
+
>>> # Cloze item with unfilled slots
|
|
231
|
+
>>> cloze_item = Item(
|
|
232
|
+
... item_template_id=UUID("..."),
|
|
233
|
+
... rendered_elements={"sentence": "The ___ cat ___ the ___"},
|
|
234
|
+
... unfilled_slots=[
|
|
235
|
+
... UnfilledSlot(slot_name="determiner", position=0, constraint_ids=[...]),
|
|
236
|
+
... UnfilledSlot(slot_name="verb", position=2, constraint_ids=[...])
|
|
237
|
+
... ]
|
|
238
|
+
... )
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
item_template_id: UUID = Field(..., description="ItemTemplate ID")
|
|
242
|
+
filled_template_refs: list[UUID] = Field(
|
|
243
|
+
default_factory=_empty_uuid_list, description="Filled template UUIDs"
|
|
244
|
+
)
|
|
245
|
+
rendered_elements: dict[str, str] = Field(
|
|
246
|
+
default_factory=_empty_str_dict, description="Rendered element text"
|
|
247
|
+
)
|
|
248
|
+
options: list[str] = Field(
|
|
249
|
+
default_factory=_empty_str_list,
|
|
250
|
+
description="Choice options for forced_choice/multi_select tasks",
|
|
251
|
+
)
|
|
252
|
+
unfilled_slots: list[UnfilledSlot] = Field(
|
|
253
|
+
default_factory=_empty_unfilled_slot_list,
|
|
254
|
+
description="Unfilled slots for cloze tasks",
|
|
255
|
+
)
|
|
256
|
+
model_outputs: list[ModelOutput] = Field(
|
|
257
|
+
default_factory=_empty_model_output_list, description="Model computations"
|
|
258
|
+
)
|
|
259
|
+
constraint_satisfaction: dict[UUID, bool] = Field(
|
|
260
|
+
default_factory=_empty_uuid_bool_dict,
|
|
261
|
+
description="Constraint satisfaction status",
|
|
262
|
+
)
|
|
263
|
+
item_metadata: dict[str, MetadataValue] = Field(
|
|
264
|
+
default_factory=_empty_metadata_dict, description="Additional metadata"
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def get_model_output(
|
|
268
|
+
self,
|
|
269
|
+
model_name: str,
|
|
270
|
+
operation: str,
|
|
271
|
+
inputs: dict[str, MetadataValue] | None = None,
|
|
272
|
+
) -> ModelOutput | None:
|
|
273
|
+
"""Get a specific model output.
|
|
274
|
+
|
|
275
|
+
Parameters
|
|
276
|
+
----------
|
|
277
|
+
model_name : str
|
|
278
|
+
Name of the model.
|
|
279
|
+
operation : str
|
|
280
|
+
Operation type.
|
|
281
|
+
inputs : dict[str, MetadataValue] | None
|
|
282
|
+
Optional input filter.
|
|
283
|
+
|
|
284
|
+
Returns
|
|
285
|
+
-------
|
|
286
|
+
ModelOutput | None
|
|
287
|
+
The model output if found, None otherwise.
|
|
288
|
+
|
|
289
|
+
Examples
|
|
290
|
+
--------
|
|
291
|
+
>>> output = item.get_model_output("gpt2", "log_probability")
|
|
292
|
+
>>> if output:
|
|
293
|
+
... print(f"Log prob: {output.output}")
|
|
294
|
+
"""
|
|
295
|
+
for output in self.model_outputs:
|
|
296
|
+
if output.model_name == model_name and output.operation == operation:
|
|
297
|
+
if inputs is None or output.inputs == inputs:
|
|
298
|
+
return output
|
|
299
|
+
return None
|
|
300
|
+
|
|
301
|
+
def add_model_output(self, output: ModelOutput) -> None:
|
|
302
|
+
"""Add a model output to this item.
|
|
303
|
+
|
|
304
|
+
Parameters
|
|
305
|
+
----------
|
|
306
|
+
output : ModelOutput
|
|
307
|
+
Model output to add.
|
|
308
|
+
|
|
309
|
+
Examples
|
|
310
|
+
--------
|
|
311
|
+
>>> item.add_model_output(my_output)
|
|
312
|
+
>>> print(f"Item now has {len(item.model_outputs)} model outputs")
|
|
313
|
+
"""
|
|
314
|
+
self.model_outputs.append(output)
|
|
315
|
+
self.update_modified_time()
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
class ItemCollection(BeadBaseModel):
|
|
319
|
+
"""A collection of constructed items.
|
|
320
|
+
|
|
321
|
+
Attributes
|
|
322
|
+
----------
|
|
323
|
+
name : str
|
|
324
|
+
Name of this collection.
|
|
325
|
+
source_template_collection_id : UUID
|
|
326
|
+
UUID of the source item template collection.
|
|
327
|
+
source_filled_collection_id : UUID
|
|
328
|
+
UUID of the source filled template collection.
|
|
329
|
+
items : list[Item]
|
|
330
|
+
The constructed items.
|
|
331
|
+
construction_stats : dict[str, int]
|
|
332
|
+
Statistics about item construction.
|
|
333
|
+
|
|
334
|
+
Examples
|
|
335
|
+
--------
|
|
336
|
+
>>> collection = ItemCollection(
|
|
337
|
+
... name="acceptability_items",
|
|
338
|
+
... source_template_collection_id=UUID("..."),
|
|
339
|
+
... source_filled_collection_id=UUID("...")
|
|
340
|
+
... )
|
|
341
|
+
>>> collection.add_item(item)
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
name: str = Field(..., description="Collection name")
|
|
345
|
+
source_template_collection_id: UUID = Field(
|
|
346
|
+
..., description="Source template collection UUID"
|
|
347
|
+
)
|
|
348
|
+
source_filled_collection_id: UUID = Field(
|
|
349
|
+
..., description="Source filled collection UUID"
|
|
350
|
+
)
|
|
351
|
+
items: list[Item] = Field(
|
|
352
|
+
default_factory=_empty_item_list, description="Constructed items"
|
|
353
|
+
)
|
|
354
|
+
construction_stats: dict[str, int] = Field(
|
|
355
|
+
default_factory=dict, description="Construction statistics"
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
@field_validator("name")
|
|
359
|
+
@classmethod
|
|
360
|
+
def validate_name(cls, v: str) -> str:
|
|
361
|
+
"""Validate collection name is not empty.
|
|
362
|
+
|
|
363
|
+
Parameters
|
|
364
|
+
----------
|
|
365
|
+
v : str
|
|
366
|
+
Collection name to validate.
|
|
367
|
+
|
|
368
|
+
Returns
|
|
369
|
+
-------
|
|
370
|
+
str
|
|
371
|
+
Validated collection name.
|
|
372
|
+
|
|
373
|
+
Raises
|
|
374
|
+
------
|
|
375
|
+
ValueError
|
|
376
|
+
If name is empty or contains only whitespace.
|
|
377
|
+
"""
|
|
378
|
+
if not v or not v.strip():
|
|
379
|
+
raise ValueError("Collection name cannot be empty")
|
|
380
|
+
return v.strip()
|
|
381
|
+
|
|
382
|
+
def add_item(self, item: Item) -> None:
|
|
383
|
+
"""Add an item to the collection.
|
|
384
|
+
|
|
385
|
+
Parameters
|
|
386
|
+
----------
|
|
387
|
+
item : Item
|
|
388
|
+
Item to add.
|
|
389
|
+
|
|
390
|
+
Examples
|
|
391
|
+
--------
|
|
392
|
+
>>> collection.add_item(my_item)
|
|
393
|
+
>>> print(f"Collection now has {len(collection.items)} items")
|
|
394
|
+
"""
|
|
395
|
+
self.items.append(item)
|
|
396
|
+
self.update_modified_time()
|