SDK & API
Field-level reference for the SDK's callback contract and REST endpoints.
This page is the reference for reaching Simulation from your own code: the agent-simulate Python package’s callback contract and TestRunner, and the REST endpoints it calls to execute a run. It covers chat agents only, since a chat agent is answered by your own code rather than dialed over the phone. If you haven’t connected one yet, start with Connect your agent. For the guided walkthrough, see Run a chat simulation.
Install and authenticate
pip install agent-simulate
from fi.simulate import TestRunner, AgentInput, AgentResponse, AgentWrapper
TestRunner takes api_key, secret_key, and api_url, each falling back to an environment variable if omitted:
| Argument | Env var | Default |
|---|---|---|
api_key | FI_API_KEY | none |
secret_key | FI_SECRET_KEY | none |
api_url | FI_BASE_URL | https://api.futureagi.com |
Requests carry the key and secret as x-api-key and x-secret-key headers. A missing key or secret only logs a warning at construction time; nothing fails until the first request comes back 401.
The callback contract
Your code is the agent. Each turn, the SDK calls your agent_callback with an AgentInput and expects back a str or an AgentResponse.
AgentInput
| Field | Type | Required | Description |
|---|---|---|---|
thread_id | str | yes | Identifies the conversation this turn belongs to |
messages | List[Dict[str, str]] | yes | The full conversation so far, including the latest simulator message |
new_message | Optional[Dict[str, str]] | no | The latest simulator message, the one to reply to this turn |
execution_id | Optional[str] | no | Correlates this turn back to the run, for your own logging |
AgentResponse
| Field | Type | Required | Description |
|---|---|---|---|
content | str | yes | The reply text sent back to the simulator |
tool_calls | Optional[List[Dict[str, Any]]] | no | Tool calls your agent made this turn |
tool_responses | Optional[List[Dict[str, Any]]] | no | Results for those tool calls, each a dict with role, tool_call_id, content |
metadata | Optional[Dict[str, Any]] | no | Free-form extra data; also accepts metadata["tool_outputs"] as {"call_id": ..., "output": ...} entries, an alternate way to report tool results |
Returning a bare str is shorthand for AgentResponse(content=...) with everything else empty:
async def agent_callback(input: AgentInput) -> str:
user_text = (input.new_message or {}).get("content", "") or ""
return f"Echo: {user_text}"
AgentWrapper is the class form: an abstract base class where you implement async def call(self, input: AgentInput) -> Union[str, AgentResponse] and pass an instance as agent_callback instead of a function. Either shape works: a plain async def function is wrapped automatically.
Note
If call() raises, the SDK doesn’t forward your exception. It reports a generic error to the platform and marks the call completed if at least one earlier turn already succeeded, or failed if it fails on the first turn. Log the real error on your own side; it won’t show up in the transcript.
The conversation ends when the platform reports the chat as ended, or after 50 turns, whichever comes first.
TestRunner.run_test
runner = TestRunner() # reads FI_API_KEY / FI_SECRET_KEY / FI_BASE_URL from env
report = await runner.run_test(
run_test_name="Chat test", # or run_id="<uuid>"
agent_callback=agent_callback,
concurrency=1,
)
- Exactly one of
run_idorrun_test_nameidentifies which run test to execute;run_test_namemust match the simulation’s name exactly, the same one it’s created under in the UI or via Create a simulation agent_callbackis your callback function orAgentWrapperinstanceconcurrencycontrols how many calls run in parallel
Note
run_test returns a TestReport, but in the current release its results field is always empty. Transcripts, metrics, and evaluations live on the platform, not on the returned object; read them from the dashboard or the REST endpoints below.
REST endpoints
These are the endpoints agent-simulate calls on your behalf while run_test runs. They’re useful for building your own client outside the SDK, or for understanding what a run does over the network. Authentication is the same x-api-key / x-secret-key headers as above.
| Method | Path | Purpose |
|---|---|---|
GET | /simulate/run-tests/get-id-by-name/{run_test_name}/ | Resolve a run test’s ID from its exact name |
POST | /simulate/run-tests/{run_test_id}/chat-execute/ | Start a chat execution for a run test |
POST | /simulate/test-executions/{test_execution_id}/chat/call-executions/batch/ | Create a batch of call executions under a test execution |
POST | /simulate/call-executions/{call_execution_id}/chat/send-message/ | Send one turn’s message on a call execution |
PATCH | /simulate/call-executions/{call_execution_id}/ | Update a call execution’s status |
Paths are relative to the same base URL as the SDK, https://api.futureagi.com unless FI_BASE_URL overrides it.
Questions & Discussion