verifiers 0.2.2.dev35__py3-none-any.whl → 0.2.2.dev37__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.
@@ -4,9 +4,12 @@ The static musl binary runs in Linux containers without additional runtime depen
4
4
  """
5
5
 
6
6
  import base64
7
+ import hashlib
8
+ import json
7
9
  import logging
8
10
  import re
9
11
  import shlex
12
+ from collections import Counter
10
13
 
11
14
  from verifiers.v1.clients import ModelContext
12
15
  from verifiers.v1.configs.harness import HarnessConfig
@@ -47,7 +50,7 @@ class CodexHarnessConfig(HarnessConfig):
47
50
 
48
51
  class CodexHarness(Harness[CodexHarnessConfig]):
49
52
  APPENDS_SYSTEM_PROMPT = False # TODO
50
- SUPPORTS_MCP = False # TODO
53
+ SUPPORTS_MCP = True
51
54
  SUPPORTS_RESUME = True
52
55
  SUPPORTS_SKILLS = True
53
56
 
@@ -128,7 +131,7 @@ class CodexHarness(Harness[CodexHarnessConfig]):
128
131
  argv = [
129
132
  CODEX_BIN,
130
133
  "exec",
131
- *self._config_args(ctx, endpoint),
134
+ *self._config_args(ctx, endpoint, mcp_urls),
132
135
  *image_args,
133
136
  "--",
134
137
  prompt,
@@ -196,7 +199,7 @@ class CodexHarness(Harness[CodexHarnessConfig]):
196
199
  "exec",
197
200
  "resume",
198
201
  "--last",
199
- *self._config_args(ctx, endpoint),
202
+ *self._config_args(ctx, endpoint, mcp_urls),
200
203
  "--",
201
204
  "\n\n".join(texts),
202
205
  ]
@@ -228,7 +231,12 @@ class CodexHarness(Harness[CodexHarnessConfig]):
228
231
  "CODEX_HOME": home,
229
232
  }
230
233
 
231
- def _config_args(self, ctx: ModelContext, endpoint: str) -> list[str]:
234
+ def _config_args(
235
+ self,
236
+ ctx: ModelContext,
237
+ endpoint: str,
238
+ mcp_urls: dict[str, str],
239
+ ) -> list[str]:
232
240
  # Values are Codex feature names such as `shell_tool`; Codex owns validation.
233
241
  # https://developers.openai.com/codex/config-reference#features
234
242
  tool_config = [
@@ -236,6 +244,49 @@ class CodexHarness(Harness[CodexHarnessConfig]):
236
244
  for tool in self.config.disabled_tools or []
237
245
  for arg in ("--disable", tool)
238
246
  ]
247
+ # Set the whole table so dots in quoted server IDs are not interpreted as
248
+ # `-c` path separators.
249
+ mcp_config = (
250
+ [
251
+ "-c",
252
+ "mcp_servers={"
253
+ + ",".join(
254
+ (
255
+ f"{json.dumps(name, ensure_ascii=False)}="
256
+ f"{{url={json.dumps(url, ensure_ascii=False)},required=true,"
257
+ "startup_timeout_sec=60.0,tool_timeout_sec=600.0}"
258
+ )
259
+ for name, url in mcp_urls.items()
260
+ )
261
+ + "}",
262
+ ]
263
+ if mcp_urls
264
+ else []
265
+ )
266
+
267
+ # Codex keeps raw server IDs for MCP calls but normalizes the namespaces
268
+ # exposed to the model. Mirror rust-v0.144.5's per-character replacement,
269
+ # optional prefix, collision hash, and possible 49-character truncation.
270
+ namespace_bases: dict[str, str] = {}
271
+ for name in mcp_urls:
272
+ namespace = re.sub(r"[^a-zA-Z0-9_]", "_", name) or "_"
273
+ namespace_bases[name] = (
274
+ namespace if namespace.startswith("mcp__") else f"mcp__{namespace}"
275
+ )
276
+ namespace_counts = Counter(namespace_bases.values())
277
+ direct_mcp_namespaces: list[str] = []
278
+ for name, namespace in namespace_bases.items():
279
+ if namespace_counts[namespace] > 1:
280
+ suffix = hashlib.sha1(f"{name}\0{name}\0".encode()).hexdigest()[:12]
281
+ namespace = (
282
+ f"{namespace[:-2]}_{suffix}__"
283
+ if namespace.endswith("__")
284
+ else f"{namespace}_{suffix}"
285
+ )
286
+ direct_mcp_namespaces.append(namespace)
287
+ if len(namespace) > 49:
288
+ direct_mcp_namespaces.append(namespace[:49])
289
+ direct_mcp_namespaces = list(dict.fromkeys(direct_mcp_namespaces))
239
290
  # `-c` values parse as TOML, falling back to a raw string (so the url / `responses`
240
291
  # come through literally); `requires_openai_auth=false` parses as a bool.
241
292
  return [
@@ -266,4 +317,16 @@ class CodexHarness(Harness[CodexHarnessConfig]):
266
317
  "-c",
267
318
  f"model_providers.{PROVIDER}.requires_openai_auth=false",
268
319
  *tool_config,
320
+ *mcp_config,
321
+ *(
322
+ [
323
+ "-c",
324
+ (
325
+ "features.code_mode.direct_only_tool_namespaces="
326
+ f"{json.dumps(direct_mcp_namespaces)}"
327
+ ),
328
+ ]
329
+ if direct_mcp_namespaces
330
+ else []
331
+ ),
269
332
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifiers
3
- Version: 0.2.2.dev35
3
+ Version: 0.2.2.dev37
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
@@ -256,7 +256,7 @@ verifiers/v1/harnesses/bash/program.py,sha256=c9XgZwlsDYAwrgLZ6CDbZefQ1W4EF-vjM-
256
256
  verifiers/v1/harnesses/claude_code/__init__.py,sha256=JkZQylMSA3o1fvBx_NM41y_umuahmOSqFjTrJ2hryTw,171
257
257
  verifiers/v1/harnesses/claude_code/harness.py,sha256=98k5T8d8nFQmxIU-ytkrkrrP6UNR5NxoGhVJRLVa-fI,4015
258
258
  verifiers/v1/harnesses/codex/__init__.py,sha256=ocyBvlpSO8c3pT6D1ebrQohoXYESQcCyPT5kN3j1-N4,132
259
- verifiers/v1/harnesses/codex/harness.py,sha256=m3WqlQF8aGa3XwZ_jWpVchmQuMNtfXyOZdo9P9xNqRs,10665
259
+ verifiers/v1/harnesses/codex/harness.py,sha256=OG1riQdVmZzVpHENsd0UzsIbdIAxDMHgRikmo73HL5M,13071
260
260
  verifiers/v1/harnesses/kimi_code/__init__.py,sha256=1BEotSfuzmVcE7UrxHeAREM5d7J20cGkonHuowlrzu4,161
261
261
  verifiers/v1/harnesses/kimi_code/harness.py,sha256=Pc2uiBsia-uQFuXvaLMFdblE6TS-p0E2cvB6ofRrHK0,4515
262
262
  verifiers/v1/harnesses/mini_swe_agent/__init__.py,sha256=1OBu2Y-XqL72-dGhFdgB6sr5uX_peEEXT9vEjPy1ovU,182
@@ -327,8 +327,8 @@ verifiers/v1/utils/logging.py,sha256=OcMHA6NsYux3oIzjPuI95rDWmFBHNcHDjZeNIhXTX-Y
327
327
  verifiers/v1/utils/memory.py,sha256=ZkIvGk6uITAH5sKon65LifKPbvZr8mJ__PVc23FZpOQ,1835
328
328
  verifiers/v1/utils/sampling.py,sha256=JczGzBn6s3wsIrSY2Hy3hE8m6NreNgsNzhSjDikQqX0,1037
329
329
  verifiers/v1/utils/version.py,sha256=-obEo_-l9-D8FLef4hYxncOe-uJpxrM1g2Hig_37Sgs,1607
330
- verifiers-0.2.2.dev35.dist-info/METADATA,sha256=C_9jwe-5-02Xq4rt1sM686TyE0ZTlQh7VFRi898xpbI,4540
331
- verifiers-0.2.2.dev35.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
332
- verifiers-0.2.2.dev35.dist-info/entry_points.txt,sha256=dF82JUYEFslR1AOW8LZfuBWeZeQoyX4wCRrduklg8-I,551
333
- verifiers-0.2.2.dev35.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
334
- verifiers-0.2.2.dev35.dist-info/RECORD,,
330
+ verifiers-0.2.2.dev37.dist-info/METADATA,sha256=UXHagxu-19jjKUKZ4hFZhSL4eOZoFV4kBwD-0MmsHOw,4540
331
+ verifiers-0.2.2.dev37.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
332
+ verifiers-0.2.2.dev37.dist-info/entry_points.txt,sha256=dF82JUYEFslR1AOW8LZfuBWeZeQoyX4wCRrduklg8-I,551
333
+ verifiers-0.2.2.dev37.dist-info/licenses/LICENSE,sha256=v0RrUsdV3IDoZhrRce297IXS3xMHNJ-_LdLpFAUWb9k,1072
334
+ verifiers-0.2.2.dev37.dist-info/RECORD,,