Skip to main content

stimulir

Command-line interface and Python SDK for the Stimulir Console platform — workspaces, API keys, BYOK credentials, usage/billing, prompts, models, inference, realtime voice, and HybrIE lab/compute.

Built with Python 3.11+, Typer, Rich, and httpx. The optional realtime extra adds a websocket voice client (websockets).

Get started

Run one command in your project, or paste it into your coding agent (Cursor, Codex, Claude Code):

npx stimulir setup                    # needs Node 18+ and uv (or pipx)
uvx stimulir setup                    # no Node needed
stimulir setup                        # if the CLI is already installed

It takes you from nothing to your first trace:

  1. Signs you in through the browser (the same device flow as stimulir login).
  2. Picks the project traces go to: your current or default one, or --project <name or id>.
  3. Creates a project-bound key called <tool>-<your name> (--key-name to change it).
  4. Adds the Stimulir MCP server so the coding agent can read traces, run evaluations and edit agents: .mcp.json for Claude Code (through claude mcp add --scope project when claude is installed), .cursor/mcp.json for Cursor, ~/.codex/config.toml for Codex.
  5. Points your app's AI calls at the gateway by writing the base URL and key into .env.local or .env (--env-file to choose), for each SDK it finds: OPENAI_BASE_URL / OPENAI_API_KEY (openai, Vercel AI SDK, litellm), ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY (Anthropic SDKs), plus STIMULIR_API_KEY and STIMULIR_PROJECT_ID. It never edits source files: if your code hardcodes a base URL it prints the one-line change instead.
  6. Sends one test request tagged stimulir-setup and prints the trace link.
$ npx stimulir setup --tool claude-code
✓ Signed in as rashid@acme.dev
✓ Project checkout-api
✓ Created key claude-code-rashid
✓ Added MCP server stimulir to .mcp.json
✓ Updated .env.local (OPENAI_BASE_URL, OPENAI_API_KEY, STIMULIR_API_KEY, STIMULIR_PROJECT_ID)
→ Sending a test request…
✓ MiniMaxAI/MiniMax-M3 replied in 842 ms
  Trace: https://console.stimulir.com/traces/<trace-id>
Restart Claude Code and approve the stimulir MCP server when it asks.

--tool is auto by default (it detects the agent it runs inside, then what is installed, and asks when that is ambiguous); pass claude-code, cursor, codex or none. Coding agents should pass --yes, which accepts every default and needs no terminal. Re-running is safe: files are merged, other MCP servers and env lines are kept, a replaced value stays as a comment, and originals are backed up to ~/.stimulir/backups/. Setup offers to add the env and MCP files to .gitignore because they hold your key. Use --no-test to skip the request, --model to pick its model, and --base-url staging (or a full URL) to set up against another environment; outside production the MCP server runs locally through uvx --from 'stimulir[mcp]' stimulir-mcp.

Install

Once published to PyPI:

uv tool install stimulir
stimulir --help
# or run without installing:
uvx stimulir --help

From this repo (development):

uv tool install ./cli          # isolated tool from the local source
# or, for live-editing development:
cd cli && uv venv && uv pip install -e .

Conda/miniconda note: if you use plain pip install -e instead of uv, Anaconda Python builds skip the __editable__.*.pth hook, so the editable install silently fails to import (ModuleNotFoundError: stimulir_cli). uv avoids this entirely.

Python SDK

For application or backend code, add the package to that project's runtime environment instead of installing it as an isolated CLI tool:

uv add stimulir                 # core SDK
uv add 'stimulir[realtime]'     # + the realtime voice client (adds websockets)

Then import the SDK from the public package:

import os

from stimulir import StimulirClient

client = StimulirClient(
    api_base=os.getenv("STIMULIR_API_BASE", "https://api.stimulir.com"),
    api_key=os.environ["STIMULIR_API_KEY"],  # hyb_...
)

