verifiers 0.3.2.dev119__tar.gz → 0.3.2.dev121__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 (219) hide show
  1. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/PKG-INFO +1 -1
  2. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/dialects/anthropic.py +35 -17
  3. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/dialects/base.py +50 -20
  4. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/dialects/chat.py +9 -3
  5. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/dialects/responses.py +41 -18
  6. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/rlm/harness.py +6 -1
  7. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/server.py +2 -1
  8. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/.gitignore +0 -0
  9. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/LICENSE +0 -0
  10. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/README.md +0 -0
  11. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/pyproject.toml +0 -0
  12. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/conftest.py +0 -0
  13. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  14. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/duet_v1.py +0 -0
  15. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
  16. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  17. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  18. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  19. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/echo_v1.py +0 -0
  20. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/pyproject.toml +0 -0
  21. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  22. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_color_codeword_tasks.py +0 -0
  23. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_configs.py +0 -0
  24. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_e2e.py +0 -0
  25. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_envs.py +0 -0
  26. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_graph.py +0 -0
  27. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_judges.py +0 -0
  28. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_platform_run.py +0 -0
  29. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_scoring.py +0 -0
  30. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_serve_delta.py +0 -0
  31. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_taskset.py +0 -0
  32. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/tests/v1/test_trace.py +0 -0
  33. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/__init__.py +0 -0
  34. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/__init__.py +0 -0
  35. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/acp/__init__.py +0 -0
  36. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/acp/runner.py +0 -0
  37. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/agent.py +0 -0
  38. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/__init__.py +0 -0
  39. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  40. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/dashboard/base.py +0 -0
  41. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/dashboard/eval.py +0 -0
  42. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/dashboard/replay.py +0 -0
  43. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/dashboard/validate.py +0 -0
  44. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/debug.py +0 -0
  45. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/eval/__init__.py +0 -0
  46. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/eval/hint.py +0 -0
  47. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/eval/main.py +0 -0
  48. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/eval/resume.py +0 -0
  49. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/eval/runner.py +0 -0
  50. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/gepa.py +0 -0
  51. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/init.py +0 -0
  52. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/output.py +0 -0
  53. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/replay.py +0 -0
  54. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/resolve.py +0 -0
  55. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/resume.py +0 -0
  56. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/cli/validate.py +0 -0
  57. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/clients/__init__.py +0 -0
  58. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/clients/base.py +0 -0
  59. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/clients/client.py +0 -0
  60. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/clients/eval.py +0 -0
  61. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/clients/train.py +0 -0
  62. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/__init__.py +0 -0
  63. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/agent.py +0 -0
  64. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/__init__.py +0 -0
  65. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/debug.py +0 -0
  66. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/env.py +0 -0
  67. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/eval.py +0 -0
  68. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/init.py +0 -0
  69. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/replay.py +0 -0
  70. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/cli/validate.py +0 -0
  71. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/client.py +0 -0
  72. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/env.py +0 -0
  73. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/harness.py +0 -0
  74. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/judge.py +0 -0
  75. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/retries.py +0 -0
  76. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/runtime.py +0 -0
  77. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/serve.py +0 -0
  78. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/task.py +0 -0
  79. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/configs/taskset.py +0 -0
  80. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/dialects/__init__.py +0 -0
  81. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/env.py +0 -0
  82. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/__init__.py +0 -0
  83. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  84. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  85. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  86. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/best_of_n/env.py +0 -0
  87. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/isolated_verifier/__init__.py +0 -0
  88. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/isolated_verifier/env.py +0 -0
  89. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/shared_agentic_judge/__init__.py +0 -0
  90. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  91. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/single_agent/env.py +0 -0
  92. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  93. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/envs/user_sim/env.py +0 -0
  94. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/episode.py +0 -0
  95. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/errors.py +0 -0
  96. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/gepa/__init__.py +0 -0
  97. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/gepa/adapter.py +0 -0
  98. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/gepa/config.py +0 -0
  99. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/gepa/dataset.py +0 -0
  100. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/gepa/reflection.py +0 -0
  101. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/gepa/runner.py +0 -0
  102. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/graph.py +0 -0
  103. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harness.py +0 -0
  104. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/__init__.py +0 -0
  105. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  106. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/bash/harness.py +0 -0
  107. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
  108. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
  109. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/browser_use/program.py +0 -0
  110. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  111. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
  112. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  113. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/codex/harness.py +0 -0
  114. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
  115. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
  116. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
  117. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  118. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  119. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  120. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  121. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  122. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/node.py +0 -0
  123. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/null/__init__.py +0 -0
  124. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/null/harness.py +0 -0
  125. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
  126. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/openclaw/harness.py +0 -0
  127. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  128. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/pi/harness.py +0 -0
  129. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
  130. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/prime_agent/harness.py +0 -0
  131. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  132. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  133. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  134. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  135. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/utils/__init__.py +0 -0
  136. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/utils/compaction.py +0 -0
  137. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/utils/core.py +0 -0
  138. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/utils/install.py +0 -0
  139. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/utils/launch.py +0 -0
  140. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/harnesses/utils/mcp.py +0 -0
  141. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/__init__.py +0 -0
  142. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/base.py +0 -0
  143. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/pool.py +0 -0
  144. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/tool.py +0 -0
  145. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  146. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/tunnel/base.py +0 -0
  147. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/tunnel/custom.py +0 -0
  148. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/interception/tunnel/prime.py +0 -0
  149. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/judge.py +0 -0
  150. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/judges/__init__.py +0 -0
  151. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/judges/reference.py +0 -0
  152. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/judges/reference.txt +0 -0
  153. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/judges/rubric.py +0 -0
  154. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/judges/rubric.txt +0 -0
  155. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/mcp/__init__.py +0 -0
  156. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/mcp/launch.py +0 -0
  157. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/mcp/server.py +0 -0
  158. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/mcp/toolset.py +0 -0
  159. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/rollout.py +0 -0
  160. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/__init__.py +0 -0
  161. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/apptainer.py +0 -0
  162. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/base.py +0 -0
  163. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/container.py +0 -0
  164. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/docker/__init__.py +0 -0
  165. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/docker/egress.py +0 -0
  166. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/limiters.py +0 -0
  167. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/modal.py +0 -0
  168. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/prime.py +0 -0
  169. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/runtimes/subprocess.py +0 -0
  170. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/semantic.py +0 -0
  171. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/__init__.py +0 -0
  172. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/client.py +0 -0
  173. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/delta.py +0 -0
  174. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/encoding.py +0 -0
  175. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/pool.py +0 -0
  176. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/server.py +0 -0
  177. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/serve/types.py +0 -0
  178. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/session.py +0 -0
  179. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/state.py +0 -0
  180. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/task.py +0 -0
  181. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/taskset.py +0 -0
  182. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/__init__.py +0 -0
  183. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  184. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/harbor/env.py +0 -0
  185. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  186. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
  187. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/lean/__init__.py +0 -0
  188. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/lean/scoring.py +0 -0
  189. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/lean/taskset.py +0 -0
  190. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
  191. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
  192. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
  193. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
  194. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
  195. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  196. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  197. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  198. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  199. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/trace.py +0 -0
  200. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/types.py +0 -0
  201. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/__init__.py +0 -0
  202. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/aio.py +0 -0
  203. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/artifacts.py +0 -0
  204. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/compile.py +0 -0
  205. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/decorators.py +0 -0
  206. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/format.py +0 -0
  207. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/generic.py +0 -0
  208. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/git.py +0 -0
  209. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/image.py +0 -0
  210. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/interrupt.py +0 -0
  211. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/loaders.py +0 -0
  212. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/logging.py +0 -0
  213. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/memory.py +0 -0
  214. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/paths.py +0 -0
  215. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/platform.py +0 -0
  216. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/prime.py +0 -0
  217. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/retries.py +0 -0
  218. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/score.py +0 -0
  219. {verifiers-0.3.2.dev119 → verifiers-0.3.2.dev121}/verifiers/v1/utils/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.3.2.dev119
