verifiers 0.3.2.dev157__py3-none-any.whl → 0.3.2.dev159__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.
verifiers/v1/__init__.py CHANGED
@@ -15,7 +15,6 @@ from verifiers.v1.clients import (
15
15
  )
16
16
  from verifiers.v1.configs.agent import AgentConfig
17
17
  from verifiers.v1.configs.cli.env import (
18
- merge_env_defaults,
19
18
  narrowed_env_annotation,
20
19
  resolve_env_field,
21
20
  )
@@ -153,6 +152,7 @@ from verifiers.v1.utils.decorators import (
153
152
  stop,
154
153
  tool,
155
154
  )
155
+ from verifiers.v1.utils.generic import merge_defaults
156
156
  from verifiers.v1.utils.git import (
157
157
  PATCH_CAP_BYTES as PATCH_CAP_BYTES,
158
158
  )
@@ -321,7 +321,7 @@ __all__ = [ # noqa: RUF022 - grouped by public API area
321
321
  "SharedEnvConfig",
322
322
  "ServeConfig",
323
323
  "resolve_env_field",
324
- "merge_env_defaults",
324
+ "merge_defaults",
325
325
  "narrowed_env_annotation",
326
326
  "SingleAgentEnvConfig",
327
327
  "AgentConfig",
@@ -1,5 +1,6 @@
1
1
  """Run-config plumbing around the `[env]` block: narrowing the `env` field of
2
- every config that owns one, and layering shared env defaults under it.
2
+ every config that owns one. `merge_defaults` (`utils/generic.py`) layers shared env
3
+ defaults under it.
3
4
 
4
5
  A run composes the blocks it needs — `[env]` (what runs, `configs/env.py`),
5
6
  `[serve]` (how it's hosted, `configs/serve.py`) — plus its own fields. Nothing here is a base class: the eval
@@ -10,11 +11,11 @@ single_agent_env_config)`. The `SerializeAsAny` is load-bearing: pydantic serial
10
11
  by declared type, so a plain `EnvConfig` silently drops a narrowed subclass's agents
11
12
  and knobs from `model_dump()` — the env-server wire's payload."""
12
13
 
13
- from pydantic import BaseModel, ValidationError
14
+ from pydantic import ValidationError
14
15
  from pydantic_config import BaseConfig
15
16
 
16
- from verifiers.v1.configs.env import EnvConfig, SharedEnvConfig
17
- from verifiers.v1.utils.generic import deep_merge, prefix_validation_error
17
+ from verifiers.v1.configs.env import EnvConfig
18
+ from verifiers.v1.utils.generic import prefix_validation_error
18
19
 
19
20
 
20
21
  def resolve_env_field(data: dict, narrowed: "type[EnvConfig] | None" = None) -> dict:
@@ -45,32 +46,6 @@ def resolve_env_field(data: dict, narrowed: "type[EnvConfig] | None" = None) ->
45
46
  return data
46
47
 
47
48
 
48
- def merge_env_defaults(defaults: SharedEnvConfig, env: dict | None) -> dict:
49
- """A raw `env` block over `defaults`, the knobs that several envs of one run share
50
- (e.g. the retries of every eval source). Only the fields set in `defaults` apply,
51
- and the env's own values win. A subtree whose `id`/`type` differs from the
52
- default's is the env's alone, so one plugin's knobs never leak into another's."""
53
- return deep_merge(_dump_set(defaults), env or {})
54
-
55
-
56
- def _dump_set(config: BaseModel) -> dict:
57
- """`config`'s set fields, including those set on a sub-config after construction
58
- (which leaves the parent's field unmarked). Each dumped sub-config keeps its
59
- `id`/`type` even at the default: `deep_merge` detects a plugin switch only when
60
- both sides name it."""
61
- dump = {}
62
- for name in type(config).model_fields:
63
- value = getattr(config, name)
64
- if isinstance(value, BaseModel):
65
- nested = _dump_set(value)
66
- if nested or name in config.model_fields_set:
67
- keys = [k for k in ("id", "type") if k in type(value).model_fields]
68
- dump[name] = {**{k: getattr(value, k) for k in keys}, **nested}
69
- elif name in config.model_fields_set:
70
- dump[name] = config.model_dump(include={name})[name]
71
- return dump
72
-
73
-
74
49
  def narrowed_env_annotation(cls) -> "type[EnvConfig] | None":
75
50
  """The env field's annotation when the CLI pre-narrowed it (`narrow_config`
76
51
  swaps in a concrete subclass). The base declaration reads as `EnvConfig` itself
@@ -69,7 +69,7 @@ class CompactionConfig(BaseConfig):
69
69
 
70
70
  class RLMHarnessConfig(HarnessConfig):
71
71
  version: str = Field(
72
- default="7b5c89b2a0055e6c1a993cdd0ba0384053835f14", min_length=1
72
+ default="f18f10800f86f13913e19ef930abe5fcde4aa90f", min_length=1
73
73
  )
74
74
  """Git ref (branch, tag, or commit) of nano-rlm to install. Must know every
75
75
  field this harness puts on the wire, i.e. be at least the default ref."""
@@ -2,7 +2,7 @@
2
2
 
3
3
  from typing import TypeVar, get_args, get_origin
4
4
 
5
- from pydantic import ValidationError
5
+ from pydantic import BaseModel, ValidationError
6
6
 
7
7
  T = TypeVar("T")
8
8
 
@@ -39,6 +39,58 @@ def deep_merge(base: dict, override: dict) -> dict:
39
39
  return merged
40
40
 
41
41
 
42
+ def merge_defaults(defaults: BaseModel, raw: dict | None) -> dict:
43
+ """Fill in a raw config block with the values that `defaults` sets, e.g. a
44
+ group's shared knobs under each member's own block.
45
+
46
+ - Only fields that were set on `defaults` are filled in; its plain defaults are not.
47
+ - Nested blocks are filled in key by key; a value already in `raw` is kept.
48
+ - If `raw` names a different `id`/`type` for a block (at any depth), that block is
49
+ taken from `raw` alone, so one plugin's fields never leak into another's.
50
+
51
+ For example, with `defaults` set to `algo = {type = "grpo", kl = 0.1}`:
52
+ `{}` becomes `{type = "grpo", kl = 0.1}`, `{kl = 0.5}` becomes
53
+ `{type = "grpo", kl = 0.5}`, and `{type = "max_rl"}` stays `{type = "max_rl"}`.
54
+ """
55
+ # `deep_merge` detects an `id`/`type` switch only on nested blocks, so wrap the
56
+ # block once to detect a switch of the block itself too.
57
+ identity = {
58
+ k: getattr(defaults, k)
59
+ for k in ("id", "type")
60
+ if k in type(defaults).model_fields
61
+ }
62
+ block = {**identity, **_dump_set(defaults)}
63
+ return deep_merge({"block": block}, {"block": raw or {}})["block"]
64
+
65
+
66
+ def _dump_set(config: BaseModel) -> dict:
67
+ """The fields set on `config`, including extra fields, as a nested dict. A
68
+ sub-config the parent did not set still counts when its own fields changed after
69
+ construction (pydantic then leaves the parent's field unmarked), but not when it
70
+ only matches the field's default, which may itself be built with arguments. A
71
+ dumped sub-config always includes its `id`/`type`, because `deep_merge` detects a
72
+ switch only when both sides name it."""
73
+ dump = {}
74
+ for name, field in type(config).model_fields.items():
75
+ value = getattr(config, name)
76
+ if isinstance(value, BaseModel):
77
+ nested = _dump_set(value)
78
+ if name not in config.model_fields_set:
79
+ default = field.get_default(
80
+ call_default_factory=True, validated_data=config.__dict__
81
+ )
82
+ if isinstance(default, BaseModel) and nested == _dump_set(default):
83
+ continue
84
+ if nested or name in config.model_fields_set:
85
+ keys = [k for k in ("id", "type") if k in type(value).model_fields]
86
+ dump[name] = {**{k: getattr(value, k) for k in keys}, **nested}
87
+ elif name in config.model_fields_set:
88
+ dump[name] = config.model_dump(include={name})[name]
89
+ # Extra fields of an `extra="allow"` model exist only because they were set.
90
+ dump.update(config.model_dump(include=set(config.model_extra or {})))
91
+ return dump
92
+
93
+
42
94
  def concrete_type(
43
95
  cls: type, bound: type[T], *, origin: type | None = None
44
96
  ) -> type[T] | None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.3.2.dev157
3
+ Version: 0.3.2.dev159
4
4
  Summary: Verifiers: Environments for LLM Reinforcement Learning
5
5
  Project-URL: Homepage, https://github.com/primeintellect-ai/verifiers
6
6
  Project-URL: Documentation, https://github.com/primeintellect-ai/verifiers
@@ -1,5 +1,5 @@
1
1
  verifiers/__init__.py,sha256=F5IVMw6mhGaPBMCw7QKk0la_r5mMwydP2hdTTdQucik,352
2
- verifiers/v1/__init__.py,sha256=6t2FsosAjmyfJz6qS8tDQ2gWCvQfyRzqk1mYwv5_-EQ,8738
2
+ verifiers/v1/__init__.py,sha256=_8pSA4XU7zR4V-8sRpnZjh-YkfAYx1a0pikJtoFKzIk,8764
3
3
  verifiers/v1/agent.py,sha256=yBCCBe5tVTeQ8OZDlVSZLw_IDvCmEQSnF3wQ1BZcT14,32342
4
4
  verifiers/v1/env.py,sha256=GqrVxxrvv-9WitXhD8Rre0tKQgnQWeD8mTM2gDHMVBs,18040
5
5
  verifiers/v1/episode.py,sha256=UPtA02aGWA-fY8cJKEuYCMtQVnPN1C0BSN13LggNT8U,5986
@@ -55,7 +55,7 @@ verifiers/v1/configs/task.py,sha256=57OnEGAa6jTiG12Lx_elREU02koYh8UkM0t0Vvxahys,
55
55
  verifiers/v1/configs/taskset.py,sha256=LLbKdV2LW0ZjB9-fsKErIVKjchOAPcDLWGLVjgXKG_0,935
56
56
  verifiers/v1/configs/cli/__init__.py,sha256=YMDUPdbRlDJ77dhj3QqzmyRhqNgUvuQdpj_bdBqzZPM,78
57
57
  verifiers/v1/configs/cli/debug.py,sha256=CcUZ9MEcv0iAL9w2BkTfnZg20yWJ-Vn8P30-e5tuCic,2741
58
- verifiers/v1/configs/cli/env.py,sha256=FcapEAtgeHzRuVaqk8BU36ZxmMOfdJ1XlioPbdwwspo,3990
58
+ verifiers/v1/configs/cli/env.py,sha256=qg2LNOasAU0yg3b0xqXpx3cIj4nHbHSlK3Ldc3NhiT4,2667
59
59
  verifiers/v1/configs/cli/eval.py,sha256=9Zw7mAUipMhoIcwRa_lgo5gII4rMmMEBAgzcPxPWPjw,6895
60
60
  verifiers/v1/configs/cli/init.py,sha256=JvIUOdhfZfNOXg2wm2i06jLLHpb97tNMzZqmcK_9wVw,916
61
61
  verifiers/v1/configs/cli/replay.py,sha256=vUCNs-9j1CXcAZhGozN1EaztcXK_dYVK3iN_fRmbSXw,2929
@@ -113,7 +113,7 @@ verifiers/v1/harnesses/pi/harness.py,sha256=ysKOLSRQnbPkMtwvuUoJU7Hd4uM4bDF1duD0
113
113
  verifiers/v1/harnesses/prime_agent/__init__.py,sha256=xfPC4RrlnyYWaf38tPAOZq4YL6M55lMpj5BoRLmaK8I,171
114
114
  verifiers/v1/harnesses/prime_agent/harness.py,sha256=Zs_f5H2hQgDzUS4zwArM5UxCYJI5Zo0ELmayn1oBkK0,10663
115
115
  verifiers/v1/harnesses/rlm/__init__.py,sha256=hwx51xTdEWzzYgMj-p4ETNcptoub3IPMDbEdJ4uB8Ns,122
116
- verifiers/v1/harnesses/rlm/harness.py,sha256=zA4VB23ibYnw5WZfhvZipxxm5Ift01pG-FaYzMtY3PI,13538
116
+ verifiers/v1/harnesses/rlm/harness.py,sha256=NFJ3u1xC06d9NwjnxFD8cCqIXoGjAIwhmJly-hXSvMA,13538
117
117
  verifiers/v1/harnesses/terminus_2/__init__.py,sha256=l1pwfg1HyVDEqT9efdnFWcXqaZwtKwe7TrplkyxZSA0,166
118
118
  verifiers/v1/harnesses/terminus_2/harness.py,sha256=cKQJluW01mkxEccTLFwSWsVMavyiwq_w-NA4Hb_JkGU,3052
119
119
  verifiers/v1/harnesses/terminus_2/program.py,sha256=X8MZdyItU3gbXGXnGOlJ9LWcUTnqIDaxlhkZvoRiqKY,2703
@@ -178,7 +178,7 @@ verifiers/v1/utils/artifacts.py,sha256=3QL2ELwqXuek9OLwF4hJdzZb_hwfVjjenw8VjepdL
178
178
  verifiers/v1/utils/compile.py,sha256=5pxy31wx2Q-3pQjOO5B9SH6OT-wwb8r4F1LAl6HMeQA,5835
179
179
  verifiers/v1/utils/decorators.py,sha256=vhoN6YoKb15-Fkqmc9RaNlUIbt9WRvNK4zAn2bAxfS4,5367
180
180
  verifiers/v1/utils/format.py,sha256=yX160sGewMMZn9iJqTHRbYYt4Z9pHasjMlFT1dXrKD8,2446
181
- verifiers/v1/utils/generic.py,sha256=2VIN9RapMO9pVkFHB1UKUHck1vlTJ1pjfad2NzxuuXA,2055
181
+ verifiers/v1/utils/generic.py,sha256=Iy_mgApIEBqm0DPpjBDLLkDFN0_NJ-UQmY9bZpdv5cM,4742
182
182
  verifiers/v1/utils/git.py,sha256=MTRinOvG4EddfjdahHkFZUihHmhJ37n5ROtgjzjE1NA,8366
183
183
  verifiers/v1/utils/image.py,sha256=OFw_wdwVtbdwa8uJ3X3vYfhpUAi0CTH5HMBupjVsRRQ,282
184
184
  verifiers/v1/utils/interrupt.py,sha256=F-KKhc5ndPJJfhd3SuMqyqhXhA32FhCRy5KWFJpEoM4,1179
@@ -193,8 +193,8 @@ verifiers/v1/utils/scope.py,sha256=bzUEiWDOVdbj7dXOwGOlzsQ_-Xu0j9NR5TalQB-8TS8,8
193
193
  verifiers/v1/utils/score.py,sha256=493yJVMw8teCu9JxapxMFPFzI0hNUqdo0Y2nGW4kckk,6200
194
194
  verifiers/v1/utils/trace_store.py,sha256=RsCDonGR-bs-tvEstcppiJm3jFmAdIiG83fA5KtCbAw,2801
195
195
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
196
- verifiers-0.3.2.dev157.dist-info/METADATA,sha256=S_JgAQryBAsnmV4JAI_Y7imKTAH7U_p-D6L1RIO25ig,4161
197
- verifiers-0.3.2.dev157.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
198
- verifiers-0.3.2.dev157.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
199
- verifiers-0.3.2.dev157.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
200
- verifiers-0.3.2.dev157.dist-info/RECORD,,
196
+ verifiers-0.3.2.dev159.dist-info/METADATA,sha256=T0FmSudGXNolQ9I6tpm8jvLx8NuiuUHcBk60c1MOKFI,4161
197
+ verifiers-0.3.2.dev159.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
198
+ verifiers-0.3.2.dev159.dist-info/entry_points.txt,sha256=iugElcdWPKbQM7uFF0lZ8iUpHsNr17-BwEAAjJWxV3U,259
199
+ verifiers-0.3.2.dev159.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
200
+ verifiers-0.3.2.dev159.dist-info/RECORD,,