The hyb_* key is the normal customer/runtime auth path. Stimulir derives the workspace and allowed platform scope from the key, so application code does not need to pass a workspace id for normal prompt, data, eval, or inference calls.

Improve

Use Improve to diagnose captured traces and compare prompt or model candidates. Inspect first, preview the cohort and evaluator, then start a run with the reviewed preview token and cohort fingerprint. Promotion remains a separate human decision.

inventory = client.improve.inspect()  # Read-only project inventory.
# Preview with the cohort, evaluator and exact judge required by your project.
preview = client.improve.preview(
    source_window="today",
    trace_tags=["support"],
    evaluation={"evaluator": {"id": "<published-evaluator-id>"}},
)
# For an LLM evaluator, also pass evaluation.judge with the exact provider/model.
# Start only after checking that the preview is runnable and reviewing its cost.
started = client.improve.run(
    normalized_source=preview["normalized_source"],
    preview_token=preview["preview_token"],
    cohort_fingerprint=preview["cohort_fingerprint"],
    evaluation={"evaluator": {"id": "<published-evaluator-id>"}},
)
stimulir lab improve inspect --env-file .env
stimulir lab improve --help

client.rsi and stimulir lab rsi remain compatibility aliases. Existing server response fields such as rsi_run, run IDs and API paths are unchanged. See Improve documentation for cohort selection, evaluator requirements and the full lifecycle.

Configuration & auto-resolution

StimulirClient() and the realtime client resolve everything from the environment when you omit it, so most apps construct them with no args. The same resolvers are exposed for direct use:

from stimulir_cli import config Resolves from (in order) Default
config.get_api_base() STIMULIR_API_BASE https://api.stimulir.com
config.get_api_key() STIMULIR_API_KEY → HYBRIE_API_KEY → credentials file —
config.get_inference_base_url() STIMULIR_INFERENCE_BASE_URL → HYBRIE_MANAGED_BASE_URL {api_base}/api/v1/inference
config.get_realtime_url() STIMULIR_REALTIME_URL → HYBRIE_REALTIME_URL {api_base}/api/v1/inference/realtime?provider=vertex (https→wss)
config.get_realtime_model() STIMULIR_REALTIME_MODEL → HYBRIE_REALTIME_MODEL canonical Vertex Live model
config.get_model_preference() STIMULIR_MODEL_PREFERENCE → HYBRIE_MODEL_PREFERENCE [] (caller supplies its own list)

Legacy HYBRIE_* names are a deprecated fallback, always below the STIMULIR_* name. Use config.resolve_env(primary, *legacy, default=...) for your own keys.

Prompts

Versioned prompts that render themselves ({{var}} and {var}; None → ""):

prompt = client.prompts.get("aca.assessment.agent", label="prod")
text = prompt.render({"category": "AI fluency", "name": "Tosin"})
print(prompt.lineage)  # {"prompt_key": ..., "prompt_version": ..., "prompt_label": ...}

Models

models = client.models.list()  # normalized list[str] of advertised model ids

Realtime voice (stimulir[realtime])

The realtime client lives behind the realtime extra — a plain import stimulir never loads websockets. It speaks the managed gateway's voice protocol and enforces the once-only setup invariant: a second setup on a live connection is swallowed, not forwarded (which is what keeps a voice session from fragmenting into one trace per turn).

from stimulir.realtime import RealtimeClient, AudioDelta, ResponseDone

rt = RealtimeClient(  # url / key / model auto-resolve from config if omitted
    instructions="You are a friendly interviewer.",
    temperature=0.7,
)

async with rt.connect() as conn:           # Bearer-only auth
    await conn.setup()                      # once per connection (idempotent)
    await conn.send_audio(pcm16_16k_mono)   # stream input audio
    await conn.commit()
    await conn.create_response()
    async for ev in conn.events():          # typed events
        if isinstance(ev, AudioDelta):
            play(ev.pcm16)                   # 24k mono PCM16 out
        elif isinstance(ev, ResponseDone):
            break