3
+ Version: 0.3.2.dev121
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
@@ -22,7 +22,7 @@ from verifiers.v1.dialects.base import (
22
22
  append_user_notice,
23
23
  blocked_url,
24
24
  parse_sse_event,
25
- provider_allowed_domains,
25
+ provider_domains,
26
26
  )
27
27
  from verifiers.v1.types import (
28
28
  AssistantMessage,
@@ -128,10 +128,14 @@ def parse_content(content) -> str | list[ContentPart]:
128
128
  return parts
129
129
 
130
130
 
131
- def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str | None:
131
+ def blocked_content_path(
132
+ value, path: str, policy: NetworkPolicyConfig, blocked_urls: list[str]
133
+ ) -> str | None:
132
134
  if isinstance(value, list):
133
135
  for index, item in enumerate(value):
134
- if blocked := blocked_content_path(item, f"{path}[{index}]", policy):
136
+ if blocked := blocked_content_path(
137
+ item, f"{path}[{index}]", policy, blocked_urls
138
+ ):
135
139
  return blocked
136
140
  return None
137
141
  if not isinstance(value, dict):
@@ -151,11 +155,11 @@ def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str |
151
155
  source_kind = source.get("type")
152
156
  if source_kind == "content":
153
157
  return blocked_content_path(
154
- source.get("content"), f"{source_path}.content", policy
158
+ source.get("content"), f"{source_path}.content", policy, blocked_urls
155
159
  )
156
160
  if source_kind == "url":
157
161
  url = source.get("url")
158
- if not isinstance(url, str) or blocked_url(url, policy):
162
+ if not isinstance(url, str) or blocked_url(url, policy, blocked_urls):
159
163
  return f"{source_path}.url"
160
164
  if source_kind == "file":
161
165
  return (
@@ -173,13 +177,17 @@ def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str |
173
177
  ) and value.get("file_id"):
174
178
  return f"{path}.file_id"
175
179
  if kind in _CONTENT_WRAPPERS:
176
- return blocked_content_path(value.get("content"), f"{path}.content", policy)
180
+ return blocked_content_path(
181
+ value.get("content"), f"{path}.content", policy, blocked_urls
182
+ )
177
183
  return None if kind in _SAFE_CONTENT_TYPES else f"{path}.type"
178
184
 
179
185
 
180
- def mediate_content(value, path: str, policy: NetworkPolicyConfig):
186
+ def mediate_content(
187
+ value, path: str, policy: NetworkPolicyConfig, blocked_urls: list[str]
188
+ ):
181
189
  if not isinstance(value, list):
182
- blocked = blocked_content_path(value, path, policy)
190
+ blocked = blocked_content_path(value, path, policy, blocked_urls)
183
191
  return ("", [blocked]) if blocked else (value, [])
184
192
 
185
193
  mediated = []
@@ -188,17 +196,17 @@ def mediate_content(value, path: str, policy: NetworkPolicyConfig):
188
196
  item_path = f"{path}[{index}]"
189
197
  if isinstance(block, dict) and block.get("type") in _CONTENT_WRAPPERS:
190
198
  if blocked := blocked_content_path(
191
- {**block, "content": []}, item_path, policy
199
+ {**block, "content": []}, item_path, policy, blocked_urls
192
200
  ):
193
201
  capabilities.append(blocked)
194
202
  continue
195
203
  content, removed = mediate_content(
196
- block.get("content"), f"{item_path}.content", policy
204
+ block.get("content"), f"{item_path}.content", policy, blocked_urls
197
205
  )
198
206
  if removed:
199
207
  block["content"] = content or ""
200
208
  capabilities.extend(removed)
201
- elif blocked := blocked_content_path(block, item_path, policy):
209
+ elif blocked := blocked_content_path(block, item_path, policy, blocked_urls):
202
210
  capabilities.append(blocked)
203
211
  continue
204
212
  mediated.append(block)
@@ -451,12 +459,15 @@ class AnthropicDialect(Dialect[AnthropicMessage]):
451
459
  ) -> tuple[RawRequest, list[str]]:
