Skip to content

Integrations

Five ways in; all evaluate against the exact same world and produce the same verdict files. Runnable versions of everything below live in examples/.

MCP (agent unchanged)

eval-mock run scenario.yaml -- <your agent command>   # URL in EVAL_MOCK_MCP_URL
eval-mock serve scenario.yaml --transport http        # long-lived, watch & iterate

Streamable HTTP + stdio, official SDK, pinned mcp>=2.0,<3. Run lifecycle: call eval.finish with your final answer (it's assertable); budgets end the run with exit code 3. Concurrent tool calls execute in a deterministic order under --determinism strict (default).

OpenAI function calling

env = EvalMockEnv("scenario.yaml")
tools = env.openai_tools()
# response = client.chat.completions.create(model=..., messages=msgs, tools=tools)
for tool_call in response.choices[0].message.tool_calls:
    msgs.append(env.call(tool_call))  # {"role": "tool", ...} ready to append

Anthropic tool use

tools = env.anthropic_tools()
# response = client.messages.create(model=..., messages=msgs, tools=tools)
results = [env.call(block) for block in response.content if block.type == "tool_use"]
msgs.append({"role": "user", "content": results})

Provider tool names cannot contain dots, so email.send is exposed as email__send and mapped back on dispatch. Hallucinated tool names still reach the journal as TOOL_NOT_ENABLED — visible to assertions. Unparseable arguments come back as MALFORMED_TOOL_CALL without touching the world.

pytest (evals as tests)

def test_my_agent(eval_mock_env):  # fixture ships with the package
    env = eval_mock_env("scenarios/email.yaml")
    ...
    env.finish("done")
    env.assert_pass()  # raises with ring attribution

JUnit for CI dashboards: pytest --junitxml=report.xml. A copy-paste GitHub Actions gate lives at examples/ci/github-actions-eval.yml.

DeepEval (optional extra)

pip install 'eval-mock[deepeval]'
from eval_mock.integrations.deepeval import to_deepeval_test_cases

cases = to_deepeval_test_cases(verdict, task_prompt=prompt)

Division of labour: eval-mock records deterministic facts (assertions, rings, repro identity ride along in additional_metadata); your judge adds semantic metrics on top. The same pattern works for LangSmith or a hand-rolled judge — verdicts are plain JSON.