Reconnection policy is the caller's: each connect() is one connection, and the once-only setup guard resets per connection (which is correct — a reconnect needs exactly one fresh setup).

MCP server (stimulir[mcp])

Stimulir as an MCP server — one hyb_* workspace key gives any MCP host (claude.ai, Claude Code, Claude Desktop, Cowork, or your own agent runtime) task-shaped tools: infer (streamed chat), speak (TTS over the realtime lane), transcribe, usage, models, and list_prompts/get_prompt.

Hosted (no install) — point your host at https://mcp.stimulir.com/mcp with an Authorization: Bearer hyb_... header:

claude mcp add --transport http stimulir https://mcp.stimulir.com/mcp \
  --header "Authorization: Bearer hyb_..."

Local (stdio) — the server ships behind the mcp extra:

pip install 'stimulir[mcp]'
stimulir-mcp            # stdio (default)
stimulir-mcp --http     # streamable HTTP on 0.0.0.0:8484

# or without installing:
claude mcp add stimulir -e STIMULIR_API_KEY=hyb_... -- \
  uvx --from 'stimulir[mcp]' stimulir-mcp

Key resolution order: per-request Authorization: Bearer header (hosted) → STIMULIR_API_KEY → ~/.stimulir/credentials.json (written by stimulir login). Keys are never logged.

Login

stimulir login uses a browser-based device authorization — no password is ever typed in the terminal. It prints a link and a short code, you approve in the console, and the CLI receives a revocable stim_cli_ token:

stimulir login
# 1. CLI prints a link + a short user_code, e.g.
#      Go to https://console.stimulir.com/cli and confirm it shows: ABCD-1234
# 2. Approve in the browser (already signed in) — confirm the code, pick a workspace
# 3. CLI receives an opaque stim_cli_ token, stored in
#    ~/.stimulir/credentials.json (0600), with the workspace pre-selected

Bare stimulir (when logged out) offers to run this same flow inline before starting the agent.

The stim_cli_ token is opaque, revocable, non-refreshable, with a 30-day TTL, pinned to your user and the workspace you selected. To rotate it, just log in again. A 401 from the server means the token expired or was revoked — re-run stimulir login.

The CLI defaults to production. To test against staging, pass --env before the subcommand — it's sugar for exporting STIMULIR_API_BASE for the duration of that one invocation:

stimulir --env staging login
stimulir --env staging keys create --name my-first-key --save
stimulir login   # no flag — back to production

stimulir login pins whichever base you authenticated against into ~/.stimulir/config.json, so a later bare stimulir in a fresh shell stays on staging until you log in again without --env (or stimulir whoami to check which one is active). For a base that isn't a named api.<env>.stimulir.com subdomain (a local dev server, a tunnel), set STIMULIR_API_BASE directly — env var or ~/.stimulir/config.json — instead of --env.

Already have a token from the console web app? Paste it as an escape hatch:

stimulir login --token <token>

Inspect or end your session with:

stimulir whoami           # opaque token: shows local email + prefix, plus
                          # server-confirmed identity, workspace, and expiry
stimulir logout           # clears the local credentials file
stimulir logout --remote  # revokes the server-side token, then clears locally

Authenticating an agent with an API key

Console-plane commands (lab, data, traces, prompts, workspace, ...) accept a hyb_* API key as well as a browser login, so a headless agent that was handed a key can drive them with no interactive step:

export STIMULIR_API_KEY=hyb_...
export STIMULIR_WORKSPACE_ID=<workspace-id>   # required, see below
stimulir lab eval create-run --data-asset-id <asset-id> --execute

Credential precedence, explicit environment before ambient file:

