Skip to main content
Requires Python 3.11 or newer. The SDK is native Python; it does not invoke the Node.js CLI.

Authorize and select scope

If you have already run firedrill init with the optional CLI, reuse its public configuration and protected login. Interactive initialization offers sign-in if needed:
For CI or an already authorized Python-only setup, supply a scoped FIREDRILL_TOKEN from your secret store and select the actual FIREDRILL_PROJECT_ID / FIREDRILL_ENVIRONMENT_ID pair. Then use Firedrill(), or pass project_id and environment_id explicitly. Do not put tokens in source or recipes.

Human sign-in without the CLI

Run this deliberately in a human’s interactive terminal, not CI or captured coding-agent output:
This displays human verification details, never access or refresh tokens. Ordinary simulation methods never open a browser. To discover scope after authorization:
Select an actual pair above. If you intend to create a project, account.create_project("My application", idempotency_key="my-application-project") atomically returns it and its Default environment. Save and reuse that key/name after uncertain delivery.

Simulate your application

This example assumes your application exposes run_agent in app.agent. Adapt the import and callback to the real application. Save as simulate.py:
For Python-only scope selected through environment variables instead of a config file, change the client line to client = Firedrill(). The example invokes the callback four times and requests no grading. Replace the scenario input with tasks your actual application understands. Callbacks return JSON-compatible output. Context includes detached task input/configuration, ID-only scenario context, run/attempt IDs, cancellation/deadline helpers, run-scoped Tools, observations, metrics, and attachments. Observations remain runner-attributed evidence. Native execution is not a sandbox; timeouts do not guarantee arbitrary application work stopped.

Async applications

Use AsyncFiredrill in your existing event loop:
The synchronous and asynchronous clients expose the same operation names. simulate(recipe, target=None, *, operation_id=None, allow_parallel=False, submission_origin=None, ci_context=None, on_progress=None) accepts a recipe dictionary or selected JSON file.

Retained reads and recovery

Async callers await these methods. Preserve result.operation_id and the private journal after a partial result. result.to_dict() uses canonical wire names such as operationId and reportUrl. A retained read does not create an execution operation ID.

CI and assessment

Use submission_origin="ci" on a fresh simulation or set FIREDRILL_SUBMISSION_ORIGIN=ci. The CI generator can execute your Python script directly. For the saved-recipe version of the synchronous script above, keep the actual application target and replace its simulation/output section with:
The generated workflow supplies CI origin and protected credentials. This script propagates retained gate/execution state; a printed report alone is not a passed job. The result separates execution, observed outcome, optional assessment, and the optional gate. Valid wording can earn partial or full semantic credit without exact matching. Fractional provider scores remain distinct from rubric levels. Missing assessment is not zero; evaluation errors are not agent failures. Keep application/model credentials separate from Firedrill authorization. See errors and recovery for safe reconciliation.