verifiers 0.3.2.dev86__py3-none-any.whl → 0.3.2.dev88__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.
@@ -58,6 +58,7 @@ class ACPConfig:
58
58
  mcp_urls: dict[str, str] | None = None
59
59
  system_prompt: str | None = None
60
60
  session_meta: JsonObject | None = None
61
+ client_capabilities: JsonObject | None = None
61
62
 
62
63
 
63
64
  class ACPHarness(Harness[ConfigT]):
@@ -265,6 +266,7 @@ class ACPHarnessSession(HarnessSession):
265
266
  "mcp_urls": self.mcp_urls,
266
267
  "system_prompt": self.config.system_prompt or "",
267
268
  "session_meta": self.config.session_meta or {},
269
+ "client_capabilities": self.config.client_capabilities or {},
268
270
  }
269
271
  async with self._lock:
270
272
  if self._closed:
@@ -194,7 +194,9 @@ class ACPSession:
194
194
  self.connection = agent_process[0]
195
195
  initialized = await self.connection.initialize(
196
196
  protocol_version=PROTOCOL_VERSION,
197
- client_capabilities=ClientCapabilities(),
197
+ client_capabilities=ClientCapabilities.model_validate(
198
+ config["client_capabilities"]
199
+ ),
198
200
  )
199
201
  self.capabilities = initialized.agent_capabilities
200
202
  session = await self.connection.new_session(
@@ -6,7 +6,7 @@ import logging
6
6
  import re
7
7
  from collections import Counter
8
8
 
9
- from verifiers.v1.acp import ACPConfig, ACPHarness
9
+ from verifiers.v1.acp import ACPConfig, ACPHarness, ACPTurn
10
10
  from verifiers.v1.clients import ModelContext
11
11
  from verifiers.v1.configs.harness import HarnessConfig, PinnedVersion
12
12
  from verifiers.v1.harnesses.node import NODE_BIN_DIR, ensure_node
@@ -47,6 +47,16 @@ class CodexHarness(ACPHarness[CodexHarnessConfig]):
47
47
  SUPPORTS_MCP = True
48
48
  SUPPORTS_SKILLS = True
49
49
 
50
+ def acp_turn_result(self, trace: Trace, result: ACPTurn) -> None:
51
+ # codex-acp returns terminal failures in metadata with stop_reason=end_turn.
52
+ failure = (
53
+ result.response_metadata.get("jetbrains", {})
54
+ .get("air", {})
55
+ .get("sessionFailure")
56
+ )
57
+ if failure and failure["phase"] == "active":
58
+ raise RuntimeError(f"Codex {failure['category']}: {failure['safeMessage']}")
59
+
50
60
  async def setup(self, runtime: Runtime) -> None:
51
61
  await self.install_skills(runtime, SKILLS_DIR)
52
62
  await ensure_node(runtime)
@@ -101,6 +111,13 @@ class CodexHarness(ACPHarness[CodexHarnessConfig]):
101
111
  # Codex reads MCP servers from the config written by build_env().
102
112
  mcp_urls={},
103
113
  system_prompt=system_prompt,
114
+ client_capabilities={
115
+ "_meta": {
116
+ "jetbrains": {
117
+ "air": {"version": 1, "capabilities": ["sessionFailure"]}
118
+ }
119
+ }
120
+ },
104
121
  )
105
122
 
106
123
  async def cleanup(self, trace: Trace, runtime: Runtime) -> None:
@@ -131,15 +131,18 @@ def _capture_response(response: web.Response) -> ReplayResponse:
131
131
  data = bytes(body)
132
132
  else:
133
133
  raise TypeError("coalesced interception responses must have a byte body")
134
- return ReplayResponse(status=response.status, body=data)
134
+ return ReplayResponse(
135
+ status=response.status,
136
+ body=data,
137
+ content_type=response.headers["Content-Type"],
138
+ )
135
139
 
136
140
 
137
141
  def _replay_response(response: ReplayResponse) -> web.Response:
138
142
  return web.Response(
139
143
  body=response.body,
140
144
  status=response.status,
141
- content_type="application/json",
142
- charset="utf-8",
145
+ headers={"Content-Type": response.content_type},
143
146
  )