Order Source Notes
1 STIMULIR_ACCESS_TOKEN Console-plane override, forwarded verbatim
2 STIMULIR_API_KEY / HYBRIE_API_KEY Beats any stored login: naming a key for this process is deliberate, a stored login is whatever the machine had
3 cli_token in ~/.stimulir/credentials.json The device login
4 access_token in ~/.stimulir/credentials.json Legacy Supabase session, auto-refreshed
5 api_key in ~/.stimulir/credentials.json Written by stimulir keys create --save; used only when there is no stored login, so it never silently downgrades a logged-in user

stimulir whoami reports which one is in play as auth_kind (access_token / cli_token / api_key).

Two things an API key does not do. It is pinned server-side to the workspace it was minted in, so STIMULIR_WORKSPACE_ID (or stimulir workspace use) must still be set, and must name that workspace — anything else is a 403, not a silent cross-tenant read. And it resolves to the key's creating user without superadmin, so superadmin-only verbs stay closed to it.

Select a workspace

Most commands are scoped to a workspace (business profile):

stimulir workspace list
stimulir workspace use <workspace-id>

Commands

Agent — the AI engineer in your terminal

Bare stimulir (no subcommand, in a TTY) launches the interactive Stimulir agent against the active workspace. The agent runs server-side (Pi through code-runtime) and executes its tool intents — bash, file reads/writes, glob search — on your machine, with approval prompts. The conversation lives server-side, so the same session shows up in the Engineering traces panel.

# Start the agent (or pass an opening task)
stimulir
stimulir agent "Add a /health endpoint and wire it into the router"

# Resume an existing session
stimulir agent --session <session-key>

# Attach this machine as the local executor for a session started in the app
# (the chat composer's "Continue in: Local" dropdown)
stimulir attach [<session-key>]

Approvals stay on your machine — destructive commands (rm -rf, sudo, force push, key revocation) always prompt even under an "always allow" grant.

API keys (hyb_* inference keys)

stimulir keys create --name cli --env prod --expires-in-days 90 --save
stimulir keys list --include-revoked
stimulir keys revoke <key-id>

The plaintext key is shown exactly once; --save stores it in ~/.stimulir/credentials.json so stimulir infer can use it.

BYOK provider credentials

Providers: openai, anthropic, google_gemini, mistral, aws_bedrock, azure_openai, together_ai, nebius.

stimulir byok add --provider anthropic --label "prod key"   # secret prompted without echo
stimulir byok list
stimulir byok verify <credential-id>
stimulir byok remove <credential-id>

Workspace prompts

Versioned prompt management — every save creates a new immutable version, and labels (e.g. prod) move between versions so you can promote or roll back without editing application code.

stimulir prompts list
stimulir prompts get <key> [--label prod|--version N]
stimulir prompts versions <key>
stimulir prompts create --key <key> --file ./prompt.md --label prod --notes "<change notes>"
stimulir prompts update <key> <version> --notes "<change notes>"
stimulir prompts archive <key> <version>
stimulir prompts label <key> <version> <label>

Data assets

Curate datasets for the training loop, including from agent traces:

stimulir data list
stimulir data upload ./dataset.jsonl --stage raw --target sft
stimulir data from-trace <trace-id> --source agent --target sft
stimulir data stage <asset-id> <raw|cleaning|clean_view|snapshot|lab>
stimulir data unstage <asset-id>
stimulir data bulk-stage --ids <asset-id>,<asset-id> --stage lab --target sft
stimulir data update <asset-id> --name "<name>" --target sft
stimulir data snapshot <asset-id>
stimulir data remove <asset-id>

The typical flow is from-trace → stage … lab → snapshot — turn an agent run into staged data, promote it, then pin a snapshot a training run consumes.

Usage & billing

stimulir usage --window 30d --group-by model
stimulir billing snapshot

Inference

Run stimulir login, then use stimulir models or stimulir infer chat. The CLI obtains a temporary inference key from your login and revokes it when the command finishes; it does not overwrite your saved credentials.

Explicit STIMULIR_API_KEY / HYBRIE_API_KEY values take precedence. Without an explicit key, the active login takes precedence over a saved API key; a saved key is used only when there is no login. A rejected login is surfaced rather than silently falling back to another credential.

