Skip to content

statspai.agent

agent

LLM agent-native tool-definition surface.

StatsPAI's agent-native branding delivers a concrete API here:

  1. tool_manifest() — returns a list of JSON-schema tool specs in the OpenAI / Anthropic tool-use format; drop straight into an agent's tools= parameter and the model can call StatsPAI estimators directly.

  2. execute_tool(name, arguments, data) — single entry point that dispatches a tool call back to the right StatsPAI function, serialises the result in a JSON-friendly dict.

  3. remediate(error, context) — error → actionable-fix registry. Given a Python exception from a failed tool call, returns a structured suggestion the agent can use to repair its next call.

Why this matters

An LLM that wants to call StatsPAI programmatically needs three things docstrings don't provide:

  • Machine-readable schemas for registered StatsPAI functions.
  • A round-trippable result representation.
  • A mapping from errors to concrete next steps.

This module provides all three as a coherent layer so an agent built on top of StatsPAI can loop "try → fail → remediate" deterministically.

Usage

With Anthropic's Claude tool-use API::

import anthropic, statspai as sp
client = anthropic.Anthropic()
response = client.messages.create(
    model='claude-opus-4-7',
    tools=sp.agent.tool_manifest(),
    messages=[{'role': 'user', 'content': 'Run a DID on ...'}],
)
for block in response.content:
    if block.type == 'tool_use':
        out = sp.agent.execute_tool(
            block.name, block.input, data=my_df,
        )

tool_manifest

tool_manifest(*, curated_only: bool = False) -> List[Dict[str, Any]]

Return the list of tool specifications for an LLM agent.

Each spec conforms to the Anthropic / OpenAI tool-use JSON schema format. Drop directly into client.messages.create(tools=...) (Anthropic) or client.chat.completions.create(tools=[...]) (OpenAI).

Parameters:

Name Type Description Default
curated_only bool

If True, return only the hand-curated tools (the bespoke 13 + the workflow / handle / bibtex tools registered by :mod:statspai.agent.workflow_tools + the pipeline composites from :mod:statspai.agent.pipeline_tools). The default merges them with the auto-generated manifest covering every agent-safe registered function so the caller sees the full catalogue (~470 tools).

False

Returns:

Type Description
list of dict

Each with keys 'name', 'description', 'input_schema'.

execute_tool

execute_tool(name: str, arguments: Dict[str, Any], data: Optional[DataFrame] = None, *, detail: str = 'agent', result_id: Optional[str] = None, as_handle: bool = False) -> Dict[str, Any]

Dispatch a tool call to the right StatsPAI function.

Parameters:

Name Type Description Default
name str

Tool name (must match a TOOL_REGISTRY entry, an auto-registered registry function, or a built-in *_result / bibtex workflow tool).

required
arguments dict

Tool-call arguments as provided by the LLM (JSON object).

required
data DataFrame

Dataset the estimator runs on. Required by most tools.

None
detail ('minimal', 'standard', 'agent')

Payload depth requested by the caller. Forwarded to the default serializer's r.to_dict(detail=...).

"minimal"
result_id str

Handle to a previously-fitted result cached by the server. When supplied, *_from_result tools resolve it from the result cache; other tools merge selected fields from the cached result (e.g. betas / sigma for honest_did_from_result).

None
as_handle bool

If True, cache the fitted result and inject result_id / result_uri into the returned dict so a subsequent execute_tool call can reference it without re-fitting.

False

Returns:

Type Description
dict

JSON-serialisable result, suitable for returning to the LLM as tool output. On error, returns {'error': <str>, 'remediation': <dict>} — the agent can use remediation to repair its next call.

remediate

remediate(error: BaseException, context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]

Return a structured remediation suggestion for an exception.

Parameters:

Name Type Description Default
error BaseException

The exception raised from a failed tool call.

required
context dict

Extra info to include in the response (e.g. which tool failed, what arguments were passed). Forwarded verbatim.

None

Returns:

Type Description
dict with keys:

'category' : short label 'diagnosis' : human-readable explanation 'fix' : concrete next action 'matched' : True if a registry entry matched 'exception_type' : class name of the raised error 'exception_message' : str(error) (truncated on the agent side) 'recovery_hint' : (StatsPAIError only) hint from the raiser 'diagnostics' : (StatsPAIError only) scalar-key map 'alternative_functions': (StatsPAIError only) ranked sp.* names

mcp_serve_stdio

mcp_serve_stdio(stdin: Optional[Iterable[str]] = None, stdout=None) -> None

Run the JSON-RPC loop on stdio until stdin closes.

Parameters:

Name Type Description Default
stdin file - like

Defaults to sys.stdin / sys.stdout. Tests can supply in-memory buffers instead.

None
stdout file - like

Defaults to sys.stdin / sys.stdout. Tests can supply in-memory buffers instead.

None

mcp_handle_request

mcp_handle_request(line: str) -> Optional[str]

Process a single JSON-RPC request line; return the response line.

Returns None for notifications — both the JSON-RPC 2.0 form (id field entirely absent) and the MCP convention of any method whose name starts with "notifications/" (e.g. notifications/initialized sent by Claude Desktop / Cursor immediately after the handshake). The MCP spec mandates servers MUST NOT respond to those.