144
147
 
145
148
 
@@ -496,7 +499,10 @@ class InterceptionServer(Interception):
496
499
  body = json.loads(raw)
497
500
  body = dialect.apply_overrides(body, session.ctx.model, session.ctx.sampling)
498
501
  streaming = dialect.streaming(body)
499
- req_hash = await _request_digest(raw) if not streaming else b""
502
+ relay_streaming = streaming and not isinstance(
503
+ session.ctx.client, TrainClientConfig
504
+ )
505
+ req_hash = await _request_digest(raw) if not relay_streaming else b""
500
506
  # Keep `read()` for aiohttp's size guard, then release its cache and our local
501
507
  # alias after parsing so the wire body does not survive model inference.
502
508
  request._read_bytes = None
@@ -511,7 +517,7 @@ class InterceptionServer(Interception):
511
517
  session.trace.id,
512
518
  streaming,
513
519
  )
514
- # Graph atomicity under retries: one logical non-streaming call must commit at most
520
+ # Graph atomicity under retries: one logical buffered call must commit at most
515
521
  # one turn. An explicit key identifies that call directly; otherwise only the SDK's
516
522
  # retry marker activates body-digest replay, since an unmarked repeated body can be a
517
523
  # legitimate later turn.
@@ -521,14 +527,14 @@ class InterceptionServer(Interception):
521
527
  replay_key: str | None = None
522
528
  binding = (request.path, req_hash)
523
529
  if idempotency_key:
524
- if streaming and acp is None:
530
+ if relay_streaming and acp is None:
525
531
  return web.json_response(
526
532
  dialect.error_body(
527
533
  "Idempotency-Key is not supported for streaming requests"
528
534
  ),
529
535
  status=400,
530
536
  )
531
- if not streaming:
537
+ if not relay_streaming:
532
538
  replay_key = f"explicit:{idempotency_key}"
533
539
  # This key identifies the harness-to-interception hop. The server owns its
534
540
  # replay semantics, and the body has since been rewritten with rollout model
@@ -538,7 +544,7 @@ class InterceptionServer(Interception):
538
544
  for name, value in upstream_headers.items()
539
545
  if name.lower() != IDEMPOTENCY_KEY_HEADER.lower()
540
546
  }
541
- elif not streaming:
547
+ elif not relay_streaming:
542
548
  replay_key = f"retry:{request.path}:{req_hash.hex()}"
543
549
 
544
550
  if replay_key is not None:
@@ -652,7 +658,7 @@ class InterceptionServer(Interception):
652
658
  return self._fail(session, dialect, error)
653
659
 
654
660
  inspect_response = bool(session.response_interceptors or session.response_stops)
