plurai.__all__ and in plurai.observability.__all__. Anything else you can import is implementation detail and
may change between versions.
Writing simulate.py
mock
Registers a mock handler for one tool, with the descriptor the backend uses to generate the mock environment.tool_name(str): the tool’s name, as inplurai.config.yaml.descriptor(dict | None): the tool’s descriptor.descriptionandargsare filled from the handler’s docstring and signature when omitted.input_schema,output_schema(keyword): a Pydantic model for typed calls. Detected from a single Pydantic-typed parameter and a Pydantic return annotation when omitted; passNoneto opt out.**desc_kwargs: descriptor fields as keyword arguments.
observe
Registers an observer for a tool that runs for real, recording its result into the world.tool_name(str): the tool’s name.capture(Callable | None): an optional capture function.
MockToolNode
A drop-in replacement for a LangGraphToolNode that routes each tool call by its mode.
invoke and ainvoke, whose ToolMessages match ToolNode’s (name, tool_call_id,
status, artifact, content). A real or observe result is rendered as JSON. A failed call is a message with
status="error", not a raised exception. Calls run one after another, and injected state, store or runtime
arguments are not supplied.
Arguments
tools(list): the agent’s tools.mock_config(dict[str, str] | None): tool name to mode,"mock"(default),"observe"or"real".name(str, keyword): the node name. Default"tools".messages_key(str, keyword): the state key holding messages. Default"messages".
mock_wrap
Wraps one tool callable so its calls route through the mock environment.name, description and args_schema.
Arguments
func(Callable): the tool.mode(str):"mock"(default),"observe"or"real"(returns the tool unchanged).failure(Callable[[MockToolError], Any] | None): for a tool whoseerror_channelisreturns, builds the failure value the real tool returns. A tool declaredraisesraisesMockToolErrorinstead.
apply_mocks
Wraps every named function on a module in place withmock_wrap.
list[str]: the names actually patched. A tool built inside a factory closure or exported under
another name is not reachable and not patched.
Arguments
module: the module that defines the tools.mock_config(dict[str, str]): tool name to mode.
MockToolError
The exception a failed mocked call raises.message(str): the failure text.case(str): which kind of failure:error_message,engine_refusal,handler_errorordrifted_status_with_content.response: the response as served.
mock_result
Turns a mock response into what your agent sees: the tool’s value, or a raisedMockToolError.
content of a success, the error map of a failure the tool reports through its
value, or the response whole when it has no standard shape. Raises MockToolError for any other failure.
Arguments
response: the mock response.channel("raises" | "returns" | None): the tool’s declarederror_channel.raisesturns a reported failure into a raisedMockToolError.
configure
Connects this process to a mock service, or hosts one in-process for local development.None. In connect mode it raises when the mock is unreachable or unhealthy; it never falls back to
a local mock.
Arguments
service_url(str | None): the mock service URL. Optional inlocalmode, where the host and port are not honored.mode("connect" | "local", keyword): default"connect".mock_service_url(str | None, keyword): an alias ofservice_url. Pass one of the two.
SimulationContext
The scenario’s context, available in mock handlers, replacement nodes and your own code.agent_context(dict): the scenario’s context values.world_state: the world proxy. Seeworld_state.
get_simulation_context
Returns the currentSimulationContext.
SimulationContext.
world_state
The scenario’s world, read and written through the mock service.get_entity(entity_id): one entity, orNone.query(entity_type, **filters): entities of a type matching exact field values.apply(changes): write{entity_id: {fields}}. Each new entity carries_entity_type.entities: a mapping of every entity. It is aMapping, not adict.generate_uuid(): a new id.
world_state_snapshot
Returns the whole world as a plain dict, in one call.dict[str, dict]: entity id to entity. Free inside a mock handler; one HTTP call elsewhere. {} when
no mock client is configured.
Arguments
session_id(str | None): default the active session. RaisesRuntimeErrorwhen none is active.
active_session_id
Returns the id of the session active in this context.str | None. None outside a scenario.
mock_service_url
Returns the mock service URL this process is configured against.str | None. None before configure.
file_row
Theworld_snapshot() row for one file your agent produced or was handed.
dict with _entity_type, name, suffix, size_bytes, sha256 and, for a previewed file,
text_preview (at most 4,000 characters, with _preview_truncated when cut). Spreadsheet formulas appear as their
formula text with the value the file saved; nothing is calculated. A file too large or too slow to read is
_unreadable with a reason.
Arguments
path(str | PathLike): the file.entity_type(str, keyword): the row’s type.preview(bool, keyword):True(default) for a file your agent produced.Falsefor a file handed to it, which addscontent_typeinstead of a preview.
store_record
The record of your harness’s own store that a seeded world row stands for.dict: the row without _-prefixed keys and without the backend’s id copy. A row with no
_entity_type, or of an undeclared type, raises HarnessFault.
Arguments
row(Mapping): a seeded row.entity_types(Mapping | None, keyword): defaultworld_state.entity_typesfrom the config beside the harness.
model_input_context
Theinput_context entries for one turn: what your agent’s model call received that the conversation does not
carry.
list[dict[str, str]]: {"source", "content"} per injected text, in model-input order. Agent-side
messages, a leading system prompt, blank text and text the conversation already carries are left out.
Arguments
model_input: the messages the model call received.conversation: the messages the harness handed the agent.source(str, keyword): the read the entries came from.
HarnessFault
Raised bysimulate.py for a refusal the harness makes, so the scenario is not scored against your agent.
not_valid. Recorded when constructed, so an agent tool that catches it does not hide it.
AgentFault
Raised by a harness on your agent’s behalf, when the agent’s own code failed where no Python frame shows it.invoke_agent, recorded as agent_raised, a failed trial your agent owns. A provider failure and an
earlier HarnessFault in the turn still win.
Host effects
For an agent built onclaude_agent_sdk, these confine each scenario’s Claude Code CLI session.
Running simulations
These REST client types live inplurai.orchestrator, not the package root.
Orchestrator
Drives one scenario end to end: opens the conversation, runs your harness in a child process, plays the turns, and finalizes for scoring.run: a ThreadResult.
Arguments (constructor, keyword-only)
simulate_path(Path): your harness.settings: the SDK’s settings object.observability(ObservabilitySink): the recording sink; seecreate_observability_sink. The orchestrator never closes it.client(OrchestratorClient): the backend client.shape("dialog" | "pipeline" | None): a debugging override;Nonelets the bench’s declaration decide.
run, keyword-only): scenario_set_id, scenario_id, eval_set_id, max_turns (default 5),
agent_version, mock_service_url, scenario_time_budget, and the required redrive_available and
allow_turn_timeout_redrive.
OrchestratorClient
The async client for the backend’s simulation API.base_url(str): the backend base URL.timeout(float): read timeout in seconds. Default 1200.api_key(str | None): the bearer token.retry: the retry policy. Default: the SDK’s.
ThreadResult
The outcome of oneOrchestrator.run().
thread_id, turns, finalize (the scoring response), user_messages, chatbot_messages,
tool_events, transcript_turns, ended_early and ended_early_cause, and resume_seed. summary() returns a
short description.
OrchestratorAdapterError
Raised when your harness’sinvoke_agent, seed_state or invoke_pipeline hits a misuse the runner can detect.
RuntimeError. Attributes: child_exc_class (the original exception class in your harness),
timed_out, thread_id, raised_at ("init" or "finalize"). The original exception is __cause__.
GraphRecursionWrap
AnOrchestratorAdapterError raised when your LangGraph agent hit its recursion limit.
cause_class ("local_seed", "remote_mock" or "unknown", best-effort), thread_id,
turn_idx. It counts as your agent’s failed trial only when the agent was not silent before it crashed.
Tool and state contract
ToolDescriptor
The schema of onetools.<name>.descriptor block in plurai.config.yaml.
description (required), original_module, original_function, reads_from, writes_to,
stateful, args, returns, agent_usage and business_rules. A descriptor whose writes_to is set must
declare post-conditions.
Mock service
MockServiceClient
The HTTP client for a mock service, local or remote.base_url(str): the mock service URL.
MockService
The mock engine: world state, events and your registered handlers, served over HTTP.configure(mode="local")
builds one for you.
port (default 8199), host (default 127.0.0.1), and optional handlers, observers,
descriptors, schemas. LocalMockService is a deprecated alias.
start_session
Starts a simulation session against the configured mock service and makes it the active one.dict). Concurrent scenarios are isolated per asyncio task.
Arguments: session_id (str), initial_world_state (dict), agent_context (dict | None).
get_full_state
Returns the current world state of a session.session_id (str | None), default the active session.
get_events
Returns the recorded tool events of a session.session_id (str | None), default the active session.
Code action channel
For an agent that calls a vendor SDK or CLI from code it runs (for example a skill snippet), these route those calls to the mock environment. The surface is projected from the mock tools inplurai.config.yaml.
Version
__version__
The installed SDK version.plurai.observability
Client-side recording of Runs to one observability platform. See Trace sources for configuration.create_observability_sink
Builds the one active sink from settings.ObservabilitySink: the sink whose <SINK>__ENABLED flag is set, or a NoOpSink when none is.
Enabling more than one sink raises ValueError at startup.
Arguments: settings, the SDK’s settings object.
ObservabilitySink
The protocol every sink satisfies: tracing a Run and syncing its dataset. A malformed sink fails at startup.NoOpSink
The sink in use when none is configured. Every method does nothing.LangSmithSink, LangfuseSink, ArizeSink, BraintrustSink
The four sinks, each built from its config.LangSmithSinkConfig, LangfuseSinkConfig, ArizeSinkConfig, BraintrustSinkConfig
Each sink’s settings, read from the matching<SINK>__<FIELD> environment variables.
LangSmithRunContext, LangfuseRunContext, ArizeRunContext, BraintrustRunContext
The per-scenario context each sink’sprepare_run returns and its later calls take. You do not build these
yourself.
RollupMetric
One rollup feedback row a sink posts per scenario. Fields:key (str), score (float), comment (str), value (float | str).
swallowable_error_types
Builds the tuple of exception classes a sink may swallow, from(module_path, class_name) pairs that resolve.
tuple[type[BaseException], ...], or fallback (default (OSError,)) when nothing resolves.