452
460
  mediated = body
453
461
  capabilities: list[str] = []
462
+ blocked_urls: list[str] = []
454
463
 
455
464
  for key in ("container", "mcp_servers"):
456
465
  if mediated.pop(key, None):
457
466
  capabilities.append(key)
458
467
 
459
- system, removed = mediate_content(mediated.get("system"), "system", policy)
468
+ system, removed = mediate_content(
469
+ mediated.get("system"), "system", policy, blocked_urls
470
+ )
460
471
  capabilities.extend(removed)
461
472
  if removed:
462
473
  if system:
@@ -471,6 +482,7 @@ class AnthropicDialect(Dialect[AnthropicMessage]):
471
482
  message.get("content"),
472
483
  f"messages[{message_index}].content",
473
484
  policy,
485
+ blocked_urls,
474
486
  )
475
487
  capabilities.extend(removed)
476
488
  if removed:
@@ -489,9 +501,12 @@ class AnthropicDialect(Dialect[AnthropicMessage]):
489
501
  and _WEB_TOOL_TYPE(kind)
490
502
  ):
491
503
  callers = tool.get("allowed_callers")
504
+ filter_key = "blocked_domains" if policy.block else "allowed_domains"
505
+ other_key = "allowed_domains" if policy.block else "blocked_domains"
492
506
  domains = (
493
- provider_allowed_domains(policy, tool.get("allowed_domains"))
494
- if tool.get("blocked_domains") in (None, [])
507
+ provider_domains(policy, tool.get(filter_key))
508
+ # Anthropic does not support combining allow and block filters.
509
+ if tool.get(other_key) in (None, [])
495
510
  and (
496
511
  callers is None
497
512
  or isinstance(callers, list)
@@ -502,10 +517,10 @@ class AnthropicDialect(Dialect[AnthropicMessage]):
502
517
  if domains:
503
518
  web_tool = {
504
519
  **tool,
505
- "allowed_domains": domains,
520
+ filter_key: domains,
506
521
  "allowed_callers": ["direct"],
507
522
  }
508
- web_tool.pop("blocked_domains", None)
523
+ web_tool.pop(other_key, None)
509
524
  tools.append(web_tool)
510
525
  continue
511
526
  capabilities.append(f"tools[{index}].type")
@@ -539,7 +554,10 @@ class AnthropicDialect(Dialect[AnthropicMessage]):
539
554
  )
540
555
  mediated.pop("tool_choice", None)
541
556
 
542
- append_user_notice(mediated.setdefault("messages", []))
557
+ if capabilities:
558
+ append_user_notice(
559
+ mediated.setdefault("messages", []), blocked_urls=blocked_urls
560
+ )
543
561
  return mediated, capabilities
544
562
 
545
563
  def is_terminal_event(self, chunk: bytes) -> bool:
@@ -31,13 +31,14 @@ logger = logging.getLogger(__name__)
31
31
 
32
32
  PROVIDER_CAPABILITY_POLICY_CODE = "provider_capability_unavailable"
33
33
  CAPABILITY_NOTICE = (
34
- "Network protocol blocked fetching a resource. Continue without those capabilities; "
35
- "use local tools or inline data already present in the conversation, and do not retry "
36
- "the blocked provider-side operation."
34
+ "Some request content or provider-side capabilities were omitted because they are "
35
+ "blocked by the network policy or cannot enforce it."
37
36
  )
38
37
 
39
38
 
40
- def blocked_url(value: str, policy: NetworkPolicyConfig) -> bool:
39
+ def blocked_url(
40
+ value: str, policy: NetworkPolicyConfig, blocked_urls: list[str] | None = None
41
+ ) -> bool:
41
42
  """Whether a provider-resolved resource is neither inline nor policy-permitted."""
42
43
  if value.lower().startswith("data:"):
43
44
  return False
@@ -46,17 +47,26 @@ def blocked_url(value: str, policy: NetworkPolicyConfig) -> bool:
46
47
  except ValidationError:
47
48
  return True
48
49
  host = url.host.lower().rstrip(".").strip("[]")
49
- return not policy.permits(url.scheme, host, url.port)
50
+ blocked = not policy.permits(url.scheme, host, url.port)
51
+ if blocked and blocked_urls is not None:
52
+ blocked_urls.append(value)
53
+ return blocked
50
54
 
51
55
 
52
- def provider_allowed_domains(
56
+ def provider_domains(
53
57
  policy: NetworkPolicyConfig, requested: object = None
54
58
  ) -> list[str]:
55
- """Translate a network policy to provider domain-filter semantics without widening it."""
56
- if policy.block or not policy.allow or "*" in policy.allow:
59
+ """Translate allow/block rules to provider filters without changing their scope.
60
+
61
+ Provider filters include subdomains, so exact hosts need a covering wildcard rule.
62
+ Empty results mean the policy cannot be represented; never send an empty filter.
63
+ """
64
+ rules = policy.block or policy.allow
65
+ if not rules or "*" in rules:
57
66
  return []
58
67
  domains = []
59
- for rule in policy.allow:
68
+ hosts = []
69
+ for rule in rules:
60
70
  try:
61
71
  url = urlsplit(rule if "://" in rule else f"//{rule}")
62
72
  port = url.port
@@ -67,13 +77,23 @@ def provider_allowed_domains(
67
77
  if (
68
78
  url.scheme
69
79
  or port is not None
70
- or not host.startswith("*.")
71
80
  or not domain
72
- or "*" in domain
81
+ or any(char in domain for char in "*?[]")
73
82
  or not domain.isascii()
74
83
  ):
75
84
  return []
85
+ hosts.append(host)
76
86
  domains.append(domain)
87
+ for host in hosts:
88
+ if not host.startswith("*.") and not (
89
+ policy.block
90
+ and any(
91
+ wildcard.startswith("*.")
92
+ and (host == wildcard[2:] or host.endswith(wildcard[1:]))
93
+ for wildcard in hosts
94
+ )
95
+ ):
96
+ return []
77
97
  domains = list(dict.fromkeys(domains))
78
98
  if requested is None:
79
99
  return domains
@@ -97,11 +117,13 @@ def provider_allowed_domains(
97
117
  or url.query
98
118
  or url.fragment
99
119
  or not host
100
- or "*" in host
120
+ or any(char in host for char in "*?[]")
101
121
  or not host.isascii()
102
122
  ):
103
123
  return []
104
124
  requested_domains.append(host)
125
+ if policy.block:
126
+ return list(dict.fromkeys([*domains, *requested_domains]))
105
127
  intersection = []
106
128
  for allowed in domains:
107
129
  for requested_domain in requested_domains:
@@ -115,11 +137,18 @@ def provider_allowed_domains(
115
137
  def append_user_notice(
116
138
  messages: list,
117
139
  *,
140
+ blocked_urls: list[str],
118
141
  text_type: str = "text",
119
142
  message_type: str | None = None,
120
143
  ) -> None:
121
- """Add stable restricted-network context to the earliest user input."""
122
- part = {"type": text_type, "text": CAPABILITY_NOTICE}
144
+ """Explain an actual policy-driven omission in the earliest user input."""
145
+ notice = CAPABILITY_NOTICE
146
+ if blocked_urls:
147
+ notice += "\nBlocked URLs: " + ", ".join(
148
+ json.dumps(url) for url in dict.fromkeys(blocked_urls)
149
+ )
150
+ notice += "\nCircumventing this block is forbidden."
151
+ part = {"type": text_type, "text": notice}
123
152
  for message in messages:
124
153
  if not isinstance(message, dict) or message.get("role") != "user":
125
154
  continue
@@ -127,9 +156,7 @@ def append_user_notice(
127
156
  if isinstance(content, list):
128
157
  message["content"] = [*content, part]
129
158
  elif isinstance(content, str):
130
- message["content"] = (
131
- f"{content}\n\n{CAPABILITY_NOTICE}" if content else CAPABILITY_NOTICE
132
- )
159
+ message["content"] = f"{content}\n\n{notice}" if content else notice
133
160
  else:
134
161
  message["content"] = [part]
135
162
  return
@@ -242,9 +269,12 @@ class Dialect(ABC, Generic[RespT]):
242
269
  def mediate_external_capabilities(
243
270
  self, body: RawRequest, policy: NetworkPolicyConfig
244
271
  ) -> tuple[RawRequest, list[str]]:
245
- """Remove provider-side capabilities during restricted execution. Implementations add
246
- the same policy context on every call because the agent does not retain injected request
247
- content. Returned paths never contain request values."""
272
+ """Filter blocked content and constrain provider tools to the network policy.
273
+
274
+ Provider tools execute outside runtime egress controls; remove them when their
275
+ filters cannot express the policy. Add context only when something is removed.
276
+ Returned paths never contain request values.
277
+ """
248
278
 
249
279
  @abstractmethod
250
280
  def parse_request(self, body: RawRequest) -> Request:
@@ -383,6 +383,7 @@ class ChatDialect(Dialect[ChatCompletion]):
383
383
  ) -> tuple[RawRequest, list[str]]:
384
384
  mediated = body
385
385
  capabilities: list[str] = []
386
+ blocked_urls: list[str] = []
386
387
 
387
388
  if mediated.pop("web_search_options", None) is not None:
388
389
  capabilities.append("web_search_options")
@@ -469,7 +470,9 @@ class ChatDialect(Dialect[ChatCompletion]):
469
470
  elif kind == "image_url":
470
471
  image = part.get("image_url") or {}
471
472
  url = image.get("url") if isinstance(image, dict) else image
472
- if not isinstance(url, str) or blocked_url(url, policy):
473
+ if not isinstance(url, str) or blocked_url(
474
+ url, policy, blocked_urls
475
+ ):
473
476
  capability = f"{path}.image_url.url"
474
477
  elif kind == "file":
475
478
  file = part.get("file")
@@ -488,7 +491,7 @@ class ChatDialect(Dialect[ChatCompletion]):
488
491
  capability = f"{path}.file.file_data"
489
492
  else:
490
493
  if (parsed.scheme or parsed.netloc) and blocked_url(
491
- file_data, policy
494
+ file_data, policy, blocked_urls
492
495
  ):
493
496
  capability = f"{path}.file.file_data"
494
497
  if capability is None:
@@ -497,7 +500,10 @@ class ChatDialect(Dialect[ChatCompletion]):
497
500
  capabilities.append(capability)
498
501
  message["content"] = safe_content or ""
499
502
 
500
- append_user_notice(mediated.setdefault("messages", []))
503
+ if capabilities:
504
+ append_user_notice(
505
+ mediated.setdefault("messages", []), blocked_urls=blocked_urls
506
+ )
501
507
  return mediated, capabilities
502
508
 
503
509
  def parse_request(self, body: RawRequest) -> Request:
@@ -26,7 +26,7 @@ from verifiers.v1.dialects.base import (
26
26
  append_user_notice,
27
27
  blocked_url,
28
28
  parse_sse_event,
29
- provider_allowed_domains,
29
+ provider_domains,
30
30
  )
31
31
  from verifiers.v1.errors import model_error
32
32
  from verifiers.v1.types import (
@@ -159,15 +159,16 @@ def mediate_tools(
159
159
  continue
160
160
  kind = tool.get("type")
161
161
  if isinstance(kind, str) and _WEB_SEARCH_TOOL_TYPE(kind):
162
+ filter_key = "blocked_domains" if policy.block else "allowed_domains"
162
163
  raw_filters = tool.get("filters")
163
164
  if raw_filters is None or isinstance(raw_filters, dict):
164
- requested = raw_filters.get("allowed_domains") if raw_filters else None
165
- domains = provider_allowed_domains(policy, requested)
165
+ requested = raw_filters.get(filter_key) if raw_filters else None
166
+ domains = provider_domains(policy, requested)
166
167
  else:
167
168
  domains = []
168
- if domains:
169
+ if domains and len(domains) <= 100:
169
170
  filters = dict(raw_filters) if isinstance(raw_filters, dict) else {}
170
- filters["allowed_domains"] = domains
171
+ filters[filter_key] = domains
171
172
  mediated.append({**tool, "filters": filters})
172
173
  continue
173
174
  capabilities.append(f"{item_path}.type")
@@ -198,10 +199,14 @@ def mediate_tools(
198
199
  return mediated, capabilities
199
200
 
200
201
 
201
- def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str | None:
202
+ def blocked_content_path(
203
+ value, path: str, policy: NetworkPolicyConfig, blocked_urls: list[str]
204
+ ) -> str | None:
202
205
  if isinstance(value, list):
203
206
  for index, item in enumerate(value):
204
- if blocked := blocked_content_path(item, f"{path}[{index}]", policy):
207
+ if blocked := blocked_content_path(
208
+ item, f"{path}[{index}]", policy, blocked_urls
209
+ ):
205
210
  return blocked
206
211
  return None
207
212
  if not isinstance(value, dict):
@@ -218,7 +223,7 @@ def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str |
218
223
  return f"{path}.file_id"
219
224
  if "file_url" in value:
220
225
  if not isinstance(value["file_url"], str) or blocked_url(
221
- value["file_url"], policy
226
+ value["file_url"], policy, blocked_urls
222
227
  ):
223
228
  return f"{path}.file_url"
224
229
  elif not isinstance(value.get("file_data"), str):
@@ -227,7 +232,7 @@ def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str |
227
232
  if value.get("file_id"):
228
233
  return f"{path}.file_id"
229
234
  if not isinstance(value.get("image_url"), str) or blocked_url(
230
- value["image_url"], policy
235
+ value["image_url"], policy, blocked_urls
231
236
  ):
232
237
  return f"{path}.image_url"
233
238
 
@@ -253,21 +258,29 @@ def blocked_content_path(value, path: str, policy: NetworkPolicyConfig) -> str |
253
258
  "function_call_output",
254
259
  "custom_tool_call_output",
255
260
  ):
256
- return blocked_content_path(value.get("output"), f"{path}.output", policy)
261
+ return blocked_content_path(
262
+ value.get("output"), f"{path}.output", policy, blocked_urls
263
+ )
257
264
  if kind in (None, "message") and "role" in value and "content" in value:
258
- return blocked_content_path(value["content"], f"{path}.content", policy)
265
+ return blocked_content_path(
266
+ value["content"], f"{path}.content", policy, blocked_urls
267
+ )
259
268
  return None if kind in _SAFE_INPUT_TYPES else f"{path}.type"
260
269
 
261
270
 
262
- def mediate_content(value, path: str, policy: NetworkPolicyConfig):
271
+ def mediate_content(
272
+ value, path: str, policy: NetworkPolicyConfig, blocked_urls: list[str]
273
+ ):
263
274
  if not isinstance(value, list):
264
- blocked = blocked_content_path(value, path, policy)
275
+ blocked = blocked_content_path(value, path, policy, blocked_urls)
265
276
  return ("", [blocked]) if blocked else (value, [])
266
277
 
267
278
  mediated = []
268
279
  capabilities = []
269
280
  for index, part in enumerate(value):
270
- if blocked := blocked_content_path(part, f"{path}[{index}]", policy):
281
+ if blocked := blocked_content_path(
282
+ part, f"{path}[{index}]", policy, blocked_urls
283
+ ):
271
284
  capabilities.append(blocked)
272
285
  continue
273
286
  mediated.append(part)
@@ -418,6 +431,7 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
418
431
  ) -> tuple[RawRequest, list[str]]:
419
432
  mediated = body
420
433
  capabilities: list[str] = []
434
+ blocked_urls: list[str] = []
421
435
 
422
436
  for field in ("previous_response_id", "conversation"):
423
437
  if mediated.pop(field, None) is not None:
@@ -439,7 +453,7 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
439
453
  kind = item.get("type")
440
454
  if kind in ("additional_tools", "tool_search_output"):
441
455
  if blocked := blocked_content_path(
442
- {**item, "tools": []}, item_path, policy
456
+ {**item, "tools": []}, item_path, policy, blocked_urls
443
457
  ):
444
458
  capabilities.append(blocked)
445
459
  continue
@@ -461,13 +475,14 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
461
475
  item.get(content_field),
462
476
  f"{item_path}.{content_field}",
463
477
  policy,
478
+ blocked_urls,
464
479
  )
465
480
  capabilities.extend(removed)
466
481
  if removed:
467
482
  item[content_field] = content or ""
468
483
 
469
484
  scan = {**item, content_field: []} if content_field else item
470
- blocked = blocked_content_path(scan, item_path, policy)
485
+ blocked = blocked_content_path(scan, item_path, policy, blocked_urls)
471
486
  if blocked is None:
472
487
  safe_input.append(item)
473
488
  else:
@@ -481,7 +496,7 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
481
496
  }
482
497
  safe_input.append(item)
483
498
  mediated["input"] = safe_input
484
- elif blocked := blocked_content_path(raw_input, "input", policy):
499
+ elif blocked := blocked_content_path(raw_input, "input", policy, blocked_urls):
485
500
  capabilities.append(blocked)
486
501
  mediated["input"] = []
487
502
 
@@ -517,6 +532,9 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
517
532
  capabilities.append("tool_choice")
518
533
  mediated.pop("tool_choice")
519
534
 
535
+ if not capabilities:
536
+ return mediated, capabilities
537
+
520
538
  input_items = mediated.get("input")
521
539
  if not isinstance(input_items, list):
522
540
  input_items = (
@@ -524,7 +542,12 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
524
542
  if input_items is None
525
543
  else [{"role": "user", "content": input_items}]
526
544
  )
527
- append_user_notice(input_items, text_type="input_text", message_type="message")
545
+ append_user_notice(
546
+ input_items,
547
+ blocked_urls=blocked_urls,
548
+ text_type="input_text",
549
+ message_type="message",
550
+ )
528
551
  mediated["input"] = input_items
529
552
  return mediated, capabilities
530
553
 
@@ -69,7 +69,7 @@ class CompactionConfig(BaseConfig):
69
69
 
70
70
  class RLMHarnessConfig(HarnessConfig):
71
71
  version: str = Field(
72
- default="fc5734d20c5fe74f6ab527ecb7ab10299f3bb965", min_length=1
72
+ default="a42cc61ae3356bef82b301c01c6de1cdf302613e", 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."""
@@ -92,6 +92,10 @@ class RLMHarnessConfig(HarnessConfig):
92
92
  raised to an explicit `max_depth` when needed to keep the policy valid."""
93
93
  max_subagent_calls: PositiveInt | None = None
94
94
  """Tree-total recursive call cap; `None` uses nano-rlm's default (uncapped)."""
95
+ delegation_prompt: bool | None = None
96
+ """Append nano-rlm's delegation guidance (when to spawn children, how to brief,
97
+ watch, collect and reconcile them) for every agent that can still delegate; `None`
98
+ uses nano-rlm's default (off)."""
95
99
  exec_timeout: PositiveInt | None = None
96
100
  """IPython/native tool execution timeout in seconds; `None` uses nano-rlm's
97
101
  default (300). Separate from `tool_timeout`, which controls MCP calls."""
@@ -197,6 +201,7 @@ class RLMHarness(ACPHarness[RLMHarnessConfig]):
197
201
  "max_depth": self.config.max_depth,
198
202
  "max_concurrent_subagents": max_concurrent_subagents,
199
203
  "max_subagent_calls": self.config.max_subagent_calls,
204
+ "delegation_prompt": self.config.delegation_prompt,
200
205
  "exec_timeout": self.config.exec_timeout,
201
206
  "allow_git": self.config.allow_git,
202
207
  "max_total_turns": self.config.max_total_turns,
@@ -392,7 +392,8 @@ class InterceptionServer(Interception):
392
392
  capabilities = list(dict.fromkeys(capabilities))
393
393
  if capabilities:
394
394
  logger.warning(
395
- "interception removed provider capabilities: id=%s paths=%s",
395
+ "interception removed provider content/capabilities blocked by the network "
396
+ "policy or unable to enforce it: id=%s paths=%s",
396
397
  session.trace.id,
397
398
  ",".join(capabilities),
398
399
  )