stimulir infer chat "Summarise IFRS 16 in one paragraph" --model hybrie-mid
stimulir infer chat "Write a haiku about ledgers" --model hybrie-small --stream

Codex App

Configure Codex App to use Stimulir as a custom model provider. The default config uses Codex command-backed auth, so Codex asks stimulir codex token for a short-lived Console-minted inference key instead of storing a key in ~/.codex/config.toml.

stimulir launch codex-app \
  --staging \
  --project 1aa6b818-3a8e-450e-b324-b14e16ca7b38 \
  --model zai-org/GLM-5.2

stimulir launch codex-app --dry-run
stimulir launch codex-app --restore
stimulir codex models

HybrIE lab (training + eval)

stimulir lab train sft --family qwen3-4b --lora-rank 8 --examples 500 --epochs 3 --lr 1e-4 --eval-examples 200 --seed 42 --checkpoint-dir runs/sft
stimulir lab train sft --family qwen3.5-4b --dataset <asset-id> --min-blocks 1 --max-blocks 4 --log-every 5 --compute-offer <offer-id> --region <region> --max-duration-hours 1 --max-cost-gbp 5 --preview
stimulir lab train d2l --family qwen3-4b --examples 500 --epochs 3 --lr 1e-4 --eval-examples 200 --seed 42 --checkpoint-dir runs/d2l
stimulir lab train rl --family qwen3-4b --environment niah --prompts 64 --group-size 8 --policy hypernet --lr 1e-5 --kl-beta 0.05
stimulir lab jobs list
stimulir lab jobs get <job-id>
stimulir lab jobs cancel <job-id>
stimulir lab eval runs
stimulir lab eval get <run-id>
stimulir lab eval create-run --data-asset-id <asset-id> --prompt <key>:<version|label> --execute
stimulir lab eval create-run --data-asset-id <asset-id> --prompt <key>:<version|label> --leave-queued
stimulir lab eval execute-run <run-id>
stimulir lab eval tree <run-id>
stimulir lab eval derive <run-id> --rationale "shorter preamble" --prompt-file new-prompt.txt --stop-parent
stimulir lab eval steer <run-id> --body "focus the next branch on the currency-mismatch cases"
stimulir lab eval steers <run-id> --pending
stimulir lab eval ack-steer <run-id> <steer-id> --consumed-by agent-session-abc --note "applied as derive on run X"
stimulir lab eval delete <run-id> [--hard --include-descendants]
stimulir lab eval niah --family qwen3-4b --checkpoint-dir ~/hybrie-mounts/d2l-artifacts/<job>/checkpoint --examples 200 --seed 42
stimulir lab eval adapter --family qwen3-4b --adapter-dir ~/adapters/invoices-lora --examples 200 --seed 42
stimulir lab eval rl --family qwen3-4b --environment niah --policy hypernet --checkpoint-dir runs/rl/<job> --tasks 50 --pass-threshold 0.8
stimulir lab adapters list
stimulir lab adapters get <adapter-id>
stimulir lab adapters load <adapter-id>
stimulir lab adapters unload <adapter-id>

create-run requires exactly one of --execute or --leave-queued; passing neither is an argument error. There is no default because both defaults are wrong. A run created and not started is QUEUED with nothing spawned, and no scheduler anywhere picks queued runs up, so it sits at zero results forever while its status claims otherwise — that is what defaulting to queued does. Defaulting to executing would instead spend real inference money on a command that did not before. --leave-queued is the deliberate version of the first, and it prints the execute-run command that starts the run (start_command in the --json document).

Starting a run detaches. create-run --execute creates the run, starts it and returns immediately with the run id, its status and a console deep link — it does not wait for the eval and there is deliberately no --wait flag, because waiting on a run is exactly the work this surface exists to hand off. Follow a run from the console link, or pull its state on demand with get / tree; a human can redirect it mid-flight with steer, and whichever agent picks the run up next reads that steer off the pending_work block of a status call it already makes.