655
- if streaming and not isinstance(session.ctx.client, TrainClientConfig):
661
+ if relay_streaming:
656
662
  return await self._stream(
657
663
  request,
658
664
  session,
@@ -670,11 +676,12 @@ class InterceptionServer(Interception):
670
676
  if streaming:
671
677
  # Training generates a complete response with token metadata.
672
678
  # Commit it through the normal path, then frame it for SSE clients.
673
- return web.Response(
679
+ served = web.Response(
674
680
  body=b"".join(dialect.stream_events(response.raw or {})),
675
681
  content_type="text/event-stream",
676
682
  )
677
- served = _completion_response(response.raw)
683
+ else:
684
+ served = _completion_response(response.raw)
678
685
  if idempotent is not None:
679
686
  idempotent.response = _capture_response(served)
680
687
  idempotent.completed_at = time.monotonic()
verifiers/v1/session.py CHANGED
@@ -96,7 +96,7 @@ class RolloutLimits:
96
96
 
97
97
  @dataclass
98
98
  class IdempotentRequest:
99
- """One non-streaming model request shared by its original call and retries."""
99
+ """One buffered model request shared by its original call and retries."""
100
100
 
101
101
  binding: tuple[str, bytes]
102
102
  response: "ReplayResponse | None" = None
@@ -110,6 +110,7 @@ class ReplayResponse:
110
110
 
111
111
  status: int
112
112
  body: bytes
113
+ content_type: str
113
114
 
114
115
 
115
116
  @dataclass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.3.2.dev86
3
+ Version: 0.3.2.dev88
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
@@ -10,14 +10,14 @@ verifiers/v1/harness.py,sha256=Yx-XCIs1HAmqv1F-nhCTDBUwAx51xQWNWgFcWL1WRTM,13777
10
10
  verifiers/v1/judge.py,sha256=uqn-djkK2_7Q3kOjkDo6ipOvV_HOvuLa9y6AoDjRux8,9618
11
11
  verifiers/v1/rollout.py,sha256=SvMgs7YBNjiftp4vlGVBMEseUsJs1h7qrqAlxmWaNwY,23987
12
12
  verifiers/v1/semantic.py,sha256=VQ_buw6Ya6QtRoh_fiYI5Avs5RmIQCfWH0H0bQc4aoc,4704
13
- verifiers/v1/session.py,sha256=LAdP72ooTeLUv9GYRqg7b0csit1dmIeVca0cHOU0Q_Q,18865
13
+ verifiers/v1/session.py,sha256=uwDcF7IxT6wVrfdMC34rEs-nAYxfsf6qxZV2qUFx8qE,18882
14
14
  verifiers/v1/state.py,sha256=EckF2bWp-vV4b1jYJ9sLI5xrfGuI5spIgYYwW926toI,595
15
15
  verifiers/v1/task.py,sha256=9YhllEDgoHSz72-1fcYwBADl-rOzASnrSVimLheWmwI,12237
16
16
  verifiers/v1/taskset.py,sha256=fp2E0IEhL_Ybj9cegZwljfTmW27p_30zTWHFKw_kXE4,4374
17
17
  verifiers/v1/trace.py,sha256=dBrStZXoEhVIKtcUzG6lZN0SEAjATOqBZCrgbaPdIXw,30398
18
18
  verifiers/v1/types.py,sha256=PH1SxRWXOjPCgQD9aZgM18_bECvFSNQ25gkCbulmTKU,9857
19
- verifiers/v1/acp/__init__.py,sha256=sbJL7vTE_BEmw34wwgbNPuWuAmQ_gwELsK3wQbT08f4,12715
20
- verifiers/v1/acp/runner.py,sha256=gMXFmsVg2qD0Zhrx7kvC6Me2Z-wsfBamRIO0i45UW8g,11097
19
+ verifiers/v1/acp/__init__.py,sha256=N2J0WQsA1VjxCyyLdbQ3mY-M_kdgJucTSRhk4ObMc70,12839
20
+ verifiers/v1/acp/runner.py,sha256=vEYEkX3gEt1vVbYCYhlVq-5y7RIMecpspDwX2vUoXuI,11179
21
21
  verifiers/v1/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  verifiers/v1/cli/debug.py,sha256=x3bqOwwbwwfwQQpxHrZeKdxsW3ZVtUT9cAn_r4aOro4,11631
23
23
  verifiers/v1/cli/gepa.py,sha256=zyUbZ0ykTEq6c-YlPUSk0kqsbkzqR-mkeW4Cl0WGeJo,4180
@@ -92,7 +92,7 @@ verifiers/v1/harnesses/browser_use/program.py,sha256=5g5AnRS-brYSMmHcteLf8-XDLaT
92
92
  verifiers/v1/harnesses/claude_code/__init__.py,sha256=JkZQylMSA3o1fvBx_NM41y_umuahmOSqFjTrJ2hryTw,171
93
93
  verifiers/v1/harnesses/claude_code/harness.py,sha256=Racxbs1EAH3gRwSeUptAIa3kB-EUm_nreUnHMwRUHuE,4119
94
94
  verifiers/v1/harnesses/codex/__init__.py,sha256=ocyBvlpSO8c3pT6D1ebrQohoXYESQcCyPT5kN3j1-N4,132
95
- verifiers/v1/harnesses/codex/harness.py,sha256=trrOj9qMLkPWxnh-Iz87uGYuwEg97cwrt67PxHrayrk,6825
95
+ verifiers/v1/harnesses/codex/harness.py,sha256=S6WLiEpOmeGHbwCYHhQyNkXSVYFbwBbCvPgk2tAuDis,7516
96
96
  verifiers/v1/harnesses/hermes_agent/__init__.py,sha256=k84Y8UTTf1KOw5LGqPb2dk-hYFagPevDJBOF7qsR_vo,176
97
97
  verifiers/v1/harnesses/hermes_agent/harness.py,sha256=dSsE2VZ8jaM-U14QXO3J7P-U6NMpSuOz3DUMtDWpWk0,3622
98
98
  verifiers/v1/harnesses/hermes_agent/program.py,sha256=RaIYm6NFD8KLXERGXp6rOE4QrQjlcTnm1Fu33xYsiHw,570
@@ -125,7 +125,7 @@ verifiers/v1/harnesses/utils/mcp.py,sha256=oNhKfLjAW-wScJcDIsW_HfuvKY-JkaGBBZrRL
125
125
  verifiers/v1/interception/__init__.py,sha256=5Kvo7tcBUVaa65s9A1NiOH3CPpzw-P5btXwxB4Nbbvs,4251
126
126
  verifiers/v1/interception/base.py,sha256=Mg16Y104lyZilF9shdivdqYoqz4OYp978i_myyrulu8,2529
127
127
  verifiers/v1/interception/pool.py,sha256=sk_zcdTV8EVRuzqlYMXxon_42tSDAlFvwcyOO2EF7hw,6473
128
- verifiers/v1/interception/server.py,sha256=QfFFXdz4dHpmZE_zT0aq8QLPc7Yp71VPsxcTiTlKbh4,52743
128
+ verifiers/v1/interception/server.py,sha256=P-gGTVHP0KyjNfFO2ikQ-_Rnp6x0yhelhEnY4g7jOIo,52919
129
129
  verifiers/v1/interception/tool.py,sha256=ZyZPxLYM_HsGkz-ZbCREQVGtiKZK9lQLChBNF_bBuuc,259
130
130
  verifiers/v1/interception/tunnel/__init__.py,sha256=eVNZJszj6myrKhx9jmJz7VRd9qlfj0AUvUZwI2bXEj8,893
131
131
  verifiers/v1/interception/tunnel/base.py,sha256=DZB6uPLwM4Qy7n7m0vKeyg-Px87MhsmpYTpe2vpPEng,1998
@@ -190,8 +190,8 @@ verifiers/v1/utils/prime.py,sha256=UTYRjp9cbjNb6CVmBHda-1wWZAIIfxNOmTyNuT7_wL4,9
190
190
  verifiers/v1/utils/retries.py,sha256=Y2ZgrAjn-qNkRKZP_RVNL_7EK0iaRcZeCa404lpGYi4,5417
191
191
  verifiers/v1/utils/score.py,sha256=493yJVMw8teCu9JxapxMFPFzI0hNUqdo0Y2nGW4kckk,6200
192
192
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
193
- verifiers-0.3.2.dev86.dist-info/METADATA,sha256=i9hBXB2HvhzvQXVBjoRSMVF5EI6ka74q3mj81S8wOJs,4237
194
- verifiers-0.3.2.dev86.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
195
- verifiers-0.3.2.dev86.dist-info/entry_points.txt,sha256=uqQje0TMsr7k6nXlWxlPs13Si0evb3pVCEDF6c-YL80,241
196
- verifiers-0.3.2.dev86.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
197
- verifiers-0.3.2.dev86.dist-info/RECORD,,
193
+ verifiers-0.3.2.dev88.dist-info/METADATA,sha256=byIq72DL9noEFv_E1iYum40wY1yX-fgG1zNV6pxkh1c,4237
194
+ verifiers-0.3.2.dev88.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
195
+ verifiers-0.3.2.dev88.dist-info/entry_points.txt,sha256=uqQje0TMsr7k6nXlWxlPs13Si0evb3pVCEDF6c-YL80,241
196
+ verifiers-0.3.2.dev88.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
197
+ verifiers-0.3.2.dev88.dist-info/RECORD,,