Skip to content

KairosClient Reference

The KairosClient is your single entry point into the Ananke ecosystem. It wraps httpx for standard REST requests and websockets for real-time streaming, abstracting away the underlying tRPC envelope.

from kairos import KairosClient
client = KairosClient(
url="https://api.anankelabs.ai", # Optional if KAIROS_URL is set
api_key="krs_...", # Optional if KAIROS_API_KEY is set
timeout=30.0, # Request timeout in seconds
engine_version="1.4.4", # Optional pinned engine version
max_retries=3, # Max transient error retries
retry_backoff=1.0, # Exponential backoff base delay
)

For peer-reviewed research, it is absolutely critical that simulation traces are perfectly reproducible years later. KAIROS guarantees bit-for-bit reproducibility if you lock the engine_version.

# Pins your client to a specific release of the continuous physics engine.
client = KairosClient(engine_version="1.4.4")

If the requested engine version is no longer active on the server, the SDK raises an EngineVersionError detailing the valid available constraints.

The highest-level method to execute a scenario is .run(). It handles creating the simulation and streaming the execution to completion.

Executes a scenario eagerly into memory.

trace = client.run(
scenario=my_scenario,
ticks=1000,
organization_id="org_id" # Optional, for billing/tracking purposes
)

For massive simulations that would cause Out-Of-Memory (OOM) errors if eagerly loaded, use the iterator.

# Yields TraceStep objects iteratively over a WebSocket
for step in client.stream_run(scenario, ticks=100_000):
if step.stability < 0.1:
print(f"Danger at tick {step.t}")

For high-throughput evaluations (e.g., Monte Carlo sampling of different capability jumps), the client provides a full asyncio interface. All async methods are prefixed with a.

import asyncio
from kairos import KairosClient
from kairos.domains.ai_safety import AISafetyScenario, AISafetyEventType
async def capability_sweep():
"""Sweep over capability values to find the critical destabilization threshold."""
client = KairosClient()
async def run_one(capability):
scenario = (
AISafetyScenario(f"sweep_{capability}", seed=capability)
.add_model(
name="model",
capability_index=capability,
alignment_score=70,
guardrail_coverage=60,
)
.add_event(100, AISafetyEventType.CAPABILITY_JUMP, target="model", magnitude=0.3)
)
trace = await client.arun(scenario, ticks=500)
return {
"capability": capability,
"final_phase": trace.final_phase(),
"mean_stability": trace.mean_stability(),
"basin_losses": len(trace.basin_losses()),
}
# Run 50 simulations concurrently
tasks = [run_one(cap) for cap in range(100, 1001, 18)]
results = await asyncio.gather(*tasks)
for r in results:
print(f" cap={r['capability']:>4} phase={r['final_phase']:<10} "
f"stability={r['mean_stability']:.4f} losses={r['basin_losses']}")
asyncio.run(capability_sweep())

For a full version with DataFrame collection and threshold analysis, see the Monte Carlo Parameter Sweep use case.

The SDK is highly resilient, built to survive integration into automated ML evaluation harness pipelines. It internally catches and retries 429 Too Many Requests, 502 Bad Gateway, and 503 Service Unavailable.

It avoids mutating endpoints twice by disabling connection-error retries for simulation.create by default.

Check kairos.errors for the exception hierarchy:

  • AuthenticationError: Invalid API keys.
  • RateLimitError: Standard 429 backoff failures (includes retry_after).
  • SimulationError: Core engine calculation faults.
  • ValidationError: Pre-flight client-side scenario rejection.