Set STIMULIR_CONSOLE_BASE (or console_base in ~/.stimulir/config.json) when your API base is not an api.* host, otherwise no link can be derived and the commands say so rather than guessing one.

delete archives by default: nothing is destroyed, the whole branch below the selection is covered, and it is one-way. --hard destroys rows and refuses, with the blocking run ids listed, unless --include-descendants is passed.

Compute (GPU offers + instances + peers)

stimulir compute offers
stimulir compute up <offer-id> --region <region> --ssh-key <provider-key-name> --count 1
stimulir compute worker <offer-id> --region <region> --ssh-key <provider-key-name> --model-repo Qwen/Qwen3.5-4B --model-slug qwen3.5-4b --hybrie-ref <pinned-commit>
stimulir compute list
stimulir compute status <instance-id>
stimulir compute down <instance-id>
stimulir compute peers list
stimulir compute peers add --name lambda-a100 --grpc http://10.0.0.5:9090 --realtime http://10.0.0.5:8011
stimulir compute peers remove <peer-id>

The supervised Lambda training sequence, cost boundary and mandatory teardown check are documented in docs/MANAGED_ADAPTER_RUN.md.

Models

stimulir models

HybrIE routing

lab and compute go through the console proxy ({api_base}/api/v1/hybrie/*, console credentials + workspace header) by default. To talk to a HybrIE runtime directly, pass --endpoint http://host:port or configure hybrie_endpoint for those commands.

models uses the managed inference catalog at /api/v1/inference/models with the login-based authentication described above. Only an explicit models --endpoint http://host:port selects a direct runtime; that path uses its configured API key, not a login-derived key.

Scripting

Every command accepts --json to emit the raw API response:

stimulir keys list --json | jq '.api_keys[].prefix'

Configuration reference

File Contents
~/.stimulir/config.json api_base, workspace_id, hybrie_endpoint, supabase_url, supabase_anon_key
~/.stimulir/credentials.json (0600) api_key, cli_token (opaque stim_cli_ from device login), optional access_token, refresh_token, expires_at, email

Common environment overrides: STIMULIR_API_BASE, STIMULIR_API_KEY, STIMULIR_WORKSPACE_ID, SUPABASE_URL, SUPABASE_ANON_KEY. Use stimulir workspace use <id> to persist the active CLI workspace. See Authenticating an agent with an API key for the order these credentials resolve in.

Managed shared rooms

client.rooms and client.compute.realtime_instances use the Console's managed Stimulir Realtime Runtime (SRR) API with the same server-side Stimulir API key and project identity. They need only the base install (pip install stimulir); Pipecat, aiortc, PyAV and WebSocket clients are not loaded. Existing GPU compute methods and stimulir.realtime.RealtimeClient retain their meaning.

from stimulir import StimulirClient

client = StimulirClient(project_id="YOUR_PROJECT_ID")  # STIMULIR_API_KEY
instance = client.compute.realtime_instances.ensure(name="assessments")
room = client.rooms.create(instance_id=instance["id"], mode="human")
connection = client.rooms.grant(
    room["id"], instance_id=instance["id"],
    participant="authenticated-user-id", name="Participant",
    ai_consent=False, recording_consent=False, vision_consent=False,
)
# Return connection only to this authorized participant; never return the API key.

Grant responses have url, token, room_id, expires_in, ice_servers and protocol. The browser uses Room from @stimulir/sdk/rooms; React apps can observe it with useRoom from @stimulir/react/rooms. These are packaged in the SRR repository and require its release archives until registry publication. The application must authenticate the participant and decide permissions before requesting a grant. Grant consent defaults are all false.

For FastAPI and other async applications:

from stimulir import AsyncStimulirClient

async def create_interview(project_id: str):
    async with AsyncStimulirClient(project_id=project_id) as client:
        instance = await client.compute.realtime_instances.ensure(name="interviews")
        room = await client.rooms.create(instance_id=instance["id"], mode="interview")
        return room

AsyncStimulirClient currently exposes managed rooms and realtime instances; other platform/inference APIs remain on StimulirClient. Its resource methods return awaitables backed by native httpx.AsyncClient, with no blocking wrapper. Reuse a client within application lifespan and call aclose() on shutdown. An injected http_client remains owned by its caller. RoomsAPIError provides status_code and a sanitized message without retaining an upstream error body.

Instance operations: ensure, list, get, update, start, suspend, delete. Ensure reuses the project/name identity and preserves existing status and limits; use update(..., expected_revision=...) to explicitly change limits. The response's observed_status tells you whether provisioning is ready. Shared instances allocate a tenant namespace and quotas on the SRR fleet; they do not create dedicated EC2 machines. Deletion is an explicit lifecycle operation.

Room operations: create, get, grant, command, handoff, set_mode, close. Every operation supplies instance_id; room IDs do not grant access. Room creation accepts a stable key for safe retry after an uncertain outcome. Handoff/mode support expected_version for optimistic concurrency. AI processing requires participant consent and configured server-side inference credentials. Provisioning, grants and room commands require the managed Console routes and an SRR deployment; installing the SDK does not deploy either service.

Image generation

Generate images through the gateway's tenant credentials, model catalogue, traces and usage counters. Image usage is currently unrated: provider counters are captured, but no published image price is applied automatically. Model availability and supported options depend on the configured provider. A catalogue entry alone does not enable a provider route.

import base64
from pathlib import Path
from stimulir import StimulirClient, TraceContext

client = StimulirClient()
result = client.images.generate(
    model="openai/gpt-image-2",
    prompt="A watercolor landscape with a lake at sunrise",
    output_format="png",
    # Optional: omit for an independent image trace.
    trace_context=TraceContext(session_id="design-session", turn_id="turn-1"),
)
Path("landscape.png").write_bytes(base64.b64decode(result["data"][0]["b64_json"]))

generate supports n and a request timeout (600 seconds by default). OpenAI options include size, quality, output_format, background, output_compression, and moderation. Gemini options include aspect_ratio and image_size; omit OpenAI-only options when using Gemini. The only supported response_format is b64_json (the default). Unsupported model options are rejected by the gateway. The SDK preserves the response's created, data and optional provider usage; it does not fetch remote URLs or write files automatically. This method generates images from text; image editing and streaming are not part of this API.

Use native async HTTP in application servers:

from stimulir import AsyncStimulirClient

async def generate_picture():
    async with AsyncStimulirClient() as client:
        return await client.images.generate(
            model="openai/gpt-image-2", prompt="A watercolor landscape",
        )

Metadata

Release files for stimulir 0.2.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stimulir 0.2.9
File Size Uploaded
stimulir-0.2.9.tar.gz 306.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stimulir 0.2.9
File Interpreter ABI Platform
stimulir-0.2.9-py3-none-any.whl Python 3 none any Details

Total release size: 540.0 kB

Release files / stimulir-0.2.9.tar.gz

Download URL stimulir-0.2.9.tar.gz
Size 306.5 kB
Tags Source
SHA-256 checksum
How to use checksums
ba41c5dc354a70c0fe431b7361610fb006a970afd0820ce79999c45414e9da50
BLAKE2b-256 checksum
How to use checksums
83f092df6ce1edfdc52f43acccbb69eddc6fefbe900066354b7b90e1942c3d4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / stimulir-0.2.9-py3-none-any.whl

Download URL stimulir-0.2.9-py3-none-any.whl
Size 233.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6b33ef5b3097dc9eb39bbe10faea5ff10a55558af52d244371b45c46af742af1
BLAKE2b-256 checksum
How to use checksums
5601533f7d301989aac00f1775f2ac61b0e566a3ee89a7d122476792273fee75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.10

2 release files

This release

0.2.9 This release

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page